feat: Sync tab, hamburger menu, network status, browse UX

- Replace History tab with Sync tab (file list, NAS status, free-up-space retention)
- Add AppMenuView hamburger sheet (History, Errors, Connection Status, Sync Activity)
- BackupView: Kisani logo chip in toolbar, hamburger menu button, swipeable ring
  pages (progress/pending/failed/uploaded), always-visible compact stats strip
- SettingsView: NETWORK section (SSID, NAS reachability, trusted-network warning,
  refresh button)
- BrowseView: pull-to-refresh, long-press context menu on items
- LANMonitor: nasReachable, nasCheckTime, checkNASReachability(host:port:)
- ConnectionStore: localRetentionDays (0/60/90/365 days)
- Regenerate xcodeproj with xcodegen to include new files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Robin Kutesa
2026-05-16 17:58:00 +03:00
parent e1e851360b
commit 15f9da843c
9 changed files with 1129 additions and 53 deletions

View File

@@ -10,6 +10,7 @@
10062AA91BC883AE597443BD /* URL+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 277DF2E5F4E566C869EC29F3 /* URL+.swift */; };
13FCA7D0BB01BFC46A5B725B /* SavedConnections.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D1C00B125D5CC000988DD0 /* SavedConnections.swift */; };
30693CB8EE711577978EF88C /* Date+.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6CD83D8292EF9EFBE3A9C6C /* Date+.swift */; };
32A4A6A2CFB6C810A8C2CE0B /* AppMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67C33F6CACACB9DD50FE3F40 /* AppMenuView.swift */; };
36FE83FFC24922EBC28287BB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88E66C22B614E89A7A9E9B35 /* AppDelegate.swift */; };
37D808079BDEF32D04847D04 /* MainTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F09160B7B7A06BD900D0D87A /* MainTabView.swift */; };
4148416D31C8AC65FEE6394F /* PHAsset+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86FA0D1522E2C4FF7C1CABF3 /* PHAsset+.swift */; };
@@ -42,6 +43,7 @@
B50445A9010E20F97E9E6E48 /* ProgressRing.swift in Sources */ = {isa = PBXBuildFile; fileRef = C955FEF6710E3667C7A73A02 /* ProgressRing.swift */; };
B7DBF1420838AD3397A280B5 /* BackupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55EA454B783C2AEDABFB00A7 /* BackupView.swift */; };
BC4346F01DAA4DE7D8F260DB /* SFTPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67584BB6D705BCB3D40192 /* SFTPService.swift */; };
BEBDBED4A7D1D786C47DB8EE /* SyncView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A1E7D60A4D778026CC8007F /* SyncView.swift */; };
C6AAC362F058E7836A91AC30 /* ConnectViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91197DD51221A3277AE318E2 /* ConnectViewModel.swift */; };
C8E9BC6070E23992EED8D013 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D17A73A05A6FDF2B89C6B2 /* SettingsView.swift */; };
CE47E9F2179F86BE0A630D91 /* LANMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5606A4C5894CFC72D555CAE1 /* LANMonitor.swift */; };
@@ -85,6 +87,8 @@
55EA454B783C2AEDABFB00A7 /* BackupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupView.swift; sourceTree = "<group>"; };
5606A4C5894CFC72D555CAE1 /* LANMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LANMonitor.swift; sourceTree = "<group>"; };
5643379BBA1FD39841F9EA55 /* BackgroundTaskManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskManager.swift; sourceTree = "<group>"; };
67C33F6CACACB9DD50FE3F40 /* AppMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMenuView.swift; sourceTree = "<group>"; };
6A1E7D60A4D778026CC8007F /* SyncView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncView.swift; sourceTree = "<group>"; };
6EEBCD4A838173E557DC3EFC /* HistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryView.swift; sourceTree = "<group>"; };
74E2AF8B56C469E0D94EFE94 /* PhotoLibraryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryProtocol.swift; sourceTree = "<group>"; };
7688CD7E9BC5475A3EB01021 /* NASProtocolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NASProtocolTests.swift; sourceTree = "<group>"; };
@@ -143,6 +147,7 @@
FDF5327105186A6456CF0B08 /* Login */,
611BB6A8B01D82432C0A32EC /* Onboarding */,
147B04CA2B7A7723CCD13E93 /* Settings */,
DFE38DFA4C8F1E08CBCC8626 /* Sync */,
);
path = Features;
sourceTree = "<group>";
@@ -233,6 +238,7 @@
803154EA96E2431367806BAF /* Backup */ = {
isa = PBXGroup;
children = (
67C33F6CACACB9DD50FE3F40 /* AppMenuView.swift */,
55EA454B783C2AEDABFB00A7 /* BackupView.swift */,
AC73AD75762D4357D171CDA4 /* BackupViewModel.swift */,
);
@@ -336,6 +342,14 @@
path = Tests;
sourceTree = "<group>";
};
DFE38DFA4C8F1E08CBCC8626 /* Sync */ = {
isa = PBXGroup;
children = (
6A1E7D60A4D778026CC8007F /* SyncView.swift */,
);
path = Sync;
sourceTree = "<group>";
};
F75092ACBEF36F32816506F7 /* Models */ = {
isa = PBXGroup;
children = (
@@ -469,6 +483,7 @@
buildActionMask = 2147483647;
files = (
36FE83FFC24922EBC28287BB /* AppDelegate.swift in Sources */,
32A4A6A2CFB6C810A8C2CE0B /* AppMenuView.swift in Sources */,
9CF57AC05F30A51B6B5269DC /* AppTheme.swift in Sources */,
84E3EE64F74D00104BF8694B /* BackgroundTaskManager.swift in Sources */,
8657A3E4C5E377FE34840E9A /* BackupEngine.swift in Sources */,
@@ -505,6 +520,7 @@
13FCA7D0BB01BFC46A5B725B /* SavedConnections.swift in Sources */,
A6D143C05EE16594E0D1AA01 /* SceneDelegate.swift in Sources */,
C8E9BC6070E23992EED8D013 /* SettingsView.swift in Sources */,
BEBDBED4A7D1D786C47DB8EE /* SyncView.swift in Sources */,
B08D787E99C3B2E193A0D694 /* ToggleRow.swift in Sources */,
96CC879835A8CFE5FDD21B85 /* UGreenCompatibilityBadge.swift in Sources */,
10062AA91BC883AE597443BD /* URL+.swift in Sources */,