Skip to content

Commit 8389395

Browse files
committed
feat: support send-only folders (fixes #106)
Signed-off-by: Tommy van der Vorst <tommy@pixelspark.nl>
1 parent 0376c58 commit 8389395

File tree

5 files changed

+234
-14
lines changed

5 files changed

+234
-14
lines changed

Localizable.xcstrings

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7256,6 +7256,144 @@
72567256
}
72577257
}
72587258
},
7259+
"Changes from other devices will be accepted, and changes made on this device will be sent to other devices." : {
7260+
"localizations" : {
7261+
"de" : {
7262+
"stringUnit" : {
7263+
"state" : "translated",
7264+
"value" : "Änderungen von anderen Geräten werden akzeptiert, und Änderungen, die auf diesem Gerät vorgenommen werden, werden an andere Geräte gesendet."
7265+
}
7266+
},
7267+
"es" : {
7268+
"stringUnit" : {
7269+
"state" : "translated",
7270+
"value" : "Los cambios de otros dispositivos serán aceptados y los cambios realizados en este dispositivo se enviarán a otros dispositivos."
7271+
}
7272+
},
7273+
"it" : {
7274+
"stringUnit" : {
7275+
"state" : "translated",
7276+
"value" : "Le modifiche provenienti da altri dispositivi verranno accettate e le modifiche apportate su questo dispositivo verranno inviate agli altri dispositivi."
7277+
}
7278+
},
7279+
"ja" : {
7280+
"stringUnit" : {
7281+
"state" : "translated",
7282+
"value" : "他のデバイスからの変更は受け入れられ、このデバイスで行われた変更は他のデバイスに送信されます。"
7283+
}
7284+
},
7285+
"nl" : {
7286+
"stringUnit" : {
7287+
"state" : "translated",
7288+
"value" : "Wijzigingen van andere apparaten zullen worden geaccepteerd en wijzigingen die op dit apparaat zijn gemaakt, zullen naar andere apparaten worden verzonden."
7289+
}
7290+
},
7291+
"uk" : {
7292+
"stringUnit" : {
7293+
"state" : "translated",
7294+
"value" : "Зміни з інших пристроїв будуть прийняті, а зміни, внесені на цьому пристрої, будуть надіслані на інші пристрої."
7295+
}
7296+
},
7297+
"zh-Hans" : {
7298+
"stringUnit" : {
7299+
"state" : "translated",
7300+
"value" : "来自其他设备的更改将被接受,并且在此设备上进行的更改将发送到其他设备。"
7301+
}
7302+
}
7303+
}
7304+
},
7305+
"Changes from other devices will be accepted. Changes made on this device will not be sent to other devices." : {
7306+
"localizations" : {
7307+
"de" : {
7308+
"stringUnit" : {
7309+
"state" : "translated",
7310+
"value" : "Änderungen von anderen Geräten werden akzeptiert. Änderungen, die auf diesem Gerät vorgenommen wurden, werden nicht an andere Geräte gesendet."
7311+
}
7312+
},
7313+
"es" : {
7314+
"stringUnit" : {
7315+
"state" : "translated",
7316+
"value" : "Los cambios de otros dispositivos serán aceptados. Los cambios realizados en este dispositivo no se enviarán a otros dispositivos."
7317+
}
7318+
},
7319+
"it" : {
7320+
"stringUnit" : {
7321+
"state" : "translated",
7322+
"value" : "Le modifiche da altri dispositivi verranno accettate. Le modifiche apportate su questo dispositivo non verranno inviate ad altri dispositivi."
7323+
}
7324+
},
7325+
"ja" : {
7326+
"stringUnit" : {
7327+
"state" : "translated",
7328+
"value" : "他のデバイスからの変更は受け入れられます。このデバイスで行われた変更は他のデバイスに送信されません。"
7329+
}
7330+
},
7331+
"nl" : {
7332+
"stringUnit" : {
7333+
"state" : "translated",
7334+
"value" : "Wijzigingen van andere apparaten worden geaccepteerd. Wijzigingen gemaakt op dit apparaat worden niet naar andere apparaten verzonden."
7335+
}
7336+
},
7337+
"uk" : {
7338+
"stringUnit" : {
7339+
"state" : "translated",
7340+
"value" : "Зміни з інших пристроїв будуть прийняті. Зміни, внесені на цьому пристрої, не будут відправлені на інші пристрої."
7341+
}
7342+
},
7343+
"zh-Hans" : {
7344+
"stringUnit" : {
7345+
"state" : "translated",
7346+
"value" : "来自其他设备的更改将被接受。在此设备上所做的更改将不会发送到其他设备。"
7347+
}
7348+
}
7349+
}
7350+
},
7351+
"Changes made on this device will be sent to other devices. Changes from other devices will not be accepted." : {
7352+
"localizations" : {
7353+
"de" : {
7354+
"stringUnit" : {
7355+
"state" : "translated",
7356+
"value" : "Änderungen, die auf diesem Gerät vorgenommen werden, werden an andere Geräte gesendet. Änderungen von anderen Geräten werden nicht akzeptiert."
7357+
}
7358+
},
7359+
"es" : {
7360+
"stringUnit" : {
7361+
"state" : "translated",
7362+
"value" : "Los cambios realizados en este dispositivo se enviarán a otros dispositivos. No se aceptarán cambios de otros dispositivos."
7363+
}
7364+
},
7365+
"it" : {
7366+
"stringUnit" : {
7367+
"state" : "translated",
7368+
"value" : "Le modifiche apportate su questo dispositivo verranno inviate ad altri dispositivi. Le modifiche provenienti da altri dispositivi non verranno accettate."
7369+
}
7370+
},
7371+
"ja" : {
7372+
"stringUnit" : {
7373+
"state" : "translated",
7374+
"value" : "このデバイスで行われた変更は他のデバイスに送信されます。他のデバイスからの変更は受け付けられません。"
7375+
}
7376+
},
7377+
"nl" : {
7378+
"stringUnit" : {
7379+
"state" : "translated",
7380+
"value" : "Wijzigingen die op dit apparaat zijn aangebracht, worden naar andere apparaten verzonden. Wijzigingen van andere apparaten worden niet geaccepteerd."
7381+
}
7382+
},
7383+
"uk" : {
7384+
"stringUnit" : {
7385+
"state" : "translated",
7386+
"value" : "Зміни, внесені на цьому пристрої, будуть надіслані на інші пристрої. Зміни з інших пристроїв не будуть прийняті."
7387+
}
7388+
},
7389+
"zh-Hans" : {
7390+
"stringUnit" : {
7391+
"state" : "translated",
7392+
"value" : "此设备上的更改将发送到其他设备。来自其他设备的更改将不被接受。"
7393+
}
7394+
}
7395+
}
7396+
},
72597397
"Checking availability on other devices..." : {
72607398
"localizations" : {
72617399
"de" : {
@@ -32056,6 +32194,52 @@
3205632194
}
3205732195
}
3205832196
},
32197+
"Synchronize with other devices" : {
32198+
"localizations" : {
32199+
"de" : {
32200+
"stringUnit" : {
32201+
"state" : "translated",
32202+
"value" : "Mit anderen Geräten synchronisieren"
32203+
}
32204+
},
32205+
"es" : {
32206+
"stringUnit" : {
32207+
"state" : "translated",
32208+
"value" : "Sincronizar con otros dispositivos"
32209+
}
32210+
},
32211+
"it" : {
32212+
"stringUnit" : {
32213+
"state" : "translated",
32214+
"value" : "Sincronizza con altri dispositivi"
32215+
}
32216+
},
32217+
"ja" : {
32218+
"stringUnit" : {
32219+
"state" : "translated",
32220+
"value" : "他のデバイスと同期"
32221+
}
32222+
},
32223+
"nl" : {
32224+
"stringUnit" : {
32225+
"state" : "translated",
32226+
"value" : "Synchroniseer met andere apparaten"
32227+
}
32228+
},
32229+
"uk" : {
32230+
"stringUnit" : {
32231+
"state" : "translated",
32232+
"value" : "Синхронізувати з іншими пристроями"
32233+
}
32234+
},
32235+
"zh-Hans" : {
32236+
"stringUnit" : {
32237+
"state" : "translated",
32238+
"value" : "与其他设备同步"
32239+
}
32240+
}
32241+
}
32242+
},
3205932243
"Synchronize with this device" : {
3206032244
"localizations" : {
3206132245
"de" : {

Sushitrain/BrowserListView.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,15 +366,19 @@ private struct ItemSelectSwipeView<Content: View>: View {
366366
Button {
367367
Task { self.errorMessage = await self.file.setSelectedFromToggle(s: false) }
368368
} label: {
369-
Label("Do not synchronize with this device", systemImage: "pin.slash")
369+
Label(
370+
file.folder!.isSendOnlyFolder ? "Synchronize with other devices" : "Do not synchronize with this device",
371+
systemImage: "pin.slash")
370372
}.tint(.red)
371373
}
372374
else {
373375
// Select button
374376
Button {
375377
Task { self.errorMessage = await self.file.setSelectedFromToggle(s: true) }
376378
} label: {
377-
Label("Synchronize with this device", systemImage: "pin")
379+
Label(
380+
file.folder!.isSendOnlyFolder ? "Synchronize with other devices" : "Synchronize with this device",
381+
systemImage: "pin")
378382
}
379383
}
380384
}

Sushitrain/FolderView.swift

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,13 @@ struct FolderSyncTypePicker: View {
289289
var body: some View {
290290
Picker("Selection", selection: $folderSyncType) {
291291
Text("All files").tag(FolderSyncType.allFiles)
292+
292293
Text("Selected files").tag(FolderSyncType.selectedFiles)
294+
.disabled(folder.isSendOnlyFolder)
295+
.selectionDisabled(folder.isSendOnlyFolder)
293296

294297
if folderSyncType == nil {
295-
Text("(Unknown)").tag(nil as FolderSyncType?).disabled(true)
298+
Text("(Unknown)").tag(nil as FolderSyncType?).disabled(true).selectionDisabled()
296299
}
297300
}
298301
.onChange(of: folderSyncType) { ov, nv in
@@ -347,17 +350,30 @@ struct FolderDirectionPicker: View {
347350
var body: some View {
348351
if folder.exists() {
349352
Picker("Direction", selection: $folderType) {
350-
Text("Send and receive").tag(SushitrainFolderTypeSendReceive as String?)
351-
Text("Receive only").tag(SushitrainFolderTypeReceiveOnly as String?)
353+
Text("Send and receive")
354+
.help(
355+
"Changes from other devices will be accepted, and changes made on this device will be sent to other devices."
356+
)
357+
.tag(SushitrainFolderTypeSendReceive as String?)
358+
359+
Text("Receive only")
360+
.help(
361+
"Changes from other devices will be accepted. Changes made on this device will not be sent to other devices."
362+
)
363+
.tag(SushitrainFolderTypeReceiveOnly as String?)
352364

353365
if folderType == nil {
354-
Text("(Unknown)").tag(nil as String?).disabled(true)
366+
Text("(Unknown)").tag(nil as String?)
367+
.disabled(true)
368+
.selectionDisabled()
355369
}
356370

357-
// Cannot be selected, but should be here when it is set
358-
if folder.folderType() == SushitrainFolderTypeSendOnly {
359-
Text("Send only").tag(SushitrainFolderTypeSendOnly as String?)
360-
}
371+
Text("Send only").tag(SushitrainFolderTypeSendOnly as String?)
372+
.help(
373+
"Changes made on this device will be sent to other devices. Changes from other devices will not be accepted."
374+
)
375+
.disabled(folder.isSelective())
376+
.selectionDisabled(folder.isSelective())
361377
}
362378
.pickerStyle(.menu)
363379
.disabled(changeProhibited)
@@ -654,9 +670,9 @@ struct FolderView: View {
654670
Text("Display name")
655671
}
656672

657-
FolderDirectionPicker(folder: folder).disabled(isPhotoFolder)
673+
FolderDirectionPicker(folder: folder).disabled(isPhotoFolder).id(appState.eventCounter)
658674

659-
FolderSyncTypePicker(folder: folder).disabled(isPhotoFolder)
675+
FolderSyncTypePicker(folder: folder).disabled(isPhotoFolder).id(appState.eventCounter)
660676
} header: {
661677
Text("Folder settings")
662678
} footer: {
@@ -1268,7 +1284,7 @@ private struct AdvancedFolderSettingsView: View {
12681284
Text("Rescan interval (minutes)")
12691285
}
12701286

1271-
if !folder.isPhotoFolder {
1287+
if !folder.isPhotoFolder && !folder.isSendOnlyFolder {
12721288
Toggle(
12731289
"Keep conflicting versions",
12741290
isOn: Binding(
@@ -1281,7 +1297,7 @@ private struct AdvancedFolderSettingsView: View {
12811297
}
12821298
}
12831299

1284-
if !folder.isPhotoFolder {
1300+
if !folder.isPhotoFolder && !folder.isReceiveOnlyFolder {
12851301
Section {
12861302
Toggle(
12871303
"Watch for changes",

Sushitrain/Utils.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ extension SushitrainFolder {
167167
}
168168
}
169169

170+
var isSendOnlyFolder: Bool {
171+
return self.folderType() == SushitrainFolderTypeSendOnly
172+
}
173+
174+
var isReceiveOnlyFolder: Bool {
175+
return self.folderType() == SushitrainFolderTypeReceiveOnly
176+
}
177+
170178
var isRegularFolder: Bool {
171179
let fsType = self.filesystemType()
172180
return fsType == "basic" || fsType == ""

SushitrainCore/src/folder.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ func (fld *Folder) SetFolderType(folderType string) error {
585585
fc.Type = config.FolderTypeReceiveOnly
586586
case FolderTypeSendReceive:
587587
fc.Type = config.FolderTypeSendReceive
588+
case FolderTypeSendOnly:
589+
fc.Type = config.FolderTypeSendOnly
588590
default:
589591
// Don't change
590592
return
@@ -603,6 +605,12 @@ func (fld *Folder) IsSelective() bool {
603605
return false
604606
}
605607

608+
// Send-only folders cannot be selective
609+
// They can still have the '*' in the ignore file, but we refuse to do our selective magic
610+
if fc.Type == config.FolderTypeSendOnly {
611+
return false
612+
}
613+
606614
ignores, err := fld.loadIgnores()
607615
if err != nil {
608616
return false

0 commit comments

Comments
 (0)