25 Commits

Author SHA1 Message Date
03c4350653 release: v1.2.0 2025-02-14 16:19:57 +08:00
f9c4c1c7cf feat: list folder recursively 2025-02-14 16:17:24 +08:00
c523f1a59c update: wails to 2.9.3 2025-02-14 15:58:10 +08:00
e3402dbfa3 update: app image 2025-02-01 19:24:31 +08:00
73687b889e feat: macOS about menu 2025-02-01 19:23:17 +08:00
4333d0ea2a fix: eof when save before load 2025-02-01 19:07:09 +08:00
e4f2d1aaab remove: debug print 2025-02-01 19:07:09 +08:00
bc67dab122 ignore: frontend files 2025-02-01 19:07:08 +08:00
ce5ca88694 ignore: frontend files 2025-02-01 19:07:08 +08:00
70ec35653d feat: change version 2025-02-01 19:07:08 +08:00
6f5f739059 feat: save preference to config file 2025-02-01 17:42:29 +08:00
b0bfb3e606 feat: prevent click when processing 2025-02-01 13:43:44 +08:00
4df7df678b feat: icons and remove button 2025-02-01 13:39:13 +08:00
33d9b91c52 update: ncmdump-go to v1.7.4 2025-02-01 13:21:07 +08:00
f7a7a7b401 feat: webview2 instruction 2025-02-01 12:11:46 +08:00
7402e35d66 feat: file drop 2025-02-01 12:11:13 +08:00
36fd04f975 release: v1.0.1 2025-01-30 12:22:17 +08:00
91bbd8deb4 removed: unnecessary dependency 2025-01-30 12:16:44 +08:00
2f25264483 upgrade: ncmdump-go to 1.7.3 2025-01-30 12:12:42 +08:00
db6d89bdb9 update: dependencies 2025-01-30 12:09:24 +08:00
a08813dc94 feat: LICENSE 2024-11-28 09:06:29 +08:00
6bc7923eea update: README.md 2024-11-28 08:58:31 +08:00
1f9e811246 update: image 2024-11-27 19:17:17 +08:00
c100bb886a update: README.md 2024-11-27 16:50:10 +08:00
66bb4ac6c5 feat: image 2024-11-27 16:44:55 +08:00
19 changed files with 314 additions and 622 deletions

4
.gitignore vendored
View File

@@ -1,3 +1,7 @@
build/bin build/bin
node_modules node_modules
frontend/dist frontend/dist
frontend/wailsjs/
frontend/package.json.md5

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018-present TaurusXin and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,19 +1,19 @@
# README # ncmdump-gui
## About ## 介绍
This is the official Wails React-TS template. ncmdump-gui 基于 [ncmdump-go](https://git.taurusxin.com/taurusxin/ncmdump-go) 开发,是一个图形化的 ncmdump 工具。
You can configure the project by editing `wails.json`. More information about the project settings can be found ![工具主界面](https://git.taurusxin.com/taurusxin/ncmdump-gui/raw/branch/main/img/ncmdump-gui.png)
here: https://wails.io/docs/reference/project-config
## Live Development 使用简单,使用 go 协程,高速并行解析并处理多个 ncm 文件,多个文件瞬间完成,支持自定义输出路径。
To run in live development mode, run `wails dev` in the project directory. This will run a Vite development ## 下载
server that will provide very fast hot reload of your frontend changes. If you want to develop in a browser
and have access to your Go methods, there is also a dev server that runs on http://localhost:34115. Connect
to this in your browser, and you can call your Go code from devtools.
## Building 前往[Releases](https://git.taurusxin.com/taurusxin/ncmdump-gui/releases)下载最新版本。
To build a redistributable, production mode package, use `wails build`. 请注意:绝大多数较新版本的 Windows 都自带了 Webview 2 运行时,如果遇到了软件无法启动的问题,请前往微软官网下载:<https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/>
## Bug 及建议
如有任何问题或建议,请直接通过 [Issue](https://git.taurusxin.com/taurusxin/ncmdump-gui/issues) 反馈,本站已开放注册。

16
app.go
View File

@@ -6,6 +6,7 @@ import (
"github.com/wailsapp/wails/v2/pkg/runtime" "github.com/wailsapp/wails/v2/pkg/runtime"
"git.taurusxin.com/taurusxin/ncmdump-go/ncmcrypt" "git.taurusxin.com/taurusxin/ncmdump-go/ncmcrypt"
"git.taurusxin.com/taurusxin/ncmdump-gui/utils"
) )
// App struct // App struct
@@ -51,6 +52,21 @@ func (a *App) SelectFolder() string {
return folder return folder
} }
func (a *App) SelectFilesFromFolder(ext string) []string {
folder, err := runtime.OpenDirectoryDialog(a.ctx, runtime.OpenDialogOptions{
Title: "请选择文件夹",
})
if err != nil {
return []string{}
} else {
files, err := utils.ListFilesFromFolder(folder, ext)
if err != nil {
return []string{}
}
return files
}
}
type Status = string type Status = string
const ( const (

View File

@@ -1 +0,0 @@
d96d5e55cba5f9d68f0aa1d714fb5f1a

View File

@@ -1,4 +1,4 @@
import React, { useEffect } from 'react' import React, { useEffect, useMemo } from 'react'
import { useState } from 'react' import { useState } from 'react'
import { import {
Button, Button,
@@ -35,12 +35,18 @@ import {
CheckmarkRegular, CheckmarkRegular,
DismissRegular, DismissRegular,
DocumentArrowRightRegular, DocumentArrowRightRegular,
DocumentAddRegular,
DeleteRegular,
DeleteDismissRegular,
FolderAddRegular,
WindowPlayRegular,
} from '@fluentui/react-icons' } from '@fluentui/react-icons'
import { Status, Item, SaveTo } from './types' import { Status, Item, SaveTo } from './types'
import { SelectFiles, SelectFolder, ProcessFiles } from '../wailsjs/go/main/App' import { SelectFiles, SelectFolder, SelectFilesFromFolder, ProcessFiles } from '../wailsjs/go/main/App'
import { Load, Save } from '../wailsjs/go/utils/ConfigManager'
import { main } from '../wailsjs/go/models' import { main } from '../wailsjs/go/models'
import { EventsOn } from '../wailsjs/runtime/runtime' import { EventsOn, OnFileDrop } from '../wailsjs/runtime/runtime'
const columnsDef: TableColumnDefinition<Item>[] = [ const columnsDef: TableColumnDefinition<Item>[] = [
createTableColumn<Item>({ createTableColumn<Item>({
@@ -51,6 +57,10 @@ const columnsDef: TableColumnDefinition<Item>[] = [
columnId: 'file', columnId: 'file',
renderHeaderCell: () => <></>, renderHeaderCell: () => <></>,
}), }),
createTableColumn<Item>({
columnId: 'operation',
renderHeaderCell: () => <></>,
}),
] ]
const useStyles = makeStyles({ const useStyles = makeStyles({
@@ -65,14 +75,15 @@ const useStyles = makeStyles({
}, },
}) })
let loaded = false
export const App = () => { export const App = () => {
const styles = useStyles() const styles = useStyles()
const [items, setItems] = useState<Item[]>([]) const [items, setItems] = useState<Item[]>([])
const [isProcessing, setIsProcessing] = useState(false) const isProcessing = useMemo(() => {
return items.some(item => item.status === 'processing')
const [totalFilesNeedToProcess, setTotalFilesNeedToProcess] = useState(0) }, [items])
const [finishedCount, setFinishedCount] = useState(0)
const [saveTo, setSaveTo] = useState<SaveTo>('original') const [saveTo, setSaveTo] = useState<SaveTo>('original')
const [savePath, setSavePath] = useState('') const [savePath, setSavePath] = useState('')
@@ -87,9 +98,13 @@ export const App = () => {
minWidth: 100, minWidth: 100,
}, },
file: { file: {
idealWidth: 150, idealWidth: 1000,
minWidth: 150, minWidth: 150,
}, },
operation: {
idealWidth: 80,
minWidth: 80,
},
}) })
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
@@ -131,11 +146,24 @@ export const App = () => {
} }
const selectFiles = () => { const selectFiles = () => {
if (isProcessing) {
return
}
SelectFiles().then(files => { SelectFiles().then(files => {
for (const file of files) { for (const file of files) {
setItems(prev => [...prev, { file, status: 'pending' }]) setItems(prev => [...prev, { file, status: 'pending' }])
} }
setTotalFilesNeedToProcess(files.length) })
}
const selectFilesFromFolder = () => {
if (isProcessing) {
return
}
SelectFilesFromFolder('ncm').then(files => {
for (const file of files) {
setItems(prev => [...prev, { file, status: 'pending' }])
}
}) })
} }
@@ -162,7 +190,10 @@ export const App = () => {
showDialog('当前文件列表已全部处理完毕,请重新添加新的文件。') showDialog('当前文件列表已全部处理完毕,请重新添加新的文件。')
return return
} }
setIsProcessing(true) if (saveTo === 'custom' && savePath === '') {
showDialog('保存路径为空,请先设置保存路径。')
return
}
const ncmFiles: main.NcmFile[] = [] const ncmFiles: main.NcmFile[] = []
items.forEach(item => { items.forEach(item => {
ncmFiles.push({ ncmFiles.push({
@@ -175,24 +206,39 @@ export const App = () => {
useEffect(() => { useEffect(() => {
EventsOn('file-status-changed', (index: number, status: Status) => { EventsOn('file-status-changed', (index: number, status: Status) => {
if (status == 'done' || status === 'error') {
setFinishedCount(prev => prev + 1)
}
setItems(prev => { setItems(prev => {
const newItems = [...prev] const newItems = [...prev]
newItems[index].status = status newItems[index].status = status
return newItems return newItems
}) })
}) })
Load().then(res => {
setSaveTo(res.save_to as SaveTo)
setSavePath(res.path)
loaded = true
})
}, []) }, [])
useEffect(() => { useEffect(() => {
if (finishedCount === totalFilesNeedToProcess) { if (loaded) {
setFinishedCount(0) Save({
setTotalFilesNeedToProcess(0) save_to: saveTo,
setIsProcessing(false) path: savePath,
}).then(_ => {})
} }
}, [finishedCount]) }, [saveTo, savePath])
OnFileDrop((_x, _y, paths) => {
let length = paths.length
for (const path of paths) {
// only end with ncm
if (!path.endsWith('.ncm')) {
length--
continue
}
setItems(prev => [...prev, { file: path, status: 'pending' }])
}
}, false)
return ( return (
<div className="p-3"> <div className="p-3">
@@ -217,10 +263,23 @@ export const App = () => {
</DialogSurface> </DialogSurface>
</Dialog> </Dialog>
<div className="flex space-between gap-3"> <div className="flex space-between gap-3">
<Button onClick={selectFiles}></Button> <Button onClick={selectFiles} icon={<DocumentAddRegular />}>
<Button onClick={() => setItems([])}></Button>
</Button>
<Button onClick={selectFilesFromFolder} icon={<FolderAddRegular />}></Button>
<Button
onClick={() => {
if (!isProcessing) {
setItems([])
}
}}
icon={<DeleteDismissRegular />}
>
</Button>
<Button <Button
appearance="primary" appearance="primary"
icon={<WindowPlayRegular />}
onClick={() => { onClick={() => {
startProcess() startProcess()
}} }}
@@ -289,6 +348,18 @@ export const App = () => {
</TableCellLayout> </TableCellLayout>
</TableCell> </TableCell>
<TableCell>{file.file}</TableCell> <TableCell>{file.file}</TableCell>
<TableCell>
<Button
size="small"
icon={<DeleteRegular />}
appearance="transparent"
onClick={() => {
setItems(prev => prev.filter((_, i) => i !== index))
}}
>
</Button>
</TableCell>
</TableRow> </TableRow>
))} ))}
</TableBody> </TableBody>

View File

@@ -1,9 +0,0 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {main} from '../models';
export function ProcessFiles(arg1:Array<main.NcmFile>,arg2:string):Promise<void>;
export function SelectFiles():Promise<Array<string>>;
export function SelectFolder():Promise<string>;

View File

@@ -1,15 +0,0 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export function ProcessFiles(arg1, arg2) {
return window['go']['main']['App']['ProcessFiles'](arg1, arg2);
}
export function SelectFiles() {
return window['go']['main']['App']['SelectFiles']();
}
export function SelectFolder() {
return window['go']['main']['App']['SelectFolder']();
}

View File

@@ -1,19 +0,0 @@
export namespace main {
export class NcmFile {
Name: string;
Status: string;
static createFrom(source: any = {}) {
return new NcmFile(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Name = source["Name"];
this.Status = source["Status"];
}
}
}

View File

@@ -1,24 +0,0 @@
{
"name": "@wailsapp/runtime",
"version": "2.0.0",
"description": "Wails Javascript runtime library",
"main": "runtime.js",
"types": "runtime.d.ts",
"scripts": {
},
"repository": {
"type": "git",
"url": "git+https://github.com/wailsapp/wails.git"
},
"keywords": [
"Wails",
"Javascript",
"Go"
],
"author": "Lea Anthony <lea.anthony@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/wailsapp/wails/issues"
},
"homepage": "https://github.com/wailsapp/wails#readme"
}

View File

@@ -1,249 +0,0 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The electron alternative for Go
(c) Lea Anthony 2019-present
*/
export interface Position {
x: number;
y: number;
}
export interface Size {
w: number;
h: number;
}
export interface Screen {
isCurrent: boolean;
isPrimary: boolean;
width : number
height : number
}
// Environment information such as platform, buildtype, ...
export interface EnvironmentInfo {
buildType: string;
platform: string;
arch: string;
}
// [EventsEmit](https://wails.io/docs/reference/runtime/events#eventsemit)
// emits the given event. Optional data may be passed with the event.
// This will trigger any event listeners.
export function EventsEmit(eventName: string, ...data: any): void;
// [EventsOn](https://wails.io/docs/reference/runtime/events#eventson) sets up a listener for the given event name.
export function EventsOn(eventName: string, callback: (...data: any) => void): () => void;
// [EventsOnMultiple](https://wails.io/docs/reference/runtime/events#eventsonmultiple)
// sets up a listener for the given event name, but will only trigger a given number times.
export function EventsOnMultiple(eventName: string, callback: (...data: any) => void, maxCallbacks: number): () => void;
// [EventsOnce](https://wails.io/docs/reference/runtime/events#eventsonce)
// sets up a listener for the given event name, but will only trigger once.
export function EventsOnce(eventName: string, callback: (...data: any) => void): () => void;
// [EventsOff](https://wails.io/docs/reference/runtime/events#eventsoff)
// unregisters the listener for the given event name.
export function EventsOff(eventName: string, ...additionalEventNames: string[]): void;
// [EventsOffAll](https://wails.io/docs/reference/runtime/events#eventsoffall)
// unregisters all listeners.
export function EventsOffAll(): void;
// [LogPrint](https://wails.io/docs/reference/runtime/log#logprint)
// logs the given message as a raw message
export function LogPrint(message: string): void;
// [LogTrace](https://wails.io/docs/reference/runtime/log#logtrace)
// logs the given message at the `trace` log level.
export function LogTrace(message: string): void;
// [LogDebug](https://wails.io/docs/reference/runtime/log#logdebug)
// logs the given message at the `debug` log level.
export function LogDebug(message: string): void;
// [LogError](https://wails.io/docs/reference/runtime/log#logerror)
// logs the given message at the `error` log level.
export function LogError(message: string): void;
// [LogFatal](https://wails.io/docs/reference/runtime/log#logfatal)
// logs the given message at the `fatal` log level.
// The application will quit after calling this method.
export function LogFatal(message: string): void;
// [LogInfo](https://wails.io/docs/reference/runtime/log#loginfo)
// logs the given message at the `info` log level.
export function LogInfo(message: string): void;
// [LogWarning](https://wails.io/docs/reference/runtime/log#logwarning)
// logs the given message at the `warning` log level.
export function LogWarning(message: string): void;
// [WindowReload](https://wails.io/docs/reference/runtime/window#windowreload)
// Forces a reload by the main application as well as connected browsers.
export function WindowReload(): void;
// [WindowReloadApp](https://wails.io/docs/reference/runtime/window#windowreloadapp)
// Reloads the application frontend.
export function WindowReloadApp(): void;
// [WindowSetAlwaysOnTop](https://wails.io/docs/reference/runtime/window#windowsetalwaysontop)
// Sets the window AlwaysOnTop or not on top.
export function WindowSetAlwaysOnTop(b: boolean): void;
// [WindowSetSystemDefaultTheme](https://wails.io/docs/next/reference/runtime/window#windowsetsystemdefaulttheme)
// *Windows only*
// Sets window theme to system default (dark/light).
export function WindowSetSystemDefaultTheme(): void;
// [WindowSetLightTheme](https://wails.io/docs/next/reference/runtime/window#windowsetlighttheme)
// *Windows only*
// Sets window to light theme.
export function WindowSetLightTheme(): void;
// [WindowSetDarkTheme](https://wails.io/docs/next/reference/runtime/window#windowsetdarktheme)
// *Windows only*
// Sets window to dark theme.
export function WindowSetDarkTheme(): void;
// [WindowCenter](https://wails.io/docs/reference/runtime/window#windowcenter)
// Centers the window on the monitor the window is currently on.
export function WindowCenter(): void;
// [WindowSetTitle](https://wails.io/docs/reference/runtime/window#windowsettitle)
// Sets the text in the window title bar.
export function WindowSetTitle(title: string): void;
// [WindowFullscreen](https://wails.io/docs/reference/runtime/window#windowfullscreen)
// Makes the window full screen.
export function WindowFullscreen(): void;
// [WindowUnfullscreen](https://wails.io/docs/reference/runtime/window#windowunfullscreen)
// Restores the previous window dimensions and position prior to full screen.
export function WindowUnfullscreen(): void;
// [WindowIsFullscreen](https://wails.io/docs/reference/runtime/window#windowisfullscreen)
// Returns the state of the window, i.e. whether the window is in full screen mode or not.
export function WindowIsFullscreen(): Promise<boolean>;
// [WindowSetSize](https://wails.io/docs/reference/runtime/window#windowsetsize)
// Sets the width and height of the window.
export function WindowSetSize(width: number, height: number): Promise<Size>;
// [WindowGetSize](https://wails.io/docs/reference/runtime/window#windowgetsize)
// Gets the width and height of the window.
export function WindowGetSize(): Promise<Size>;
// [WindowSetMaxSize](https://wails.io/docs/reference/runtime/window#windowsetmaxsize)
// Sets the maximum window size. Will resize the window if the window is currently larger than the given dimensions.
// Setting a size of 0,0 will disable this constraint.
export function WindowSetMaxSize(width: number, height: number): void;
// [WindowSetMinSize](https://wails.io/docs/reference/runtime/window#windowsetminsize)
// Sets the minimum window size. Will resize the window if the window is currently smaller than the given dimensions.
// Setting a size of 0,0 will disable this constraint.
export function WindowSetMinSize(width: number, height: number): void;
// [WindowSetPosition](https://wails.io/docs/reference/runtime/window#windowsetposition)
// Sets the window position relative to the monitor the window is currently on.
export function WindowSetPosition(x: number, y: number): void;
// [WindowGetPosition](https://wails.io/docs/reference/runtime/window#windowgetposition)
// Gets the window position relative to the monitor the window is currently on.
export function WindowGetPosition(): Promise<Position>;
// [WindowHide](https://wails.io/docs/reference/runtime/window#windowhide)
// Hides the window.
export function WindowHide(): void;
// [WindowShow](https://wails.io/docs/reference/runtime/window#windowshow)
// Shows the window, if it is currently hidden.
export function WindowShow(): void;
// [WindowMaximise](https://wails.io/docs/reference/runtime/window#windowmaximise)
// Maximises the window to fill the screen.
export function WindowMaximise(): void;
// [WindowToggleMaximise](https://wails.io/docs/reference/runtime/window#windowtogglemaximise)
// Toggles between Maximised and UnMaximised.
export function WindowToggleMaximise(): void;
// [WindowUnmaximise](https://wails.io/docs/reference/runtime/window#windowunmaximise)
// Restores the window to the dimensions and position prior to maximising.
export function WindowUnmaximise(): void;
// [WindowIsMaximised](https://wails.io/docs/reference/runtime/window#windowismaximised)
// Returns the state of the window, i.e. whether the window is maximised or not.
export function WindowIsMaximised(): Promise<boolean>;
// [WindowMinimise](https://wails.io/docs/reference/runtime/window#windowminimise)
// Minimises the window.
export function WindowMinimise(): void;
// [WindowUnminimise](https://wails.io/docs/reference/runtime/window#windowunminimise)
// Restores the window to the dimensions and position prior to minimising.
export function WindowUnminimise(): void;
// [WindowIsMinimised](https://wails.io/docs/reference/runtime/window#windowisminimised)
// Returns the state of the window, i.e. whether the window is minimised or not.
export function WindowIsMinimised(): Promise<boolean>;
// [WindowIsNormal](https://wails.io/docs/reference/runtime/window#windowisnormal)
// Returns the state of the window, i.e. whether the window is normal or not.
export function WindowIsNormal(): Promise<boolean>;
// [WindowSetBackgroundColour](https://wails.io/docs/reference/runtime/window#windowsetbackgroundcolour)
// Sets the background colour of the window to the given RGBA colour definition. This colour will show through for all transparent pixels.
export function WindowSetBackgroundColour(R: number, G: number, B: number, A: number): void;
// [ScreenGetAll](https://wails.io/docs/reference/runtime/window#screengetall)
// Gets the all screens. Call this anew each time you want to refresh data from the underlying windowing system.
export function ScreenGetAll(): Promise<Screen[]>;
// [BrowserOpenURL](https://wails.io/docs/reference/runtime/browser#browseropenurl)
// Opens the given URL in the system browser.
export function BrowserOpenURL(url: string): void;
// [Environment](https://wails.io/docs/reference/runtime/intro#environment)
// Returns information about the environment
export function Environment(): Promise<EnvironmentInfo>;
// [Quit](https://wails.io/docs/reference/runtime/intro#quit)
// Quits the application.
export function Quit(): void;
// [Hide](https://wails.io/docs/reference/runtime/intro#hide)
// Hides the application.
export function Hide(): void;
// [Show](https://wails.io/docs/reference/runtime/intro#show)
// Shows the application.
export function Show(): void;
// [ClipboardGetText](https://wails.io/docs/reference/runtime/clipboard#clipboardgettext)
// Returns the current text stored on clipboard
export function ClipboardGetText(): Promise<string>;
// [ClipboardSetText](https://wails.io/docs/reference/runtime/clipboard#clipboardsettext)
// Sets a text on the clipboard
export function ClipboardSetText(text: string): Promise<boolean>;
// [OnFileDrop](https://wails.io/docs/reference/runtime/draganddrop#onfiledrop)
// OnFileDrop listens to drag and drop events and calls the callback with the coordinates of the drop and an array of path strings.
export function OnFileDrop(callback: (x: number, y: number ,paths: string[]) => void, useDropTarget: boolean) :void
// [OnFileDropOff](https://wails.io/docs/reference/runtime/draganddrop#dragandddropoff)
// OnFileDropOff removes the drag and drop listeners and handlers.
export function OnFileDropOff() :void
// Check if the file path resolver is available
export function CanResolveFilePaths(): boolean;
// Resolves file paths for an array of files
export function ResolveFilePaths(files: File[]): void

View File

@@ -1,238 +0,0 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The electron alternative for Go
(c) Lea Anthony 2019-present
*/
export function LogPrint(message) {
window.runtime.LogPrint(message);
}
export function LogTrace(message) {
window.runtime.LogTrace(message);
}
export function LogDebug(message) {
window.runtime.LogDebug(message);
}
export function LogInfo(message) {
window.runtime.LogInfo(message);
}
export function LogWarning(message) {
window.runtime.LogWarning(message);
}
export function LogError(message) {
window.runtime.LogError(message);
}
export function LogFatal(message) {
window.runtime.LogFatal(message);
}
export function EventsOnMultiple(eventName, callback, maxCallbacks) {
return window.runtime.EventsOnMultiple(eventName, callback, maxCallbacks);
}
export function EventsOn(eventName, callback) {
return EventsOnMultiple(eventName, callback, -1);
}
export function EventsOff(eventName, ...additionalEventNames) {
return window.runtime.EventsOff(eventName, ...additionalEventNames);
}
export function EventsOnce(eventName, callback) {
return EventsOnMultiple(eventName, callback, 1);
}
export function EventsEmit(eventName) {
let args = [eventName].slice.call(arguments);
return window.runtime.EventsEmit.apply(null, args);
}
export function WindowReload() {
window.runtime.WindowReload();
}
export function WindowReloadApp() {
window.runtime.WindowReloadApp();
}
export function WindowSetAlwaysOnTop(b) {
window.runtime.WindowSetAlwaysOnTop(b);
}
export function WindowSetSystemDefaultTheme() {
window.runtime.WindowSetSystemDefaultTheme();
}
export function WindowSetLightTheme() {
window.runtime.WindowSetLightTheme();
}
export function WindowSetDarkTheme() {
window.runtime.WindowSetDarkTheme();
}
export function WindowCenter() {
window.runtime.WindowCenter();
}
export function WindowSetTitle(title) {
window.runtime.WindowSetTitle(title);
}
export function WindowFullscreen() {
window.runtime.WindowFullscreen();
}
export function WindowUnfullscreen() {
window.runtime.WindowUnfullscreen();
}
export function WindowIsFullscreen() {
return window.runtime.WindowIsFullscreen();
}
export function WindowGetSize() {
return window.runtime.WindowGetSize();
}
export function WindowSetSize(width, height) {
window.runtime.WindowSetSize(width, height);
}
export function WindowSetMaxSize(width, height) {
window.runtime.WindowSetMaxSize(width, height);
}
export function WindowSetMinSize(width, height) {
window.runtime.WindowSetMinSize(width, height);
}
export function WindowSetPosition(x, y) {
window.runtime.WindowSetPosition(x, y);
}
export function WindowGetPosition() {
return window.runtime.WindowGetPosition();
}
export function WindowHide() {
window.runtime.WindowHide();
}
export function WindowShow() {
window.runtime.WindowShow();
}
export function WindowMaximise() {
window.runtime.WindowMaximise();
}
export function WindowToggleMaximise() {
window.runtime.WindowToggleMaximise();
}
export function WindowUnmaximise() {
window.runtime.WindowUnmaximise();
}
export function WindowIsMaximised() {
return window.runtime.WindowIsMaximised();
}
export function WindowMinimise() {
window.runtime.WindowMinimise();
}
export function WindowUnminimise() {
window.runtime.WindowUnminimise();
}
export function WindowSetBackgroundColour(R, G, B, A) {
window.runtime.WindowSetBackgroundColour(R, G, B, A);
}
export function ScreenGetAll() {
return window.runtime.ScreenGetAll();
}
export function WindowIsMinimised() {
return window.runtime.WindowIsMinimised();
}
export function WindowIsNormal() {
return window.runtime.WindowIsNormal();
}
export function BrowserOpenURL(url) {
window.runtime.BrowserOpenURL(url);
}
export function Environment() {
return window.runtime.Environment();
}
export function Quit() {
window.runtime.Quit();
}
export function Hide() {
window.runtime.Hide();
}
export function Show() {
window.runtime.Show();
}
export function ClipboardGetText() {
return window.runtime.ClipboardGetText();
}
export function ClipboardSetText(text) {
return window.runtime.ClipboardSetText(text);
}
/**
* Callback for OnFileDrop returns a slice of file path strings when a drop is finished.
*
* @export
* @callback OnFileDropCallback
* @param {number} x - x coordinate of the drop
* @param {number} y - y coordinate of the drop
* @param {string[]} paths - A list of file paths.
*/
/**
* OnFileDrop listens to drag and drop events and calls the callback with the coordinates of the drop and an array of path strings.
*
* @export
* @param {OnFileDropCallback} callback - Callback for OnFileDrop returns a slice of file path strings when a drop is finished.
* @param {boolean} [useDropTarget=true] - Only call the callback when the drop finished on an element that has the drop target style. (--wails-drop-target)
*/
export function OnFileDrop(callback, useDropTarget) {
return window.runtime.OnFileDrop(callback, useDropTarget);
}
/**
* OnFileDropOff removes the drag and drop listeners and handlers.
*/
export function OnFileDropOff() {
return window.runtime.OnFileDropOff();
}
export function CanResolveFilePaths() {
return window.runtime.CanResolveFilePaths();
}
export function ResolveFilePaths(files) {
return window.runtime.ResolveFilePaths(files);
}

20
go.mod
View File

@@ -5,8 +5,8 @@ go 1.23.0
toolchain go1.23.3 toolchain go1.23.3
require ( require (
git.taurusxin.com/taurusxin/ncmdump-go v1.7.2 git.taurusxin.com/taurusxin/ncmdump-go v1.7.4
github.com/wailsapp/wails/v2 v2.9.2 github.com/wailsapp/wails/v2 v2.9.3
) )
require ( require (
@@ -20,30 +20,30 @@ require (
github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
github.com/labstack/echo/v4 v4.12.0 // indirect github.com/labstack/echo/v4 v4.13.3 // indirect
github.com/labstack/gommon v0.4.2 // indirect github.com/labstack/gommon v0.4.2 // indirect
github.com/leaanthony/go-ansi-parser v1.6.1 // indirect github.com/leaanthony/go-ansi-parser v1.6.1 // indirect
github.com/leaanthony/gosod v1.0.4 // indirect github.com/leaanthony/gosod v1.0.4 // indirect
github.com/leaanthony/slicer v1.6.0 // indirect github.com/leaanthony/slicer v1.6.0 // indirect
github.com/leaanthony/u v1.1.1 // indirect github.com/leaanthony/u v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/samber/lo v1.47.0 // indirect github.com/samber/lo v1.49.1 // indirect
github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect
github.com/tkrajina/go-reflector v0.5.8 // indirect github.com/tkrajina/go-reflector v0.5.8 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/wailsapp/go-webview2 v1.0.17 // indirect github.com/wailsapp/go-webview2 v1.0.19 // indirect
github.com/wailsapp/mimetype v1.4.1 // indirect github.com/wailsapp/mimetype v1.4.1 // indirect
golang.org/x/crypto v0.29.0 // indirect golang.org/x/crypto v0.33.0 // indirect
golang.org/x/net v0.31.0 // indirect golang.org/x/net v0.35.0 // indirect
golang.org/x/sys v0.27.0 // indirect golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.20.0 // indirect golang.org/x/text v0.22.0 // indirect
) )
// replace github.com/wailsapp/wails/v2 v2.9.2 => /Users/taurusxin/Workspace/gopath/pkg/mod // replace github.com/wailsapp/wails/v2 v2.9.2 => /Users/taurusxin/Workspace/gopath/pkg/mod

46
go.sum
View File

@@ -1,5 +1,5 @@
git.taurusxin.com/taurusxin/ncmdump-go v1.7.2 h1:VF9gWpwswAvXA1WIXnxxJpCiUqdQ8gPzKURHsddgadU= git.taurusxin.com/taurusxin/ncmdump-go v1.7.4 h1:Uk7tP58yNMOMqH1e9+BOFwwQ/lqScK3F10mAIFB/jtM=
git.taurusxin.com/taurusxin/ncmdump-go v1.7.2/go.mod h1:6kRSwUFM9BZwvDrg6MEPBn+29+Q2131QjK/URWO7seg= git.taurusxin.com/taurusxin/ncmdump-go v1.7.4/go.mod h1:6kRSwUFM9BZwvDrg6MEPBn+29+Q2131QjK/URWO7seg=
github.com/TwiN/go-color v1.4.1 h1:mqG0P/KBgHKVqmtL5ye7K0/Gr4l6hTksPgTgMk3mUzc= github.com/TwiN/go-color v1.4.1 h1:mqG0P/KBgHKVqmtL5ye7K0/Gr4l6hTksPgTgMk3mUzc=
github.com/TwiN/go-color v1.4.1/go.mod h1:WcPf/jtiW95WBIsEeY1Lc/b8aaWoiqQpu5cf8WFxu+s= github.com/TwiN/go-color v1.4.1/go.mod h1:WcPf/jtiW95WBIsEeY1Lc/b8aaWoiqQpu5cf8WFxu+s=
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
@@ -22,8 +22,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc= github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
@@ -39,9 +39,8 @@ github.com/leaanthony/u v1.1.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQc
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
@@ -53,10 +52,10 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew=
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
@@ -70,24 +69,24 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/wailsapp/go-webview2 v1.0.17 h1:DkLnUKqW7J///OBXkInMq1fzC88G6ZjHwKuHXThuaco= github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU=
github.com/wailsapp/go-webview2 v1.0.17/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo= github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
github.com/wailsapp/wails/v2 v2.9.2 h1:Xb5YRTos1w5N7DTMyYegWaGukCP2fIaX9WF21kPPF2k= github.com/wailsapp/wails/v2 v2.9.3 h1:45Oe68FM7oovN8bd/IIX4GzTRnbkL6pUIy+74Qxi5WA=
github.com/wailsapp/wails/v2 v2.9.2/go.mod h1:uehvlCwJSFcBq7rMCGfk4rxca67QQGsbg5Nm4m9UnBs= github.com/wailsapp/wails/v2 v2.9.3/go.mod h1:P/TmJfTmOqrVkl6PI9HkkNp3JeQ4AfWLjevoHI77UPo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -97,11 +96,10 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -109,8 +107,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=

BIN
img/ncmdump-gui.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 KiB

21
main.go
View File

@@ -6,6 +6,9 @@ import (
"github.com/wailsapp/wails/v2" "github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/options" "github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/options/assetserver" "github.com/wailsapp/wails/v2/pkg/options/assetserver"
"github.com/wailsapp/wails/v2/pkg/options/mac"
"git.taurusxin.com/taurusxin/ncmdump-gui/utils"
) )
//go:embed all:frontend/dist //go:embed all:frontend/dist
@@ -15,8 +18,13 @@ func main() {
// Create an instance of the app structure // Create an instance of the app structure
app := NewApp() app := NewApp()
config_manager, err := utils.NewConfigManager("config.json")
if err != nil {
return
}
// Create application with options // Create application with options
err := wails.Run(&options.App{ err = wails.Run(&options.App{
Title: "ncmdump-gui", Title: "ncmdump-gui",
Width: 750, Width: 750,
Height: 500, Height: 500,
@@ -27,6 +35,17 @@ func main() {
OnStartup: app.startup, OnStartup: app.startup,
Bind: []interface{}{ Bind: []interface{}{
app, app,
config_manager,
},
DragAndDrop: &options.DragAndDrop{
EnableFileDrop: true,
DisableWebViewDrop: true,
},
Mac: &mac.Options{
About: &mac.AboutInfo{
Title: "ncmdump-gui",
Message: "Copyright © 2025 TaurusXin",
},
}, },
}) })

81
utils/config_manager.go Normal file
View File

@@ -0,0 +1,81 @@
package utils
import (
"encoding/json"
"os"
"path/filepath"
)
type SaveToType = string
const (
Original SaveToType = "original"
Custom SaveToType = "custom"
)
type Preference struct {
SaveTo SaveToType `json:"save_to"`
Path string `json:"path"`
}
type ConfigManager struct {
FilePath string
}
// NewConfigManager 创建一个新的配置管理器,自动适配不同操作系统的用户目录
func NewConfigManager(filename string) (*ConfigManager, error) {
configDir, err := os.UserConfigDir() // 获取用户配置目录
if err != nil {
return nil, err
}
dirPath := filepath.Join(configDir, "ncmdump-gui")
err = os.MkdirAll(dirPath, os.ModePerm)
if err != nil {
return nil, err
}
filePath := filepath.Join(dirPath, filename)
configManager := &ConfigManager{FilePath: filePath}
// if not exist, create it with default value
if _, err := os.Stat(filePath); os.IsNotExist(err) {
defaultConfig := &Preference{
SaveTo: Original,
Path: "",
}
configManager.Save(defaultConfig)
}
return &ConfigManager{FilePath: filePath}, nil
}
// Save 将配置保存到文件
func (cm *ConfigManager) Save(preference *Preference) bool {
file, err := os.Create(cm.FilePath)
if err != nil {
return false
}
defer file.Close()
encoder := json.NewEncoder(file)
encoder.SetIndent("", " ") // 格式化输出
err = encoder.Encode(preference)
return err == nil
}
// Load 从文件读取配置
func (cm *ConfigManager) Load() *Preference {
file, err := os.Open(cm.FilePath)
if err != nil {
return nil
}
defer file.Close()
var preference *Preference = nil
decoder := json.NewDecoder(file)
err = decoder.Decode(&preference)
if err != nil {
return nil
}
return preference
}

30
utils/file_util.go Normal file
View File

@@ -0,0 +1,30 @@
package utils
import (
"os"
"path/filepath"
)
func ListFilesFromFolder(root string, ext string) ([]string, error) {
var files []string
// Walk函数会遍历文件树递归地访问每个目录和文件
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// 检查是否是文件以及文件后缀是否匹配
if !info.IsDir() && filepath.Ext(path) == "."+ext {
files = append(files, path)
}
return nil
})
if err != nil {
return nil, err
}
return files, nil
}

View File

@@ -9,5 +9,12 @@
"author": { "author": {
"name": "TaurusXin", "name": "TaurusXin",
"email": "i@taurusxin.com" "email": "i@taurusxin.com"
},
"info": {
"companyName": "TaurusXin",
"productName": "ncmdump-gui",
"productVersion": "1.2.0",
"copyright": "Copyright © 2025 TaurusXin",
"comments": "Convert ncm to mp3/flac"
} }
} }