fix save history
This commit is contained in:
@@ -19,16 +19,16 @@ export enum Language {
|
||||
* WindowState 定义窗口状态
|
||||
*/
|
||||
export class WindowState {
|
||||
"Width": number;
|
||||
"Height": number;
|
||||
"width": number;
|
||||
"height": number;
|
||||
|
||||
/** Creates a new WindowState instance. */
|
||||
constructor($$source: Partial<WindowState> = {}) {
|
||||
if (!("Width" in $$source)) {
|
||||
this["Width"] = 0;
|
||||
if (!("width" in $$source)) {
|
||||
this["width"] = 0;
|
||||
}
|
||||
if (!("Height" in $$source)) {
|
||||
this["Height"] = 0;
|
||||
if (!("height" in $$source)) {
|
||||
this["height"] = 0;
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
|
||||
@@ -8,6 +8,9 @@ import { Call as $Call, CancellablePromise as $CancellablePromise, Create as $Cr
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as discovery$0 from "../discovery/models.js";
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as sync$0 from "../../../sync/models.js";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
@@ -45,6 +48,12 @@ export function GetTransferList(): $CancellablePromise<($models.Transfer | null)
|
||||
});
|
||||
}
|
||||
|
||||
export function GetTransferSyncMap(): $CancellablePromise<sync$0.Map | null> {
|
||||
return $Call.ByID(2986557111).then(($result: any) => {
|
||||
return $$createType4($result);
|
||||
});
|
||||
}
|
||||
|
||||
export function LoadHistory(): $CancellablePromise<void> {
|
||||
return $Call.ByID(2987999795);
|
||||
}
|
||||
@@ -61,8 +70,8 @@ export function ResolvePendingRequest(id: string, accept: boolean, savePath: str
|
||||
return $Call.ByID(207902967, id, accept, savePath);
|
||||
}
|
||||
|
||||
export function SaveHistory(transfers: ($models.Transfer | null)[]): $CancellablePromise<void> {
|
||||
return $Call.ByID(713135400, transfers);
|
||||
export function SaveHistory(): $CancellablePromise<void> {
|
||||
return $Call.ByID(713135400);
|
||||
}
|
||||
|
||||
export function SendFile(target: discovery$0.Peer | null, targetIP: string, filePath: string): $CancellablePromise<void> {
|
||||
@@ -97,3 +106,5 @@ export function StoreTransfersToList(transfers: ($models.Transfer | null)[]): $C
|
||||
const $$createType0 = $models.Transfer.createFrom;
|
||||
const $$createType1 = $Create.Nullable($$createType0);
|
||||
const $$createType2 = $Create.Array($$createType1);
|
||||
const $$createType3 = sync$0.Map.createFrom;
|
||||
const $$createType4 = $Create.Nullable($$createType3);
|
||||
|
||||
6
frontend/bindings/sync/index.ts
Normal file
6
frontend/bindings/sync/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export {
|
||||
Map
|
||||
} from "./models.js";
|
||||
52
frontend/bindings/sync/models.ts
Normal file
52
frontend/bindings/sync/models.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import { Create as $Create } from "@wailsio/runtime";
|
||||
|
||||
/**
|
||||
* Map is like a Go map[any]any but is safe for concurrent use
|
||||
* by multiple goroutines without additional locking or coordination.
|
||||
* Loads, stores, and deletes run in amortized constant time.
|
||||
*
|
||||
* The Map type is specialized. Most code should use a plain Go map instead,
|
||||
* with separate locking or coordination, for better type safety and to make it
|
||||
* easier to maintain other invariants along with the map content.
|
||||
*
|
||||
* The Map type is optimized for two common use cases: (1) when the entry for a given
|
||||
* key is only ever written once but read many times, as in caches that only grow,
|
||||
* or (2) when multiple goroutines read, write, and overwrite entries for disjoint
|
||||
* sets of keys. In these two cases, use of a Map may significantly reduce lock
|
||||
* contention compared to a Go map paired with a separate [Mutex] or [RWMutex].
|
||||
*
|
||||
* The zero Map is empty and ready for use. A Map must not be copied after first use.
|
||||
*
|
||||
* In the terminology of [the Go memory model], Map arranges that a write operation
|
||||
* “synchronizes before” any read operation that observes the effect of the write, where
|
||||
* read and write operations are defined as follows.
|
||||
* [Map.Load], [Map.LoadAndDelete], [Map.LoadOrStore], [Map.Swap], [Map.CompareAndSwap],
|
||||
* and [Map.CompareAndDelete] are read operations;
|
||||
* [Map.Delete], [Map.LoadAndDelete], [Map.Store], and [Map.Swap] are write operations;
|
||||
* [Map.LoadOrStore] is a write operation when it returns loaded set to false;
|
||||
* [Map.CompareAndSwap] is a write operation when it returns swapped set to true;
|
||||
* and [Map.CompareAndDelete] is a write operation when it returns deleted set to true.
|
||||
*
|
||||
* [the Go memory model]: https://go.dev/ref/mem
|
||||
*/
|
||||
export class Map {
|
||||
|
||||
/** Creates a new Map instance. */
|
||||
constructor($$source: Partial<Map> = {}) {
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Map instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): Map {
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
return new Map($$parsedSource as Partial<Map>);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,10 @@ body,
|
||||
/* 标准属性 */
|
||||
cursor: default;
|
||||
/* 鼠标指针变为默认箭头,而不是文本输入的 I 形 */
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"root":["./src/main.ts","./src/vite-env.d.ts","./src/plugins/i18n.ts","./src/plugins/index.ts","./src/plugins/vuetify.ts","./src/App.vue","./src/components/MainLayout.vue","./src/components/PeerCard.vue","./src/components/SettingsView.vue","./src/components/TransferItem.vue","./src/components/modals/FileSendModal.vue","./src/components/modals/TextSendModal.vue","./bindings/github.com/wailsapp/wails/v3/internal/eventcreate.ts","./bindings/github.com/wailsapp/wails/v3/internal/eventdata.d.ts","./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.ts","./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.ts","./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/notificationservice.ts","./bindings/mesh-drop/index.ts","./bindings/mesh-drop/models.ts","./bindings/mesh-drop/internal/config/config.ts","./bindings/mesh-drop/internal/config/index.ts","./bindings/mesh-drop/internal/config/models.ts","./bindings/mesh-drop/internal/discovery/index.ts","./bindings/mesh-drop/internal/discovery/models.ts","./bindings/mesh-drop/internal/discovery/service.ts","./bindings/mesh-drop/internal/transfer/index.ts","./bindings/mesh-drop/internal/transfer/models.ts","./bindings/mesh-drop/internal/transfer/service.ts","./bindings/time/index.ts","./bindings/time/models.ts"],"version":"5.9.3"}
|
||||
{"root":["./src/main.ts","./src/vite-env.d.ts","./src/plugins/i18n.ts","./src/plugins/index.ts","./src/plugins/vuetify.ts","./src/App.vue","./src/components/MainLayout.vue","./src/components/PeerCard.vue","./src/components/SettingsView.vue","./src/components/TransferItem.vue","./src/components/modals/FileSendModal.vue","./src/components/modals/TextSendModal.vue","./bindings/github.com/wailsapp/wails/v3/internal/eventcreate.ts","./bindings/github.com/wailsapp/wails/v3/internal/eventdata.d.ts","./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/index.ts","./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/models.ts","./bindings/github.com/wailsapp/wails/v3/pkg/services/notifications/notificationservice.ts","./bindings/mesh-drop/index.ts","./bindings/mesh-drop/models.ts","./bindings/mesh-drop/internal/config/config.ts","./bindings/mesh-drop/internal/config/index.ts","./bindings/mesh-drop/internal/config/models.ts","./bindings/mesh-drop/internal/discovery/index.ts","./bindings/mesh-drop/internal/discovery/models.ts","./bindings/mesh-drop/internal/discovery/service.ts","./bindings/mesh-drop/internal/transfer/index.ts","./bindings/mesh-drop/internal/transfer/models.ts","./bindings/mesh-drop/internal/transfer/service.ts","./bindings/sync/index.ts","./bindings/sync/models.ts","./bindings/time/index.ts","./bindings/time/models.ts"],"version":"5.9.3"}
|
||||
10
go.mod
10
go.mod
@@ -5,7 +5,6 @@ go 1.25
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.68
|
||||
)
|
||||
|
||||
@@ -24,7 +23,6 @@ require (
|
||||
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
|
||||
github.com/ebitengine/purego v0.9.1 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
@@ -34,7 +32,6 @@ require (
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/goccy/go-yaml v1.18.0 // indirect
|
||||
github.com/godbus/dbus/v5 v5.2.2 // indirect
|
||||
@@ -58,21 +55,14 @@ require (
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.54.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/samber/lo v1.52.0 // indirect
|
||||
github.com/sergi/go-diff v1.4.0 // indirect
|
||||
github.com/skeema/knownhosts v1.3.2 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||
github.com/wailsapp/go-webview2 v1.0.23 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/arch v0.20.0 // indirect
|
||||
golang.org/x/crypto v0.47.0 // indirect
|
||||
golang.org/x/mod v0.32.0 // indirect
|
||||
|
||||
22
go.sum
22
go.sum
@@ -36,10 +36,6 @@ github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o
|
||||
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
@@ -68,8 +64,6 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
|
||||
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||
@@ -140,8 +134,6 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw=
|
||||
github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
|
||||
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
|
||||
@@ -149,16 +141,6 @@ github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepq
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skeema/knownhosts v1.3.2 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg=
|
||||
github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@@ -170,8 +152,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
||||
@@ -184,8 +164,6 @@ github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
|
||||
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"mesh-drop/internal/security"
|
||||
"os"
|
||||
@@ -8,13 +9,12 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// WindowState 定义窗口状态
|
||||
type WindowState struct {
|
||||
Width int `mapstructure:"width"`
|
||||
Height int `mapstructure:"height"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
}
|
||||
|
||||
var Version = "next"
|
||||
@@ -27,24 +27,24 @@ const (
|
||||
)
|
||||
|
||||
type configData struct {
|
||||
WindowState WindowState `mapstructure:"window_state"`
|
||||
ID string `mapstructure:"id"`
|
||||
PrivateKey string `mapstructure:"private_key"`
|
||||
PublicKey string `mapstructure:"public_key"`
|
||||
SavePath string `mapstructure:"save_path"`
|
||||
HostName string `mapstructure:"host_name"`
|
||||
AutoAccept bool `mapstructure:"auto_accept"`
|
||||
SaveHistory bool `mapstructure:"save_history"`
|
||||
TrustedPeer map[string]string `mapstructure:"trusted_peer"` // ID -> PublicKey
|
||||
WindowState WindowState `json:"window_state"`
|
||||
ID string `json:"id"`
|
||||
PrivateKey string `json:"private_key"`
|
||||
PublicKey string `json:"public_key"`
|
||||
SavePath string `json:"save_path"`
|
||||
HostName string `json:"host_name"`
|
||||
AutoAccept bool `json:"auto_accept"`
|
||||
SaveHistory bool `json:"save_history"`
|
||||
TrustedPeer map[string]string `json:"trusted_peer"` // ID -> PublicKey
|
||||
|
||||
Language Language `mapstructure:"language"`
|
||||
CloseToSystray bool `mapstructure:"close_to_systray"`
|
||||
Language Language `json:"language"`
|
||||
CloseToSystray bool `json:"close_to_systray"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
v *viper.Viper
|
||||
mu sync.RWMutex
|
||||
data configData
|
||||
configPath string
|
||||
}
|
||||
|
||||
func GetConfigDir() string {
|
||||
@@ -65,36 +65,45 @@ func GetUserHomeDir() string {
|
||||
|
||||
// New 读取配置
|
||||
func Load(defaultState WindowState) *Config {
|
||||
v := viper.New()
|
||||
configDir := GetConfigDir()
|
||||
err := os.MkdirAll(configDir, 0755)
|
||||
if err != nil {
|
||||
slog.Error("Failed to create config directory", "error", err)
|
||||
}
|
||||
_ = os.MkdirAll(configDir, 0755)
|
||||
configFile := filepath.Join(configDir, "config.json")
|
||||
|
||||
// 设置默认值
|
||||
defaultSavePath := filepath.Join(GetUserHomeDir(), "Downloads")
|
||||
v.SetDefault("window_state", defaultState)
|
||||
v.SetDefault("save_path", defaultSavePath)
|
||||
defaultHostName, err := os.Hostname()
|
||||
if err != nil {
|
||||
defaultHostName = "localhost"
|
||||
}
|
||||
v.SetDefault("host_name", defaultHostName)
|
||||
v.SetDefault("id", uuid.New().String())
|
||||
v.SetDefault("save_history", true)
|
||||
|
||||
v.SetConfigFile(configFile)
|
||||
v.SetConfigType("json")
|
||||
|
||||
// 尝试读取配置
|
||||
if err := v.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||
slog.Info("Config file not found, using defaults")
|
||||
} else {
|
||||
slog.Warn("Failed to read config file, using defaults", "error", err)
|
||||
cfgData := configData{
|
||||
WindowState: defaultState,
|
||||
SavePath: defaultSavePath,
|
||||
AutoAccept: false,
|
||||
SaveHistory: true,
|
||||
Language: LanguageEnglish,
|
||||
CloseToSystray: false,
|
||||
ID: uuid.New().String(),
|
||||
HostName: defaultHostName,
|
||||
TrustedPeer: make(map[string]string),
|
||||
}
|
||||
|
||||
fileBytes, err := os.ReadFile(configFile)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
slog.Error("Failed to read config file", "error", err)
|
||||
} else {
|
||||
slog.Info("Config file not found, creating new one")
|
||||
}
|
||||
} else {
|
||||
if err := json.Unmarshal(fileBytes, &cfgData); err != nil {
|
||||
slog.Error("Failed to unmarshal config", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
config := Config{
|
||||
data: cfgData,
|
||||
configPath: configFile,
|
||||
}
|
||||
|
||||
// 确保默认保存路径存在
|
||||
@@ -103,16 +112,6 @@ func Load(defaultState WindowState) *Config {
|
||||
slog.Error("Failed to create default save path", "path", defaultSavePath, "error", err)
|
||||
}
|
||||
|
||||
var data configData
|
||||
if err := v.Unmarshal(&data); err != nil {
|
||||
slog.Error("Failed to unmarshal config", "error", err)
|
||||
}
|
||||
|
||||
config := Config{
|
||||
v: v,
|
||||
data: data,
|
||||
}
|
||||
|
||||
// 如果没有密钥对,生成新的
|
||||
if config.data.PrivateKey == "" || config.data.PublicKey == "" {
|
||||
priv, pub, err := security.GenerateKey()
|
||||
@@ -121,12 +120,6 @@ func Load(defaultState WindowState) *Config {
|
||||
} else {
|
||||
config.data.PrivateKey = priv
|
||||
config.data.PublicKey = pub
|
||||
v.Set("private_key", priv)
|
||||
v.Set("public_key", pub)
|
||||
// 保存新生成的密钥
|
||||
if err := config.Save(); err != nil {
|
||||
slog.Error("Failed to save generated keys", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +128,11 @@ func Load(defaultState WindowState) *Config {
|
||||
config.data.TrustedPeer = make(map[string]string)
|
||||
}
|
||||
|
||||
// 保存
|
||||
if err := config.Save(); err != nil {
|
||||
slog.Error("Failed to save config", "error", err)
|
||||
}
|
||||
|
||||
return &config
|
||||
}
|
||||
|
||||
@@ -146,21 +144,21 @@ func (c *Config) Save() error {
|
||||
}
|
||||
|
||||
func (c *Config) save() error {
|
||||
configDir := GetConfigDir()
|
||||
if err := os.MkdirAll(configDir, 0755); err != nil {
|
||||
dir := filepath.Dir(c.configPath)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.v.WriteConfig(); err != nil {
|
||||
slog.Error("Failed to write config", "error", err)
|
||||
jsonData, err := json.MarshalIndent(c.data, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 设置配置文件权限为 0600 (仅所有者读写)
|
||||
configFile := c.v.ConfigFileUsed()
|
||||
if configFile != "" {
|
||||
if err := os.Chmod(configFile, 0600); err != nil {
|
||||
slog.Warn("Failed to set config file permissions", "error", err)
|
||||
if c.configPath != "" {
|
||||
if err := os.WriteFile(c.configPath, jsonData, 0600); err != nil {
|
||||
slog.Warn("Failed to write config file", "error", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +181,6 @@ func (c *Config) update(fn func()) {
|
||||
func (c *Config) SetSavePath(savePath string) {
|
||||
c.update(func() {
|
||||
c.data.SavePath = savePath
|
||||
c.v.Set("save_path", savePath)
|
||||
_ = os.MkdirAll(savePath, 0755)
|
||||
})
|
||||
}
|
||||
@@ -197,7 +194,6 @@ func (c *Config) GetSavePath() string {
|
||||
func (c *Config) SetHostName(hostName string) {
|
||||
c.update(func() {
|
||||
c.data.HostName = hostName
|
||||
c.v.Set("host_name", hostName)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -216,7 +212,6 @@ func (c *Config) GetID() string {
|
||||
func (c *Config) SetAutoAccept(autoAccept bool) {
|
||||
c.update(func() {
|
||||
c.data.AutoAccept = autoAccept
|
||||
c.v.Set("auto_accept", autoAccept)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -229,7 +224,6 @@ func (c *Config) GetAutoAccept() bool {
|
||||
func (c *Config) SetSaveHistory(saveHistory bool) {
|
||||
c.update(func() {
|
||||
c.data.SaveHistory = saveHistory
|
||||
c.v.Set("save_history", saveHistory)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -246,7 +240,6 @@ func (c *Config) GetVersion() string {
|
||||
func (c *Config) SetWindowState(state WindowState) {
|
||||
c.update(func() {
|
||||
c.data.WindowState = state
|
||||
c.v.Set("window_state", state)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -262,7 +255,6 @@ func (c *Config) AddTrust(peerID string, publicKey string) {
|
||||
c.data.TrustedPeer = make(map[string]string)
|
||||
}
|
||||
c.data.TrustedPeer[peerID] = publicKey
|
||||
c.v.Set("trusted_peer", c.data.TrustedPeer)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -275,7 +267,6 @@ func (c *Config) GetTrusted() map[string]string {
|
||||
func (c *Config) RemoveTrust(peerID string) {
|
||||
c.update(func() {
|
||||
delete(c.data.TrustedPeer, peerID)
|
||||
c.v.Set("trusted_peer", c.data.TrustedPeer)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -289,7 +280,6 @@ func (c *Config) IsTrusted(peerID string) bool {
|
||||
func (c *Config) SetLanguage(language Language) {
|
||||
c.update(func() {
|
||||
c.data.Language = language
|
||||
c.v.Set("language", language)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -302,7 +292,6 @@ func (c *Config) GetLanguage() Language {
|
||||
func (c *Config) SetCloseToSystray(closeToSystray bool) {
|
||||
c.update(func() {
|
||||
c.data.CloseToSystray = closeToSystray
|
||||
c.v.Set("close_to_systray", closeToSystray)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -8,25 +8,36 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func (s *Service) SaveHistory(transfers []*Transfer) {
|
||||
func (s *Service) SaveHistory() {
|
||||
if !s.config.GetSaveHistory() {
|
||||
return
|
||||
}
|
||||
configDir := config.GetConfigDir()
|
||||
historyPath := filepath.Join(configDir, "history.json")
|
||||
historyJson, err := json.Marshal(transfers)
|
||||
tempPath := historyPath + ".tmp"
|
||||
|
||||
// 序列化传输列表
|
||||
historyJson, err := json.MarshalIndent(s.GetTransferList(), "", " ")
|
||||
if err != nil {
|
||||
slog.Error("Failed to marshal history", "error", err, "component", "transfer")
|
||||
return
|
||||
}
|
||||
file, err := os.OpenFile(historyPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
|
||||
// 写入临时文件
|
||||
if err := os.WriteFile(tempPath, historyJson, 0644); err != nil {
|
||||
slog.Error("Failed to write temp history file", "error", err, "component", "transfer")
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
_, err = file.Write(historyJson)
|
||||
if err != nil {
|
||||
slog.Error("Failed to write history", "error", err)
|
||||
|
||||
// 原子性重命名
|
||||
if err := os.Rename(tempPath, historyPath); err != nil {
|
||||
slog.Error("Failed to rename temp history file", "error", err, "component", "transfer")
|
||||
// 清理临时文件
|
||||
_ = os.Remove(tempPath)
|
||||
return
|
||||
}
|
||||
|
||||
slog.Info("History saved successfully", "path", historyPath, "component", "transfer")
|
||||
}
|
||||
|
||||
func (s *Service) LoadHistory() {
|
||||
|
||||
@@ -32,7 +32,7 @@ func (s *Service) handleAsk(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 检查是否已经存在
|
||||
if _, exists := s.transferList.Load(task.ID); exists {
|
||||
if _, exists := s.transfers.Load(task.ID); exists {
|
||||
// 如果已经存在,说明是网络重试,直接忽略
|
||||
return
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ type Service struct {
|
||||
|
||||
// pendingRequests 存储等待用户确认的通道
|
||||
// Key: TransferID, Value: *Transfer
|
||||
transferList sync.Map
|
||||
transfers sync.Map
|
||||
|
||||
discoveryService *discovery.Service
|
||||
|
||||
@@ -90,9 +90,13 @@ func (s *Service) Start() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (s *Service) GetTransferSyncMap() *sync.Map {
|
||||
return &s.transfers
|
||||
}
|
||||
|
||||
func (s *Service) GetTransferList() []*Transfer {
|
||||
var requests []*Transfer = make([]*Transfer, 0)
|
||||
s.transferList.Range(func(key, value any) bool {
|
||||
s.transfers.Range(func(key, value any) bool {
|
||||
transfer := value.(*Transfer)
|
||||
requests = append(requests, transfer)
|
||||
return true
|
||||
@@ -105,7 +109,7 @@ func (s *Service) GetTransferList() []*Transfer {
|
||||
}
|
||||
|
||||
func (s *Service) GetTransfer(transferID string) (*Transfer, bool) {
|
||||
val, ok := s.transferList.Load(transferID)
|
||||
val, ok := s.transfers.Load(transferID)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
@@ -126,15 +130,13 @@ func (s *Service) CancelTransfer(transferID string) {
|
||||
|
||||
func (s *Service) StoreTransfersToList(transfers []*Transfer) {
|
||||
for _, transfer := range transfers {
|
||||
s.transferList.Store(transfer.ID, transfer)
|
||||
s.transfers.Store(transfer.ID, transfer)
|
||||
}
|
||||
s.SaveHistory(transfers)
|
||||
s.NotifyTransferListUpdate()
|
||||
}
|
||||
|
||||
func (s *Service) StoreTransferToList(transfer *Transfer) {
|
||||
s.transferList.Store(transfer.ID, transfer)
|
||||
s.SaveHistory([]*Transfer{transfer})
|
||||
s.transfers.Store(transfer.ID, transfer)
|
||||
s.NotifyTransferListUpdate()
|
||||
}
|
||||
|
||||
@@ -144,22 +146,20 @@ func (s *Service) NotifyTransferListUpdate() {
|
||||
|
||||
// CleanTransferList 清理完成的 transfer
|
||||
func (s *Service) CleanFinishedTransferList() {
|
||||
s.transferList.Range(func(key, value any) bool {
|
||||
s.transfers.Range(func(key, value any) bool {
|
||||
task := value.(*Transfer)
|
||||
if task.Status == TransferStatusCompleted ||
|
||||
task.Status == TransferStatusError ||
|
||||
task.Status == TransferStatusCanceled ||
|
||||
task.Status == TransferStatusRejected {
|
||||
s.transferList.Delete(key)
|
||||
s.transfers.Delete(key)
|
||||
}
|
||||
return true
|
||||
})
|
||||
s.SaveHistory(s.GetTransferList())
|
||||
s.NotifyTransferListUpdate()
|
||||
}
|
||||
|
||||
func (s *Service) DeleteTransfer(transferID string) {
|
||||
s.transferList.Delete(transferID)
|
||||
s.SaveHistory(s.GetTransferList())
|
||||
s.transfers.Delete(transferID)
|
||||
s.NotifyTransferListUpdate()
|
||||
}
|
||||
|
||||
13
main.go
13
main.go
@@ -163,14 +163,15 @@ func (a *App) setupEvents() {
|
||||
// 保存传输历史
|
||||
if a.conf.GetSaveHistory() {
|
||||
// 将 pending 状态的任务改为 canceled
|
||||
t := a.transferService.GetTransferList()
|
||||
for _, task := range t {
|
||||
if task.Status == transfer.TransferStatusPending {
|
||||
task.Status = transfer.TransferStatusCanceled
|
||||
}
|
||||
a.transferService.GetTransferSyncMap().Range(func(key, value any) bool {
|
||||
t := value.(*transfer.Transfer)
|
||||
if t.Status == transfer.TransferStatusPending {
|
||||
t.Status = transfer.TransferStatusCanceled
|
||||
}
|
||||
return true
|
||||
})
|
||||
// 保存传输历史
|
||||
a.transferService.SaveHistory(t)
|
||||
a.transferService.SaveHistory()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user