feat(17-01): add WriteTrackTagsByPath and ImageFilePicker backend methods

- WriteTrackTagsByPath resolves filePath to trackID via GetAudioFileByPath
- ImageFilePicker opens native file dialog filtered to JPEG/PNG
- Added Wails TypeScript bindings for both new methods
This commit is contained in:
2026-03-17 21:03:17 -04:00
parent 290f236a1b
commit 4235b4a4d5
6 changed files with 68 additions and 0 deletions
+23
View File
@@ -67,3 +67,26 @@ func (fe *FrontendUtil) PlaylistFilePicker() (
return files, nil return files, nil
} }
// ImageFilePicker opens a file selection dialog filtered to image
// files (JPEG, PNG). Returns the selected file path, or empty
// string if the user cancelled.
func (fe *FrontendUtil) ImageFilePicker() (string, error) {
file, err := runtime.OpenFileDialog(
fe.ctx,
runtime.OpenDialogOptions{
Title: "Select Cover Art",
Filters: []runtime.FileFilter{
{
DisplayName: "Image Files (*.jpg, *.jpeg, *.png)",
Pattern: "*.jpg;*.jpeg;*.png",
},
},
},
)
if err != nil {
return "", fmt.Errorf("could not open file dialog: %w", err)
}
return file, nil
}
+14
View File
@@ -172,3 +172,17 @@ func (tw *TagWriter) WriteTrackTags(trackID int64, changes TagChanges) error {
return nil return nil
} }
// WriteTrackTagsByPath resolves a file path to its audio_file.id and
// delegates to WriteTrackTags. This is the frontend-facing entry
// point since the frontend identifies tracks by FilePath.
func (tw *TagWriter) WriteTrackTagsByPath(filePath string, changes TagChanges) error {
ctx := context.Background()
audioFile, err := tw.db.Queries.GetAudioFileByPath(ctx, filePath)
if err != nil {
return fmt.Errorf("resolve track by path %q: %w", filePath, err)
}
return tw.WriteTrackTags(audioFile.ID, changes)
}
+2
View File
@@ -4,6 +4,8 @@ import {context} from '../models';
export function DirectoryPicker():Promise<string>; export function DirectoryPicker():Promise<string>;
export function ImageFilePicker():Promise<string>;
export function PlaylistFilePicker():Promise<Array<string>>; export function PlaylistFilePicker():Promise<Array<string>>;
export function SetContext(arg1:context.Context):Promise<void>; export function SetContext(arg1:context.Context):Promise<void>;
@@ -6,6 +6,10 @@ export function DirectoryPicker() {
return window['go']['frontendutil']['FrontendUtil']['DirectoryPicker'](); return window['go']['frontendutil']['FrontendUtil']['DirectoryPicker']();
} }
export function ImageFilePicker() {
return window['go']['frontendutil']['FrontendUtil']['ImageFilePicker']();
}
export function PlaylistFilePicker() { export function PlaylistFilePicker() {
return window['go']['frontendutil']['FrontendUtil']['PlaylistFilePicker'](); return window['go']['frontendutil']['FrontendUtil']['PlaylistFilePicker']();
} }
+10
View File
@@ -0,0 +1,10 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {context} from '../models';
import {tagwriter} from '../models';
export function SetContext(arg1:context.Context):Promise<void>;
export function WriteTrackTags(arg1:number,arg2:tagwriter.TagChanges):Promise<void>;
export function WriteTrackTagsByPath(arg1:string,arg2:tagwriter.TagChanges):Promise<void>;
+15
View File
@@ -0,0 +1,15 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export function SetContext(arg1) {
return window['go']['tagwriter']['TagWriter']['SetContext'](arg1);
}
export function WriteTrackTags(arg1, arg2) {
return window['go']['tagwriter']['TagWriter']['WriteTrackTags'](arg1, arg2);
}
export function WriteTrackTagsByPath(arg1, arg2) {
return window['go']['tagwriter']['TagWriter']['WriteTrackTagsByPath'](arg1, arg2);
}