mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-25 01:31:04 +00:00
More TabView cleanup
Bump to iOS 18 only + remove custom sidebar
This commit is contained in:
parent
76a6462867
commit
e051437fcb
28 changed files with 174 additions and 568 deletions
|
@ -36,7 +36,7 @@
|
||||||
9F2A542A296AF557009B2D7C /* NotificationServiceSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5429296AF557009B2D7C /* NotificationServiceSupport.swift */; };
|
9F2A542A296AF557009B2D7C /* NotificationServiceSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5429296AF557009B2D7C /* NotificationServiceSupport.swift */; };
|
||||||
9F2A542C296B1177009B2D7C /* glass.caf in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542B296B1177009B2D7C /* glass.caf */; };
|
9F2A542C296B1177009B2D7C /* glass.caf in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542B296B1177009B2D7C /* glass.caf */; };
|
||||||
9F2A542E296B1CC0009B2D7C /* glass.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542D296B1CC0009B2D7C /* glass.wav */; };
|
9F2A542E296B1CC0009B2D7C /* glass.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542D296B1CC0009B2D7C /* glass.wav */; };
|
||||||
9F2B92F6295AE04800DE16D0 /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B92F5295AE04800DE16D0 /* Tabs.swift */; };
|
9F2B92F6295AE04800DE16D0 /* AppTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B92F5295AE04800DE16D0 /* AppTab.swift */; };
|
||||||
9F2B92FA295DA7D700DE16D0 /* AddAccountsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */; };
|
9F2B92FA295DA7D700DE16D0 /* AddAccountsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */; };
|
||||||
9F2B92FC295DA94500DE16D0 /* InstanceInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B92FB295DA94500DE16D0 /* InstanceInfoView.swift */; };
|
9F2B92FC295DA94500DE16D0 /* InstanceInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B92FB295DA94500DE16D0 /* InstanceInfoView.swift */; };
|
||||||
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4629506F6600B3281A /* NotificationTab.swift */; };
|
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4629506F6600B3281A /* NotificationTab.swift */; };
|
||||||
|
@ -102,14 +102,12 @@
|
||||||
9FAD85A0297456A100496AB1 /* Models in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD859F297456A100496AB1 /* Models */; };
|
9FAD85A0297456A100496AB1 /* Models in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD859F297456A100496AB1 /* Models */; };
|
||||||
9FAD85A2297456A400496AB1 /* Env in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85A1297456A400496AB1 /* Env */; };
|
9FAD85A2297456A400496AB1 /* Env in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85A1297456A400496AB1 /* Env */; };
|
||||||
9FAD85A4297456A800496AB1 /* DesignSystem in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85A3297456A800496AB1 /* DesignSystem */; };
|
9FAD85A4297456A800496AB1 /* DesignSystem in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85A3297456A800496AB1 /* DesignSystem */; };
|
||||||
9FAD85CF2975B68900496AB1 /* SideBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD85CE2975B68900496AB1 /* SideBarView.swift */; };
|
|
||||||
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAE4ACA293783B000772766 /* SettingsTab.swift */; };
|
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAE4ACA293783B000772766 /* SettingsTab.swift */; };
|
||||||
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAE4ACD29379A5A00772766 /* KeychainSwift */; };
|
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAE4ACD29379A5A00772766 /* KeychainSwift */; };
|
||||||
9FB143D12983104700A27BB1 /* glass.caf in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542B296B1177009B2D7C /* glass.caf */; };
|
9FB143D12983104700A27BB1 /* glass.caf in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542B296B1177009B2D7C /* glass.caf */; };
|
||||||
9FB143D22983104A00A27BB1 /* glass.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542D296B1CC0009B2D7C /* glass.wav */; };
|
9FB143D22983104A00A27BB1 /* glass.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542D296B1CC0009B2D7C /* glass.wav */; };
|
||||||
9FB183222AE9268800BBB692 /* IceCubesApp+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183212AE9268800BBB692 /* IceCubesApp+Menu.swift */; };
|
9FB183222AE9268800BBB692 /* IceCubesApp+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183212AE9268800BBB692 /* IceCubesApp+Menu.swift */; };
|
||||||
9FB183292AE9449100BBB692 /* IceCubesApp+Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183282AE9449100BBB692 /* IceCubesApp+Scene.swift */; };
|
9FB183292AE9449100BBB692 /* IceCubesApp+Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183282AE9449100BBB692 /* IceCubesApp+Scene.swift */; };
|
||||||
9FBA1D352B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBA1D342B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift */; };
|
|
||||||
9FBFE63D292A715500C250E9 /* IceCubesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBFE63C292A715500C250E9 /* IceCubesApp.swift */; };
|
9FBFE63D292A715500C250E9 /* IceCubesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBFE63C292A715500C250E9 /* IceCubesApp.swift */; };
|
||||||
9FBFE64E292A72BD00C250E9 /* Network in Frameworks */ = {isa = PBXBuildFile; productRef = 9FBFE64D292A72BD00C250E9 /* Network */; };
|
9FBFE64E292A72BD00C250E9 /* Network in Frameworks */ = {isa = PBXBuildFile; productRef = 9FBFE64D292A72BD00C250E9 /* Network */; };
|
||||||
9FC14EF22B494D180006CEE1 /* TagsGroupSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FC14EF12B494D180006CEE1 /* TagsGroupSettingView.swift */; };
|
9FC14EF22B494D180006CEE1 /* TagsGroupSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FC14EF12B494D180006CEE1 /* TagsGroupSettingView.swift */; };
|
||||||
|
@ -231,7 +229,7 @@
|
||||||
9F2A5429296AF557009B2D7C /* NotificationServiceSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationServiceSupport.swift; sourceTree = "<group>"; };
|
9F2A5429296AF557009B2D7C /* NotificationServiceSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationServiceSupport.swift; sourceTree = "<group>"; };
|
||||||
9F2A542B296B1177009B2D7C /* glass.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = glass.caf; sourceTree = "<group>"; };
|
9F2A542B296B1177009B2D7C /* glass.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = glass.caf; sourceTree = "<group>"; };
|
||||||
9F2A542D296B1CC0009B2D7C /* glass.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = glass.wav; sourceTree = "<group>"; };
|
9F2A542D296B1CC0009B2D7C /* glass.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = glass.wav; sourceTree = "<group>"; };
|
||||||
9F2B92F5295AE04800DE16D0 /* Tabs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = "<group>"; };
|
9F2B92F5295AE04800DE16D0 /* AppTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTab.swift; sourceTree = "<group>"; };
|
||||||
9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountsView.swift; sourceTree = "<group>"; };
|
9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountsView.swift; sourceTree = "<group>"; };
|
||||||
9F2B92FB295DA94500DE16D0 /* InstanceInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceInfoView.swift; sourceTree = "<group>"; };
|
9F2B92FB295DA94500DE16D0 /* InstanceInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceInfoView.swift; sourceTree = "<group>"; };
|
||||||
9F35DB45294FA04C00B3281A /* DesignSystem */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DesignSystem; path = Packages/DesignSystem; sourceTree = "<group>"; };
|
9F35DB45294FA04C00B3281A /* DesignSystem */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DesignSystem; path = Packages/DesignSystem; sourceTree = "<group>"; };
|
||||||
|
@ -286,12 +284,10 @@
|
||||||
9FAD858A29743F7400496AB1 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
9FAD858A29743F7400496AB1 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||||
9FAD858F29743F7400496AB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
9FAD858F29743F7400496AB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
9FAD859629743F7E00496AB1 /* IceCubesShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IceCubesShareExtension.entitlements; sourceTree = "<group>"; };
|
9FAD859629743F7E00496AB1 /* IceCubesShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IceCubesShareExtension.entitlements; sourceTree = "<group>"; };
|
||||||
9FAD85CE2975B68900496AB1 /* SideBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarView.swift; sourceTree = "<group>"; };
|
|
||||||
9FAE4AC8293774FF00772766 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
9FAE4AC8293774FF00772766 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
9FAE4ACA293783B000772766 /* SettingsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTab.swift; sourceTree = "<group>"; };
|
9FAE4ACA293783B000772766 /* SettingsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTab.swift; sourceTree = "<group>"; };
|
||||||
9FB183212AE9268800BBB692 /* IceCubesApp+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Menu.swift"; sourceTree = "<group>"; };
|
9FB183212AE9268800BBB692 /* IceCubesApp+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Menu.swift"; sourceTree = "<group>"; };
|
||||||
9FB183282AE9449100BBB692 /* IceCubesApp+Scene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Scene.swift"; sourceTree = "<group>"; };
|
9FB183282AE9449100BBB692 /* IceCubesApp+Scene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Scene.swift"; sourceTree = "<group>"; };
|
||||||
9FBA1D342B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarEntriesSettingsView.swift; sourceTree = "<group>"; };
|
|
||||||
9FBFE639292A715500C250E9 /* Ice Cubes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Ice Cubes.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
9FBFE639292A715500C250E9 /* Ice Cubes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Ice Cubes.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
9FBFE63C292A715500C250E9 /* IceCubesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IceCubesApp.swift; sourceTree = "<group>"; };
|
9FBFE63C292A715500C250E9 /* IceCubesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IceCubesApp.swift; sourceTree = "<group>"; };
|
||||||
9FC14EF12B494D180006CEE1 /* TagsGroupSettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsGroupSettingView.swift; sourceTree = "<group>"; };
|
9FC14EF12B494D180006CEE1 /* TagsGroupSettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsGroupSettingView.swift; sourceTree = "<group>"; };
|
||||||
|
@ -460,7 +456,6 @@
|
||||||
9FAE4AC9293783A200772766 /* Tabs */,
|
9FAE4AC9293783A200772766 /* Tabs */,
|
||||||
9F398AA52935FE8A00A889F2 /* AppRegistry.swift */,
|
9F398AA52935FE8A00A889F2 /* AppRegistry.swift */,
|
||||||
639CDF9B296AC82F00C35E58 /* SafariRouter.swift */,
|
639CDF9B296AC82F00C35E58 /* SafariRouter.swift */,
|
||||||
9FAD85CE2975B68900496AB1 /* SideBarView.swift */,
|
|
||||||
);
|
);
|
||||||
path = App;
|
path = App;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -565,7 +560,7 @@
|
||||||
9F35DB4629506F6600B3281A /* NotificationTab.swift */,
|
9F35DB4629506F6600B3281A /* NotificationTab.swift */,
|
||||||
9F35DB4B2952005C00B3281A /* MessagesTab.swift */,
|
9F35DB4B2952005C00B3281A /* MessagesTab.swift */,
|
||||||
9F55C68C2955968700F94077 /* ExploreTab.swift */,
|
9F55C68C2955968700F94077 /* ExploreTab.swift */,
|
||||||
9F2B92F5295AE04800DE16D0 /* Tabs.swift */,
|
9F2B92F5295AE04800DE16D0 /* AppTab.swift */,
|
||||||
9F4A48182976B21900A1A038 /* ProfileTab.swift */,
|
9F4A48182976B21900A1A038 /* ProfileTab.swift */,
|
||||||
9F15D5FF2B3D6A850008C220 /* NavigationTab.swift */,
|
9F15D5FF2B3D6A850008C220 /* NavigationTab.swift */,
|
||||||
9F15D6032B3DC2180008C220 /* NavigationSheet.swift */,
|
9F15D6032B3DC2180008C220 /* NavigationSheet.swift */,
|
||||||
|
@ -672,7 +667,6 @@
|
||||||
9FC14EF12B494D180006CEE1 /* TagsGroupSettingView.swift */,
|
9FC14EF12B494D180006CEE1 /* TagsGroupSettingView.swift */,
|
||||||
9FC14EF32B494D940006CEE1 /* RemoteTimelinesSettingView.swift */,
|
9FC14EF32B494D940006CEE1 /* RemoteTimelinesSettingView.swift */,
|
||||||
9FC14EF52B494DFF0006CEE1 /* RecenTagsSettingView.swift */,
|
9FC14EF52B494DFF0006CEE1 /* RecenTagsSettingView.swift */,
|
||||||
9FBA1D342B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift */,
|
|
||||||
);
|
);
|
||||||
path = Settings;
|
path = Settings;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1071,7 +1065,6 @@
|
||||||
9F37BDE12BE38646007F28AD /* PostImageIntent.swift in Sources */,
|
9F37BDE12BE38646007F28AD /* PostImageIntent.swift in Sources */,
|
||||||
9F37BDDF2BE37C35007F28AD /* TabIntent.swift in Sources */,
|
9F37BDDF2BE37C35007F28AD /* TabIntent.swift in Sources */,
|
||||||
9F7788C02BE63935004E6BEF /* InlinePostIntent.swift in Sources */,
|
9F7788C02BE63935004E6BEF /* InlinePostIntent.swift in Sources */,
|
||||||
9FAD85CF2975B68900496AB1 /* SideBarView.swift in Sources */,
|
|
||||||
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
||||||
9FC14EF42B494D940006CEE1 /* RemoteTimelinesSettingView.swift in Sources */,
|
9FC14EF42B494D940006CEE1 /* RemoteTimelinesSettingView.swift in Sources */,
|
||||||
9FC14EF22B494D180006CEE1 /* TagsGroupSettingView.swift in Sources */,
|
9FC14EF22B494D180006CEE1 /* TagsGroupSettingView.swift in Sources */,
|
||||||
|
@ -1079,7 +1072,7 @@
|
||||||
9F7335F92968576500AFF0BA /* DisplaySettingsView.swift in Sources */,
|
9F7335F92968576500AFF0BA /* DisplaySettingsView.swift in Sources */,
|
||||||
9F2A540729699698009B2D7C /* SupportAppView.swift in Sources */,
|
9F2A540729699698009B2D7C /* SupportAppView.swift in Sources */,
|
||||||
9FB183292AE9449100BBB692 /* IceCubesApp+Scene.swift in Sources */,
|
9FB183292AE9449100BBB692 /* IceCubesApp+Scene.swift in Sources */,
|
||||||
9F2B92F6295AE04800DE16D0 /* Tabs.swift in Sources */,
|
9F2B92F6295AE04800DE16D0 /* AppTab.swift in Sources */,
|
||||||
FA31A9AB2A66BF7C00D5F662 /* EditTagGroupView.swift in Sources */,
|
FA31A9AB2A66BF7C00D5F662 /* EditTagGroupView.swift in Sources */,
|
||||||
9F398AB329360A4C00A889F2 /* TimelineTab.swift in Sources */,
|
9F398AB329360A4C00A889F2 /* TimelineTab.swift in Sources */,
|
||||||
9F398AA62935FE8A00A889F2 /* AppRegistry.swift in Sources */,
|
9F398AA62935FE8A00A889F2 /* AppRegistry.swift in Sources */,
|
||||||
|
@ -1099,7 +1092,6 @@
|
||||||
9F6028562B3F36AE00476078 /* AppView.swift in Sources */,
|
9F6028562B3F36AE00476078 /* AppView.swift in Sources */,
|
||||||
9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */,
|
9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */,
|
||||||
9F1E8B47298EBCBB00609F80 /* HapticSettingsView.swift in Sources */,
|
9F1E8B47298EBCBB00609F80 /* HapticSettingsView.swift in Sources */,
|
||||||
9FBA1D352B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift in Sources */,
|
|
||||||
9F2A5411296A1429009B2D7C /* PushNotificationsView.swift in Sources */,
|
9F2A5411296A1429009B2D7C /* PushNotificationsView.swift in Sources */,
|
||||||
9F6028582B3F3B7600476078 /* ToolbarTab.swift in Sources */,
|
9F6028582B3F3B7600476078 /* ToolbarTab.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
@ -1187,7 +1179,7 @@
|
||||||
INFOPLIST_FILE = IceCubesNotifications/Info.plist;
|
INFOPLIST_FILE = IceCubesNotifications/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = IceCubesNotifications;
|
INFOPLIST_KEY_CFBundleDisplayName = IceCubesNotifications;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -1222,7 +1214,7 @@
|
||||||
INFOPLIST_FILE = IceCubesNotifications/Info.plist;
|
INFOPLIST_FILE = IceCubesNotifications/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = IceCubesNotifications;
|
INFOPLIST_KEY_CFBundleDisplayName = IceCubesNotifications;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -1261,7 +1253,7 @@
|
||||||
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -1297,7 +1289,7 @@
|
||||||
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -1330,7 +1322,7 @@
|
||||||
INFOPLIST_FILE = IceCubesShareExtension/Info.plist;
|
INFOPLIST_FILE = IceCubesShareExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -1364,7 +1356,7 @@
|
||||||
INFOPLIST_FILE = IceCubesShareExtension/Info.plist;
|
INFOPLIST_FILE = IceCubesShareExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -1548,7 +1540,7 @@
|
||||||
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
|
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
@ -1573,7 +1565,7 @@
|
||||||
SWIFT_UPCOMING_FEATURE_REGION_BASED_ISOLATION = YES;
|
SWIFT_UPCOMING_FEATURE_REGION_BASED_ISOLATION = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,7";
|
TARGETED_DEVICE_FAMILY = "1,2,7";
|
||||||
_EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = YES;
|
_EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = NO;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -1615,7 +1607,7 @@
|
||||||
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
|
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait";
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
@ -1640,7 +1632,7 @@
|
||||||
SWIFT_UPCOMING_FEATURE_REGION_BASED_ISOLATION = YES;
|
SWIFT_UPCOMING_FEATURE_REGION_BASED_ISOLATION = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,7";
|
TARGETED_DEVICE_FAMILY = "1,2,7";
|
||||||
_EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = YES;
|
_EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = NO;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -1659,7 +1651,7 @@
|
||||||
INFOPLIST_FILE = IceCubesActionExtension/Info.plist;
|
INFOPLIST_FILE = IceCubesActionExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Open in Ice Cube";
|
INFOPLIST_KEY_CFBundleDisplayName = "Open in Ice Cube";
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -1694,7 +1686,7 @@
|
||||||
INFOPLIST_FILE = IceCubesActionExtension/Info.plist;
|
INFOPLIST_FILE = IceCubesActionExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Open in Ice Cube";
|
INFOPLIST_KEY_CFBundleDisplayName = "Open in Ice Cube";
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|
|
@ -133,7 +133,7 @@ extension View {
|
||||||
StatusEditHistoryView(statusId: status)
|
StatusEditHistoryView(statusId: status)
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
case .settings:
|
case .settings:
|
||||||
SettingsTabs(popToRootTab: .constant(.settings), isModal: true)
|
SettingsTabs(isModal: true)
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
.preferredColorScheme(Theme.shared.selectedScheme == .dark ? .dark : .light)
|
.preferredColorScheme(Theme.shared.selectedScheme == .dark ? .dark : .light)
|
||||||
case .accountPushNotficationsSettings:
|
case .accountPushNotficationsSettings:
|
||||||
|
|
|
@ -21,12 +21,12 @@ struct AppView: View {
|
||||||
@Environment(\.openWindow) var openWindow
|
@Environment(\.openWindow) var openWindow
|
||||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||||
|
|
||||||
@Binding var selectedTab: Tab
|
@Binding var selectedTab: AppTab
|
||||||
@Binding var appRouterPath: RouterPath
|
@Binding var appRouterPath: RouterPath
|
||||||
|
|
||||||
@State var popToRootTab: Tab = .other
|
|
||||||
@State var iosTabs = iOSTabs.shared
|
@State var iosTabs = iOSTabs.shared
|
||||||
@State var sidebarTabs = SidebarTabs.shared
|
@AppStorage("SidebarTabsCustomization")
|
||||||
|
private var sidebarTabsCustomization: TabViewCustomization
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
#if os(visionOS)
|
#if os(visionOS)
|
||||||
|
@ -40,16 +40,16 @@ struct AppView: View {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
var availableTabs: [Tab] {
|
var availableTabs: [AppTab] {
|
||||||
guard appAccountsManager.currentClient.isAuth else {
|
guard appAccountsManager.currentClient.isAuth else {
|
||||||
return Tab.loggedOutTab()
|
return AppTab.loggedOutTab()
|
||||||
}
|
}
|
||||||
if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact {
|
if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact {
|
||||||
return iosTabs.tabs
|
return iosTabs.tabs
|
||||||
} else if UIDevice.current.userInterfaceIdiom == .vision {
|
} else if UIDevice.current.userInterfaceIdiom == .vision {
|
||||||
return Tab.visionOSTab()
|
return AppTab.visionOSTab()
|
||||||
}
|
}
|
||||||
return sidebarTabs.tabs.map { $0.tab }
|
return AppTab.sideBarTab()
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabBarView: some View {
|
var tabBarView: some View {
|
||||||
|
@ -64,39 +64,31 @@ struct AppView: View {
|
||||||
#endif
|
#endif
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if newTab == selectedTab {
|
|
||||||
/// Stupid hack to trigger onChange binding in tab views.
|
|
||||||
popToRootTab = .other
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
|
||||||
popToRootTab = selectedTab
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HapticManager.shared.fireHaptic(.tabSelection)
|
HapticManager.shared.fireHaptic(.tabSelection)
|
||||||
SoundEffectManager.shared.playSound(.tabSelection)
|
SoundEffectManager.shared.playSound(.tabSelection)
|
||||||
|
|
||||||
selectedTab = newTab
|
selectedTab = newTab
|
||||||
})) {
|
})) {
|
||||||
ForEach(availableTabs) { tab in
|
ForEach(availableTabs) { tab in
|
||||||
tab.makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab)
|
Tab(value: tab) {
|
||||||
.tabItem {
|
tab.makeContentView(selectedTab: $selectedTab)
|
||||||
if userPreferences.showiPhoneTabLabel {
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .tabBar)
|
||||||
tab.label
|
} label: {
|
||||||
.environment(\.symbolVariants, tab == selectedTab ? .fill : .none)
|
if userPreferences.showiPhoneTabLabel {
|
||||||
} else {
|
tab.label
|
||||||
Image(systemName: tab.iconName)
|
.environment(\.symbolVariants, tab == selectedTab ? .fill : .none)
|
||||||
}
|
} else {
|
||||||
|
Image(systemName: tab.iconName)
|
||||||
}
|
}
|
||||||
.tag(tab)
|
}
|
||||||
.badge(badgeFor(tab: tab))
|
.badge(badgeFor(tab: tab))
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .tabBar)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.id(appAccountsManager.currentClient.id)
|
.id(appAccountsManager.currentClient.id)
|
||||||
.withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func badgeFor(tab: Tab) -> Int {
|
private func badgeFor(tab: AppTab) -> Int {
|
||||||
if tab == .notifications, selectedTab != tab,
|
if tab == .notifications, selectedTab != tab,
|
||||||
let token = appAccountsManager.currentAccount.oauthToken
|
let token = appAccountsManager.currentAccount.oauthToken
|
||||||
{
|
{
|
||||||
|
@ -107,42 +99,38 @@ struct AppView: View {
|
||||||
|
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
var sidebarView: some View {
|
var sidebarView: some View {
|
||||||
SideBarView(selectedTab: $selectedTab,
|
HStack(spacing: 0) {
|
||||||
popToRootTab: $popToRootTab,
|
TabView(selection: $selectedTab) {
|
||||||
tabs: availableTabs)
|
ForEach(availableTabs) { tab in
|
||||||
{
|
Tab(value: tab, role: tab == .explore ? .search : nil) {
|
||||||
HStack(spacing: 0) {
|
|
||||||
TabView(selection: $selectedTab) {
|
|
||||||
ForEach(availableTabs) { tab in
|
|
||||||
tab
|
tab
|
||||||
.makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab)
|
.makeContentView(selectedTab: $selectedTab)
|
||||||
.tabItem {
|
} label: {
|
||||||
tab.label
|
tab.label
|
||||||
}
|
|
||||||
.tag(tab)
|
|
||||||
}
|
}
|
||||||
}
|
.customizationID(tab.iconName)
|
||||||
.introspect(.tabView, on: .iOS(.v17, .v18)) { (tabview: UITabBarController) in
|
.badge(badgeFor(tab: tab))
|
||||||
tabview.tabBar.isHidden = horizontalSizeClass == .regular
|
|
||||||
tabview.customizableViewControllers = []
|
|
||||||
tabview.moreNavigationController.isNavigationBarHidden = true
|
|
||||||
}
|
|
||||||
if horizontalSizeClass == .regular,
|
|
||||||
appAccountsManager.currentClient.isAuth,
|
|
||||||
userPreferences.showiPadSecondaryColumn
|
|
||||||
{
|
|
||||||
Divider().edgesIgnoringSafeArea(.all)
|
|
||||||
notificationsSecondaryColumn
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.tabViewStyle(.sidebarAdaptable)
|
||||||
|
.tabViewCustomization($sidebarTabsCustomization)
|
||||||
|
.introspect(.tabView, on: .iOS(.v17, .v18)) { (tabview: UITabBarController) in
|
||||||
|
tabview.customizableViewControllers = []
|
||||||
|
tabview.moreNavigationController.isNavigationBarHidden = true
|
||||||
|
}
|
||||||
|
if horizontalSizeClass == .regular,
|
||||||
|
appAccountsManager.currentClient.isAuth,
|
||||||
|
userPreferences.showiPadSecondaryColumn
|
||||||
|
{
|
||||||
|
Divider().edgesIgnoringSafeArea(.all)
|
||||||
|
notificationsSecondaryColumn
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.environment(appRouterPath)
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var notificationsSecondaryColumn: some View {
|
var notificationsSecondaryColumn: some View {
|
||||||
NotificationsTab(selectedTab: .constant(.notifications),
|
NotificationsTab(selectedTab: .constant(.notifications), lockedType: nil)
|
||||||
popToRootTab: $popToRootTab, lockedType: nil)
|
|
||||||
.environment(\.isSecondaryColumn, true)
|
.environment(\.isSecondaryColumn, true)
|
||||||
.frame(maxWidth: .secondaryColumnWidth)
|
.frame(maxWidth: .secondaryColumnWidth)
|
||||||
.id(appAccountsManager.currentAccount.id)
|
.id(appAccountsManager.currentAccount.id)
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct IceCubesApp: App {
|
||||||
@State var quickLook = QuickLook.shared
|
@State var quickLook = QuickLook.shared
|
||||||
@State var theme = Theme.shared
|
@State var theme = Theme.shared
|
||||||
|
|
||||||
@State var selectedTab: Tab = .timeline
|
@State var selectedTab: AppTab = .timeline
|
||||||
@State var appRouterPath = RouterPath()
|
@State var appRouterPath = RouterPath()
|
||||||
|
|
||||||
@State var isSupporter: Bool = false
|
@State var isSupporter: Bool = false
|
||||||
|
|
|
@ -1,245 +0,0 @@
|
||||||
import Account
|
|
||||||
import AppAccount
|
|
||||||
import DesignSystem
|
|
||||||
import Env
|
|
||||||
import Models
|
|
||||||
import SwiftUI
|
|
||||||
import SwiftUIIntrospect
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
struct SideBarView<Content: View>: View {
|
|
||||||
@Environment(\.openWindow) private var openWindow
|
|
||||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
|
||||||
|
|
||||||
@Environment(AppAccountsManager.self) private var appAccounts
|
|
||||||
@Environment(CurrentAccount.self) private var currentAccount
|
|
||||||
@Environment(Theme.self) private var theme
|
|
||||||
@Environment(StreamWatcher.self) private var watcher
|
|
||||||
@Environment(UserPreferences.self) private var userPreferences
|
|
||||||
@Environment(RouterPath.self) private var routerPath
|
|
||||||
|
|
||||||
@Binding var selectedTab: Tab
|
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
var tabs: [Tab]
|
|
||||||
@ViewBuilder var content: () -> Content
|
|
||||||
|
|
||||||
@State private var sidebarTabs = SidebarTabs.shared
|
|
||||||
|
|
||||||
private func badgeFor(tab: Tab) -> Int {
|
|
||||||
if tab == .notifications, selectedTab != tab,
|
|
||||||
let token = appAccounts.currentAccount.oauthToken
|
|
||||||
{
|
|
||||||
return watcher.unreadNotificationsCount + (userPreferences.notificationsCount[token] ?? 0)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
private func makeIconForTab(tab: Tab) -> some View {
|
|
||||||
HStack {
|
|
||||||
ZStack(alignment: .topTrailing) {
|
|
||||||
SideBarIcon(systemIconName: tab.iconName,
|
|
||||||
isSelected: tab == selectedTab)
|
|
||||||
let badge = badgeFor(tab: tab)
|
|
||||||
if badge > 0 {
|
|
||||||
makeBadgeView(count: badge)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if userPreferences.isSidebarExpanded {
|
|
||||||
Text(tab.title)
|
|
||||||
.font(.headline)
|
|
||||||
.foregroundColor(tab == selectedTab ? theme.tintColor : theme.labelColor)
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.frame(width: (userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth) - 24, height: 50)
|
|
||||||
.background(tab == selectedTab ? theme.secondaryBackgroundColor : .clear,
|
|
||||||
in: RoundedRectangle(cornerRadius: 8))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func makeBadgeView(count: Int) -> some View {
|
|
||||||
ZStack {
|
|
||||||
Circle()
|
|
||||||
.fill(.red)
|
|
||||||
Text(count > 99 ? "99+" : String(count))
|
|
||||||
.foregroundColor(.white)
|
|
||||||
.font(.caption2)
|
|
||||||
}
|
|
||||||
.frame(width: 24, height: 24)
|
|
||||||
.offset(x: 14, y: -14)
|
|
||||||
}
|
|
||||||
|
|
||||||
private var postButton: some View {
|
|
||||||
Button {
|
|
||||||
#if targetEnvironment(macCatalyst) || os(visionOS)
|
|
||||||
openWindow(value: WindowDestinationEditor.newStatusEditor(visibility: userPreferences.postVisibility))
|
|
||||||
#else
|
|
||||||
routerPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
|
|
||||||
#endif
|
|
||||||
} label: {
|
|
||||||
Image(systemName: "square.and.pencil")
|
|
||||||
.resizable()
|
|
||||||
.aspectRatio(contentMode: .fit)
|
|
||||||
.frame(width: 20, height: 30)
|
|
||||||
.offset(x: 2, y: -2)
|
|
||||||
}
|
|
||||||
.buttonStyle(.borderedProminent)
|
|
||||||
.help(Tab.post.title)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func makeAccountButton(account: AppAccount, showBadge: Bool) -> some View {
|
|
||||||
Button {
|
|
||||||
if account.id == appAccounts.currentAccount.id {
|
|
||||||
selectedTab = .profile
|
|
||||||
SoundEffectManager.shared.playSound(.tabSelection)
|
|
||||||
} else {
|
|
||||||
var transation = Transaction()
|
|
||||||
transation.disablesAnimations = true
|
|
||||||
withTransaction(transation) {
|
|
||||||
appAccounts.currentAccount = account
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} label: {
|
|
||||||
ZStack(alignment: .topTrailing) {
|
|
||||||
if userPreferences.isSidebarExpanded {
|
|
||||||
AppAccountView(viewModel: .init(appAccount: account,
|
|
||||||
isCompact: false,
|
|
||||||
isInSettings: false),
|
|
||||||
isParentPresented: .constant(false))
|
|
||||||
} else {
|
|
||||||
AppAccountView(viewModel: .init(appAccount: account,
|
|
||||||
isCompact: true,
|
|
||||||
isInSettings: false),
|
|
||||||
isParentPresented: .constant(false))
|
|
||||||
}
|
|
||||||
if !userPreferences.isSidebarExpanded,
|
|
||||||
showBadge,
|
|
||||||
let token = account.oauthToken,
|
|
||||||
let notificationsCount = userPreferences.notificationsCount[token],
|
|
||||||
notificationsCount > 0
|
|
||||||
{
|
|
||||||
makeBadgeView(count: notificationsCount)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.padding(.leading, userPreferences.isSidebarExpanded ? 16 : 0)
|
|
||||||
}
|
|
||||||
.help(accountButtonTitle(accountName: account.accountName))
|
|
||||||
.frame(width: userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth, height: 50)
|
|
||||||
.padding(.vertical, 8)
|
|
||||||
.background(selectedTab == .profile && account.id == appAccounts.currentAccount.id ?
|
|
||||||
theme.secondaryBackgroundColor : .clear)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func accountButtonTitle(accountName: String?) -> LocalizedStringKey {
|
|
||||||
if let accountName {
|
|
||||||
"tab.profile-account-\(accountName)"
|
|
||||||
} else {
|
|
||||||
Tab.profile.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var tabsView: some View {
|
|
||||||
ForEach(tabs) { tab in
|
|
||||||
if tab != .profile && sidebarTabs.isEnabled(tab) {
|
|
||||||
Button {
|
|
||||||
// ensure keyboard is always dismissed when selecting a tab
|
|
||||||
hideKeyboard()
|
|
||||||
|
|
||||||
if tab == selectedTab {
|
|
||||||
popToRootTab = .other
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
|
||||||
popToRootTab = tab
|
|
||||||
}
|
|
||||||
}
|
|
||||||
selectedTab = tab
|
|
||||||
SoundEffectManager.shared.playSound(.tabSelection)
|
|
||||||
if tab == .notifications {
|
|
||||||
if let token = appAccounts.currentAccount.oauthToken {
|
|
||||||
userPreferences.notificationsCount[token] = 0
|
|
||||||
}
|
|
||||||
watcher.unreadNotificationsCount = 0
|
|
||||||
}
|
|
||||||
} label: {
|
|
||||||
makeIconForTab(tab: tab)
|
|
||||||
}
|
|
||||||
.help(tab.title)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
@Bindable var routerPath = routerPath
|
|
||||||
HStack(spacing: 0) {
|
|
||||||
if horizontalSizeClass == .regular {
|
|
||||||
ScrollView {
|
|
||||||
VStack(alignment: .center) {
|
|
||||||
if appAccounts.availableAccounts.isEmpty {
|
|
||||||
tabsView
|
|
||||||
} else {
|
|
||||||
ForEach(appAccounts.availableAccounts) { account in
|
|
||||||
makeAccountButton(account: account,
|
|
||||||
showBadge: account.id != appAccounts.currentAccount.id)
|
|
||||||
if account.id == appAccounts.currentAccount.id {
|
|
||||||
tabsView
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.frame(width: userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth)
|
|
||||||
.scrollContentBackground(.hidden)
|
|
||||||
.background(.thinMaterial)
|
|
||||||
.safeAreaInset(edge: .bottom, content: {
|
|
||||||
HStack(spacing: 16) {
|
|
||||||
postButton
|
|
||||||
.padding(.vertical, 24)
|
|
||||||
.padding(.leading, userPreferences.isSidebarExpanded ? 18 : 0)
|
|
||||||
if userPreferences.isSidebarExpanded {
|
|
||||||
Text("menu.new-post")
|
|
||||||
.font(.subheadline)
|
|
||||||
.foregroundColor(theme.labelColor)
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.frame(width: userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth)
|
|
||||||
.background(.thinMaterial)
|
|
||||||
})
|
|
||||||
Divider().edgesIgnoringSafeArea(.all)
|
|
||||||
}
|
|
||||||
content()
|
|
||||||
}
|
|
||||||
.background(.thinMaterial)
|
|
||||||
.edgesIgnoringSafeArea(.bottom)
|
|
||||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct SideBarIcon: View {
|
|
||||||
@Environment(Theme.self) private var theme
|
|
||||||
|
|
||||||
let systemIconName: String
|
|
||||||
let isSelected: Bool
|
|
||||||
|
|
||||||
@State private var isHovered: Bool = false
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
Image(systemName: systemIconName)
|
|
||||||
.font(.title2)
|
|
||||||
.fontWeight(.medium)
|
|
||||||
.foregroundColor(isSelected ? theme.tintColor : theme.labelColor)
|
|
||||||
.symbolVariant(isSelected ? .fill : .none)
|
|
||||||
.scaleEffect(isHovered ? 0.8 : 1.0)
|
|
||||||
.onHover { isHovered in
|
|
||||||
withAnimation(.interpolatingSpring(stiffness: 300, damping: 15)) {
|
|
||||||
self.isHovered = isHovered
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.frame(width: 50, height: 40)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension View {
|
|
||||||
@MainActor func hideKeyboard() {
|
|
||||||
let resign = #selector(UIResponder.resignFirstResponder)
|
|
||||||
UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,8 +7,8 @@ import StatusKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
enum AppTab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
case timeline, notifications, mentions, explore, messages, settings, other
|
case timeline, notifications, mentions, explore, messages, settings
|
||||||
case trending, federated, local
|
case trending, federated, local
|
||||||
case profile
|
case profile
|
||||||
case bookmarks
|
case bookmarks
|
||||||
|
@ -22,37 +22,43 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
rawValue
|
rawValue
|
||||||
}
|
}
|
||||||
|
|
||||||
static func loggedOutTab() -> [Tab] {
|
static func loggedOutTab() -> [AppTab] {
|
||||||
[.timeline, .settings]
|
[.timeline, .settings]
|
||||||
}
|
}
|
||||||
|
|
||||||
static func visionOSTab() -> [Tab] {
|
static func visionOSTab() -> [AppTab] {
|
||||||
[.profile, .timeline, .notifications, .mentions, .explore, .post, .settings]
|
[.profile, .timeline, .notifications, .mentions, .explore, .post, .settings]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func sideBarTab() -> [AppTab] {
|
||||||
|
[.timeline, .trending, .federated, .local, .notifications,
|
||||||
|
.mentions, .mentions, .explore, .bookmarks, .favorites,
|
||||||
|
.followedTags, .links, .lists, .settings, .profile]
|
||||||
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
func makeContentView(selectedTab: Binding<Tab>, popToRootTab: Binding<Tab>) -> some View {
|
func makeContentView(selectedTab: Binding<AppTab>) -> some View {
|
||||||
switch self {
|
switch self {
|
||||||
case .timeline:
|
case .timeline:
|
||||||
TimelineTab(popToRootTab: popToRootTab)
|
TimelineTab()
|
||||||
case .trending:
|
case .trending:
|
||||||
TimelineTab(popToRootTab: popToRootTab, timeline: .trending)
|
TimelineTab(timeline: .trending)
|
||||||
case .local:
|
case .local:
|
||||||
TimelineTab(popToRootTab: popToRootTab, timeline: .local)
|
TimelineTab(timeline: .local)
|
||||||
case .federated:
|
case .federated:
|
||||||
TimelineTab(popToRootTab: popToRootTab, timeline: .federated)
|
TimelineTab(timeline: .federated)
|
||||||
case .notifications:
|
case .notifications:
|
||||||
NotificationsTab(selectedTab: selectedTab, popToRootTab: popToRootTab, lockedType: nil)
|
NotificationsTab(selectedTab: selectedTab, lockedType: nil)
|
||||||
case .mentions:
|
case .mentions:
|
||||||
NotificationsTab(selectedTab: selectedTab, popToRootTab: popToRootTab, lockedType: .mention)
|
NotificationsTab(selectedTab: selectedTab, lockedType: .mention)
|
||||||
case .explore:
|
case .explore:
|
||||||
ExploreTab(popToRootTab: popToRootTab)
|
ExploreTab()
|
||||||
case .messages:
|
case .messages:
|
||||||
MessagesTab(popToRootTab: popToRootTab)
|
MessagesTab()
|
||||||
case .settings:
|
case .settings:
|
||||||
SettingsTabs(popToRootTab: popToRootTab, isModal: false)
|
SettingsTabs(isModal: false)
|
||||||
case .profile:
|
case .profile:
|
||||||
ProfileTab(popToRootTab: popToRootTab)
|
ProfileTab()
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
NavigationTab {
|
NavigationTab {
|
||||||
AccountStatusesListView(mode: .bookmarks)
|
AccountStatusesListView(mode: .bookmarks)
|
||||||
|
@ -73,16 +79,12 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
NavigationTab { TrendingLinksListView(cards: []) }
|
NavigationTab { TrendingLinksListView(cards: []) }
|
||||||
case .post:
|
case .post:
|
||||||
VStack {}
|
VStack {}
|
||||||
case .other:
|
|
||||||
EmptyView()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
var label: some View {
|
var label: some View {
|
||||||
if self != .other {
|
Label(title, systemImage: iconName)
|
||||||
Label(title, systemImage: iconName)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var title: LocalizedStringKey {
|
var title: LocalizedStringKey {
|
||||||
|
@ -119,8 +121,6 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
"timeline.filter.lists"
|
"timeline.filter.lists"
|
||||||
case .links:
|
case .links:
|
||||||
"explore.section.trending.links"
|
"explore.section.trending.links"
|
||||||
case .other:
|
|
||||||
""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,59 +158,10 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
"list.bullet"
|
"list.bullet"
|
||||||
case .links:
|
case .links:
|
||||||
"newspaper"
|
"newspaper"
|
||||||
case .other:
|
|
||||||
""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
|
||||||
@Observable
|
|
||||||
class SidebarTabs {
|
|
||||||
struct SidedebarTab: Hashable, Codable {
|
|
||||||
let tab: Tab
|
|
||||||
var enabled: Bool
|
|
||||||
}
|
|
||||||
|
|
||||||
class Storage {
|
|
||||||
@AppStorage("sidebar_tabs") var tabs: [SidedebarTab] = [
|
|
||||||
.init(tab: .timeline, enabled: true),
|
|
||||||
.init(tab: .trending, enabled: true),
|
|
||||||
.init(tab: .federated, enabled: true),
|
|
||||||
.init(tab: .local, enabled: true),
|
|
||||||
.init(tab: .notifications, enabled: true),
|
|
||||||
.init(tab: .mentions, enabled: true),
|
|
||||||
.init(tab: .messages, enabled: true),
|
|
||||||
.init(tab: .explore, enabled: true),
|
|
||||||
.init(tab: .bookmarks, enabled: true),
|
|
||||||
.init(tab: .favorites, enabled: true),
|
|
||||||
.init(tab: .followedTags, enabled: true),
|
|
||||||
.init(tab: .lists, enabled: true),
|
|
||||||
.init(tab: .links, enabled: true),
|
|
||||||
|
|
||||||
.init(tab: .settings, enabled: true),
|
|
||||||
.init(tab: .profile, enabled: true),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
private let storage = Storage()
|
|
||||||
public static let shared = SidebarTabs()
|
|
||||||
|
|
||||||
var tabs: [SidedebarTab] {
|
|
||||||
didSet {
|
|
||||||
storage.tabs = tabs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func isEnabled(_ tab: Tab) -> Bool {
|
|
||||||
tabs.first(where: { $0.tab.id == tab.id })?.enabled == true
|
|
||||||
}
|
|
||||||
|
|
||||||
private init() {
|
|
||||||
tabs = storage.tabs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
@Observable
|
@Observable
|
||||||
class iOSTabs {
|
class iOSTabs {
|
||||||
|
@ -219,45 +170,45 @@ class iOSTabs {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Storage {
|
class Storage {
|
||||||
@AppStorage(TabEntries.first.rawValue) var firstTab = Tab.timeline
|
@AppStorage(TabEntries.first.rawValue) var firstTab = AppTab.timeline
|
||||||
@AppStorage(TabEntries.second.rawValue) var secondTab = Tab.notifications
|
@AppStorage(TabEntries.second.rawValue) var secondTab = AppTab.notifications
|
||||||
@AppStorage(TabEntries.third.rawValue) var thirdTab = Tab.explore
|
@AppStorage(TabEntries.third.rawValue) var thirdTab = AppTab.explore
|
||||||
@AppStorage(TabEntries.fourth.rawValue) var fourthTab = Tab.links
|
@AppStorage(TabEntries.fourth.rawValue) var fourthTab = AppTab.links
|
||||||
@AppStorage(TabEntries.fifth.rawValue) var fifthTab = Tab.profile
|
@AppStorage(TabEntries.fifth.rawValue) var fifthTab = AppTab.profile
|
||||||
}
|
}
|
||||||
|
|
||||||
private let storage = Storage()
|
private let storage = Storage()
|
||||||
public static let shared = iOSTabs()
|
public static let shared = iOSTabs()
|
||||||
|
|
||||||
var tabs: [Tab] {
|
var tabs: [AppTab] {
|
||||||
[firstTab, secondTab, thirdTab, fourthTab, fifthTab]
|
[firstTab, secondTab, thirdTab, fourthTab, fifthTab]
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstTab: Tab {
|
var firstTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.firstTab = firstTab
|
storage.firstTab = firstTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var secondTab: Tab {
|
var secondTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.secondTab = secondTab
|
storage.secondTab = secondTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var thirdTab: Tab {
|
var thirdTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.thirdTab = thirdTab
|
storage.thirdTab = thirdTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fourthTab: Tab {
|
var fourthTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.fourthTab = fourthTab
|
storage.fourthTab = fourthTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fifthTab: Tab {
|
var fifthTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.fifthTab = fifthTab
|
storage.fifthTab = fifthTab
|
||||||
}
|
}
|
|
@ -14,7 +14,6 @@ struct ExploreTab: View {
|
||||||
@Environment(Client.self) private var client
|
@Environment(Client.self) private var client
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@State private var scrollToTopSignal: Int = 0
|
@State private var scrollToTopSignal: Int = 0
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routerPath.path) {
|
NavigationStack(path: $routerPath.path) {
|
||||||
|
@ -28,15 +27,6 @@ struct ExploreTab: View {
|
||||||
}
|
}
|
||||||
.withSafariRouter()
|
.withSafariRouter()
|
||||||
.environment(routerPath)
|
.environment(routerPath)
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .explore {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: client.id) {
|
.onChange(of: client.id) {
|
||||||
routerPath.path = []
|
routerPath.path = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ struct MessagesTab: View {
|
||||||
@Environment(AppAccountsManager.self) private var appAccount
|
@Environment(AppAccountsManager.self) private var appAccount
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@State private var scrollToTopSignal: Int = 0
|
@State private var scrollToTopSignal: Int = 0
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routerPath.path) {
|
NavigationStack(path: $routerPath.path) {
|
||||||
|
@ -29,15 +28,6 @@ struct MessagesTab: View {
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||||
.id(client.id)
|
.id(client.id)
|
||||||
}
|
}
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .messages {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: client.id) {
|
.onChange(of: client.id) {
|
||||||
routerPath.path = []
|
routerPath.path = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,7 @@ struct NotificationsTab: View {
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@State private var scrollToTopSignal: Int = 0
|
@State private var scrollToTopSignal: Int = 0
|
||||||
|
|
||||||
@Binding var selectedTab: Tab
|
@Binding var selectedTab: AppTab
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
let lockedType: Models.Notification.NotificationType?
|
let lockedType: Models.Notification.NotificationType?
|
||||||
|
|
||||||
|
@ -51,15 +50,6 @@ struct NotificationsTab: View {
|
||||||
}
|
}
|
||||||
.withSafariRouter()
|
.withSafariRouter()
|
||||||
.environment(routerPath)
|
.environment(routerPath)
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .notifications {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: selectedTab) { _, _ in
|
.onChange(of: selectedTab) { _, _ in
|
||||||
clearNotifications()
|
clearNotifications()
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ struct ProfileTab: View {
|
||||||
@Environment(CurrentAccount.self) private var currentAccount
|
@Environment(CurrentAccount.self) private var currentAccount
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@State private var scrollToTopSignal: Int = 0
|
@State private var scrollToTopSignal: Int = 0
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routerPath.path) {
|
NavigationStack(path: $routerPath.path) {
|
||||||
|
@ -31,15 +30,6 @@ struct ProfileTab: View {
|
||||||
.allowsHitTesting(false)
|
.allowsHitTesting(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .profile {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: client.id) {
|
.onChange(of: client.id) {
|
||||||
routerPath.path = []
|
routerPath.path = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@ struct SettingsTabs: View {
|
||||||
@State private var cachedRemoved = false
|
@State private var cachedRemoved = false
|
||||||
@State private var timelineCache = TimelineCache()
|
@State private var timelineCache = TimelineCache()
|
||||||
|
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
let isModal: Bool
|
let isModal: Bool
|
||||||
|
|
||||||
@State private var startingPoint: SettingsStartingPoint? = nil
|
@State private var startingPoint: SettingsStartingPoint? = nil
|
||||||
|
@ -103,11 +101,6 @@ struct SettingsTabs: View {
|
||||||
}
|
}
|
||||||
.withSafariRouter()
|
.withSafariRouter()
|
||||||
.environment(routerPath)
|
.environment(routerPath)
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .notifications {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var accountsSection: some View {
|
private var accountsSection: some View {
|
||||||
|
@ -192,10 +185,6 @@ struct SettingsTabs: View {
|
||||||
NavigationLink(destination: TabbarEntriesSettingsView()) {
|
NavigationLink(destination: TabbarEntriesSettingsView()) {
|
||||||
Label("settings.general.tabbarEntries", systemImage: "platter.filled.bottom.iphone")
|
Label("settings.general.tabbarEntries", systemImage: "platter.filled.bottom.iphone")
|
||||||
}
|
}
|
||||||
} else if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
|
||||||
NavigationLink(destination: SidebarEntriesSettingsView()) {
|
|
||||||
Label("settings.general.sidebarEntries", systemImage: "sidebar.squares.leading")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
NavigationLink(destination: TranslationSettingsView()) {
|
NavigationLink(destination: TranslationSettingsView()) {
|
||||||
Label("settings.general.translate", systemImage: "captions.bubble")
|
Label("settings.general.translate", systemImage: "captions.bubble")
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
import DesignSystem
|
|
||||||
import Env
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
struct SidebarEntriesSettingsView: View {
|
|
||||||
@Environment(Theme.self) private var theme
|
|
||||||
@Environment(UserPreferences.self) private var userPreferences
|
|
||||||
|
|
||||||
@State private var sidebarTabs = SidebarTabs.shared
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
@Bindable var userPreferences = userPreferences
|
|
||||||
Form {
|
|
||||||
Section {
|
|
||||||
ForEach($sidebarTabs.tabs, id: \.tab) { $tab in
|
|
||||||
if tab.tab != .profile && tab.tab != .settings {
|
|
||||||
Toggle(isOn: $tab.enabled) {
|
|
||||||
tab.tab.label
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onMove(perform: move)
|
|
||||||
}
|
|
||||||
#if !os(visionOS)
|
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
.environment(\.editMode, .constant(.active))
|
|
||||||
.navigationTitle("settings.general.sidebarEntries")
|
|
||||||
#if !os(visionOS)
|
|
||||||
.scrollContentBackground(.hidden)
|
|
||||||
.background(theme.secondaryBackgroundColor)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
func move(from source: IndexSet, to destination: Int) {
|
|
||||||
sidebarTabs.tabs.move(fromOffsets: source, toOffset: destination)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,27 +14,27 @@ struct TabbarEntriesSettingsView: View {
|
||||||
Form {
|
Form {
|
||||||
Section {
|
Section {
|
||||||
Picker("settings.tabs.first-tab", selection: $tabs.firstTab) {
|
Picker("settings.tabs.first-tab", selection: $tabs.firstTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
tab.label.tag(tab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picker("settings.tabs.second-tab", selection: $tabs.secondTab) {
|
Picker("settings.tabs.second-tab", selection: $tabs.secondTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
tab.label.tag(tab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picker("settings.tabs.third-tab", selection: $tabs.thirdTab) {
|
Picker("settings.tabs.third-tab", selection: $tabs.thirdTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
tab.label.tag(tab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picker("settings.tabs.fourth-tab", selection: $tabs.fourthTab) {
|
Picker("settings.tabs.fourth-tab", selection: $tabs.fourthTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
tab.label.tag(tab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picker("settings.tabs.fifth-tab", selection: $tabs.fifthTab) {
|
Picker("settings.tabs.fifth-tab", selection: $tabs.fifthTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
tab.label.tag(tab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ struct TimelineTab: View {
|
||||||
@Environment(UserPreferences.self) private var preferences
|
@Environment(UserPreferences.self) private var preferences
|
||||||
@Environment(Client.self) private var client
|
@Environment(Client.self) private var client
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
@State private var didAppear: Bool = false
|
@State private var didAppear: Bool = false
|
||||||
@State private var timeline: TimelineFilter = .home
|
@State private var timeline: TimelineFilter = .home
|
||||||
|
@ -33,9 +32,8 @@ struct TimelineTab: View {
|
||||||
|
|
||||||
private let canFilterTimeline: Bool
|
private let canFilterTimeline: Bool
|
||||||
|
|
||||||
init(popToRootTab: Binding<Tab>, timeline: TimelineFilter? = nil) {
|
init(timeline: TimelineFilter? = nil) {
|
||||||
canFilterTimeline = timeline == nil
|
canFilterTimeline = timeline == nil
|
||||||
_popToRootTab = popToRootTab
|
|
||||||
_timeline = .init(initialValue: timeline ?? .home)
|
_timeline = .init(initialValue: timeline ?? .home)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,15 +75,6 @@ struct TimelineTab: View {
|
||||||
.onChange(of: currentAccount.account?.id) {
|
.onChange(of: currentAccount.account?.id) {
|
||||||
resetTimelineFilter()
|
resetTimelineFilter()
|
||||||
}
|
}
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .timeline {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: client.id) {
|
.onChange(of: client.id) {
|
||||||
routerPath.path = []
|
routerPath.path = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,29 +15,10 @@ struct ToolbarTab: ToolbarContent {
|
||||||
|
|
||||||
var body: some ToolbarContent {
|
var body: some ToolbarContent {
|
||||||
if !isSecondaryColumn {
|
if !isSecondaryColumn {
|
||||||
ToolbarItem(placement: .topBarLeading) {
|
|
||||||
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
|
||||||
Button {
|
|
||||||
withAnimation {
|
|
||||||
userPreferences.isSidebarExpanded.toggle()
|
|
||||||
}
|
|
||||||
} label: {
|
|
||||||
if userPreferences.isSidebarExpanded {
|
|
||||||
Image(systemName: "sidebar.squares.left")
|
|
||||||
} else {
|
|
||||||
Image(systemName: "sidebar.left")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
statusEditorToolbarItem(routerPath: routerPath,
|
statusEditorToolbarItem(routerPath: routerPath,
|
||||||
visibility: userPreferences.postVisibility)
|
visibility: userPreferences.postVisibility)
|
||||||
if UIDevice.current.userInterfaceIdiom != .pad ||
|
ToolbarItem(placement: .navigationBarLeading) {
|
||||||
(UIDevice.current.userInterfaceIdiom == .pad && horizontalSizeClass == .compact)
|
AppAccountsSelectorView(routerPath: routerPath, avatarConfig: theme.avatarShape == .circle ? .badge : .badgeRounded)
|
||||||
{
|
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
|
||||||
AppAccountsSelectorView(routerPath: routerPath, avatarConfig: theme.avatarShape == .circle ? .badge : .badgeRounded)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if UIDevice.current.userInterfaceIdiom == .pad && horizontalSizeClass == .regular {
|
if UIDevice.current.userInterfaceIdiom == .pad && horizontalSizeClass == .regular {
|
||||||
|
|
|
@ -77330,6 +77330,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tab.profile-account-%@" : {
|
"tab.profile-account-%@" : {
|
||||||
|
"extractionState" : "stale",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"be" : {
|
"be" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
|
@ -82976,4 +82977,4 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version" : "1.0"
|
"version" : "1.0"
|
||||||
}
|
}
|
|
@ -35,7 +35,7 @@ enum TabEnum: String, AppEnum, Sendable {
|
||||||
.post: .init(title: "New post")]
|
.post: .init(title: "New post")]
|
||||||
}
|
}
|
||||||
|
|
||||||
var toAppTab: Tab {
|
var toAppTab: AppTab {
|
||||||
switch self {
|
switch self {
|
||||||
case .timeline:
|
case .timeline:
|
||||||
.timeline
|
.timeline
|
||||||
|
|
|
@ -23,8 +23,11 @@ struct AccountWidgetProvider: AppIntentTimelineProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func fetchAccount(configuration: AccountWidgetConfiguration) async -> Account {
|
private func fetchAccount(configuration: AccountWidgetConfiguration) async -> Account {
|
||||||
let client = Client(server: configuration.account.account.server,
|
guard let account = configuration.account else {
|
||||||
oauthToken: configuration.account.account.oauthToken)
|
return .placeholder()
|
||||||
|
}
|
||||||
|
let client = Client(server: account.account.server,
|
||||||
|
oauthToken: account.account.oauthToken)
|
||||||
do {
|
do {
|
||||||
let account: Account = try await client.get(endpoint: Accounts.verifyCredentials)
|
let account: Account = try await client.get(endpoint: Accounts.verifyCredentials)
|
||||||
return account
|
return account
|
||||||
|
|
|
@ -6,7 +6,7 @@ struct AccountWidgetConfiguration: WidgetConfigurationIntent {
|
||||||
static let description = IntentDescription("Choose the account for this widget")
|
static let description = IntentDescription("Choose the account for this widget")
|
||||||
|
|
||||||
@Parameter(title: "Account")
|
@Parameter(title: "Account")
|
||||||
var account: AppAccountEntity
|
var account: AppAccountEntity?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AccountWidgetConfiguration {
|
extension AccountWidgetConfiguration {
|
||||||
|
|
|
@ -29,9 +29,16 @@ struct HashtagPostsWidgetProvider: AppIntentTimelineProvider {
|
||||||
|
|
||||||
private func timeline(for configuration: HashtagPostsWidgetConfiguration, context: Context) async -> Timeline<PostsWidgetEntry> {
|
private func timeline(for configuration: HashtagPostsWidgetConfiguration, context: Context) async -> Timeline<PostsWidgetEntry> {
|
||||||
do {
|
do {
|
||||||
let timeline: TimelineFilter = .hashtag(tag: configuration.hashgtag, accountId: nil)
|
guard let account = configuration.account, let hashgtag = configuration.hashgtag else {
|
||||||
|
return Timeline(entries: [.init(date: Date(),
|
||||||
|
title: "#Mastodon",
|
||||||
|
statuses: [],
|
||||||
|
images: [:])],
|
||||||
|
policy: .atEnd)
|
||||||
|
}
|
||||||
|
let timeline: TimelineFilter = .hashtag(tag: hashgtag, accountId: nil)
|
||||||
let statuses = await loadStatuses(for: timeline,
|
let statuses = await loadStatuses(for: timeline,
|
||||||
account: configuration.account,
|
account: account,
|
||||||
widgetFamily: context.family)
|
widgetFamily: context.family)
|
||||||
let images = try await loadImages(urls: statuses.map { $0.account.avatar })
|
let images = try await loadImages(urls: statuses.map { $0.account.avatar })
|
||||||
return Timeline(entries: [.init(date: Date(),
|
return Timeline(entries: [.init(date: Date(),
|
||||||
|
|
|
@ -6,10 +6,10 @@ struct HashtagPostsWidgetConfiguration: WidgetConfigurationIntent {
|
||||||
static let description = IntentDescription("Choose the account and hashtag for this widget")
|
static let description = IntentDescription("Choose the account and hashtag for this widget")
|
||||||
|
|
||||||
@Parameter(title: "Account")
|
@Parameter(title: "Account")
|
||||||
var account: AppAccountEntity
|
var account: AppAccountEntity?
|
||||||
|
|
||||||
@Parameter(title: "Hashtag")
|
@Parameter(title: "Hashtag")
|
||||||
var hashgtag: String
|
var hashgtag: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension HashtagPostsWidgetConfiguration {
|
extension HashtagPostsWidgetConfiguration {
|
||||||
|
|
|
@ -18,7 +18,7 @@ struct LatestPostsWidgetProvider: AppIntentTimelineProvider {
|
||||||
return entry
|
return entry
|
||||||
}
|
}
|
||||||
return .init(date: Date(),
|
return .init(date: Date(),
|
||||||
title: configuration.timeline.timeline.title,
|
title: configuration.timeline?.timeline.title ?? "",
|
||||||
statuses: [],
|
statuses: [],
|
||||||
images: [:])
|
images: [:])
|
||||||
}
|
}
|
||||||
|
@ -29,17 +29,24 @@ struct LatestPostsWidgetProvider: AppIntentTimelineProvider {
|
||||||
|
|
||||||
private func timeline(for configuration: LatestPostsWidgetConfiguration, context: Context) async -> Timeline<PostsWidgetEntry> {
|
private func timeline(for configuration: LatestPostsWidgetConfiguration, context: Context) async -> Timeline<PostsWidgetEntry> {
|
||||||
do {
|
do {
|
||||||
let statuses = await loadStatuses(for: configuration.timeline.timeline,
|
guard let timeline = configuration.timeline, let account = configuration.account else {
|
||||||
account: configuration.account,
|
return Timeline(entries: [.init(date: Date(),
|
||||||
|
title: "",
|
||||||
|
statuses: [],
|
||||||
|
images: [:])],
|
||||||
|
policy: .atEnd)
|
||||||
|
}
|
||||||
|
let statuses = await loadStatuses(for: timeline.timeline,
|
||||||
|
account: account,
|
||||||
widgetFamily: context.family)
|
widgetFamily: context.family)
|
||||||
let images = try await loadImages(urls: statuses.map { $0.account.avatar })
|
let images = try await loadImages(urls: statuses.map { $0.account.avatar })
|
||||||
return Timeline(entries: [.init(date: Date(),
|
return Timeline(entries: [.init(date: Date(),
|
||||||
title: configuration.timeline.timeline.title,
|
title: timeline.timeline.title,
|
||||||
statuses: statuses,
|
statuses: statuses,
|
||||||
images: images)], policy: .atEnd)
|
images: images)], policy: .atEnd)
|
||||||
} catch {
|
} catch {
|
||||||
return Timeline(entries: [.init(date: Date(),
|
return Timeline(entries: [.init(date: Date(),
|
||||||
title: configuration.timeline.timeline.title,
|
title: configuration.timeline?.timeline.title ?? "",
|
||||||
statuses: [],
|
statuses: [],
|
||||||
images: [:])],
|
images: [:])],
|
||||||
policy: .atEnd)
|
policy: .atEnd)
|
||||||
|
|
|
@ -6,10 +6,10 @@ struct LatestPostsWidgetConfiguration: WidgetConfigurationIntent {
|
||||||
static let description = IntentDescription("Choose the account and timeline for this widget")
|
static let description = IntentDescription("Choose the account and timeline for this widget")
|
||||||
|
|
||||||
@Parameter(title: "Account")
|
@Parameter(title: "Account")
|
||||||
var account: AppAccountEntity
|
var account: AppAccountEntity?
|
||||||
|
|
||||||
@Parameter(title: "Timeline")
|
@Parameter(title: "Timeline")
|
||||||
var timeline: TimelineFilterEntity
|
var timeline: TimelineFilterEntity?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension LatestPostsWidgetConfiguration {
|
extension LatestPostsWidgetConfiguration {
|
||||||
|
|
|
@ -29,13 +29,20 @@ struct ListsWidgetProvider: AppIntentTimelineProvider {
|
||||||
|
|
||||||
private func timeline(for configuration: ListsWidgetConfiguration, context: Context) async -> Timeline<PostsWidgetEntry> {
|
private func timeline(for configuration: ListsWidgetConfiguration, context: Context) async -> Timeline<PostsWidgetEntry> {
|
||||||
do {
|
do {
|
||||||
let timeline: TimelineFilter = .list(list: configuration.timeline.list)
|
guard let account = configuration.account, let timeline = configuration.timeline else {
|
||||||
let statuses = await loadStatuses(for: timeline,
|
return Timeline(entries: [.init(date: Date(),
|
||||||
account: configuration.account,
|
title: "List name",
|
||||||
|
statuses: [],
|
||||||
|
images: [:])],
|
||||||
|
policy: .atEnd)
|
||||||
|
}
|
||||||
|
let filter: TimelineFilter = .list(list: timeline.list)
|
||||||
|
let statuses = await loadStatuses(for: filter,
|
||||||
|
account: account,
|
||||||
widgetFamily: context.family)
|
widgetFamily: context.family)
|
||||||
let images = try await loadImages(urls: statuses.map { $0.account.avatar })
|
let images = try await loadImages(urls: statuses.map { $0.account.avatar })
|
||||||
return Timeline(entries: [.init(date: Date(),
|
return Timeline(entries: [.init(date: Date(),
|
||||||
title: timeline.title,
|
title: filter.title,
|
||||||
statuses: statuses,
|
statuses: statuses,
|
||||||
images: images)], policy: .atEnd)
|
images: images)], policy: .atEnd)
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
@ -6,10 +6,10 @@ struct ListsWidgetConfiguration: WidgetConfigurationIntent {
|
||||||
static let description = IntentDescription("Choose the account and list for this widget")
|
static let description = IntentDescription("Choose the account and list for this widget")
|
||||||
|
|
||||||
@Parameter(title: "Account")
|
@Parameter(title: "Account")
|
||||||
var account: AppAccountEntity
|
var account: AppAccountEntity?
|
||||||
|
|
||||||
@Parameter(title: "List")
|
@Parameter(title: "List")
|
||||||
var timeline: ListEntity
|
var timeline: ListEntity?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ListsWidgetConfiguration {
|
extension ListsWidgetConfiguration {
|
||||||
|
|
|
@ -29,8 +29,15 @@ struct MentionsWidgetProvider: AppIntentTimelineProvider {
|
||||||
|
|
||||||
private func timeline(for configuration: MentionsWidgetConfiguration, context _: Context) async -> Timeline<PostsWidgetEntry> {
|
private func timeline(for configuration: MentionsWidgetConfiguration, context _: Context) async -> Timeline<PostsWidgetEntry> {
|
||||||
do {
|
do {
|
||||||
let client = Client(server: configuration.account.account.server,
|
guard let account = configuration.account else {
|
||||||
oauthToken: configuration.account.account.oauthToken)
|
return Timeline(entries: [.init(date: Date(),
|
||||||
|
title: "Mentions",
|
||||||
|
statuses: [],
|
||||||
|
images: [:])],
|
||||||
|
policy: .atEnd)
|
||||||
|
}
|
||||||
|
let client = Client(server: account.account.server,
|
||||||
|
oauthToken: account.account.oauthToken)
|
||||||
var excludedTypes = Models.Notification.NotificationType.allCases
|
var excludedTypes = Models.Notification.NotificationType.allCases
|
||||||
excludedTypes.removeAll(where: { $0 == .mention })
|
excludedTypes.removeAll(where: { $0 == .mention })
|
||||||
let notifications: [Models.Notification] =
|
let notifications: [Models.Notification] =
|
||||||
|
|
|
@ -6,7 +6,7 @@ struct MentionsWidgetConfiguration: WidgetConfigurationIntent {
|
||||||
static let description = IntentDescription("Choose the account for this widget")
|
static let description = IntentDescription("Choose the account for this widget")
|
||||||
|
|
||||||
@Parameter(title: "Account")
|
@Parameter(title: "Account")
|
||||||
var account: AppAccountEntity
|
var account: AppAccountEntity?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MentionsWidgetConfiguration {
|
extension MentionsWidgetConfiguration {
|
||||||
|
|
|
@ -49,12 +49,21 @@ public struct AppAccountsSelectorView: View {
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $isPresented, content: {
|
.sheet(isPresented: $isPresented, content: {
|
||||||
accountsView.presentationDetents([.height(preferredHeight), .large])
|
if UIDevice.current.userInterfaceIdiom == .mac || UIDevice.current.userInterfaceIdiom == .pad {
|
||||||
.presentationBackground(.ultraThinMaterial)
|
accountsView
|
||||||
.presentationCornerRadius(16)
|
.presentationBackground(.ultraThinMaterial)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
refreshAccounts()
|
refreshAccounts()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
accountsView
|
||||||
|
.presentationDetents([.height(preferredHeight), .large])
|
||||||
|
.presentationBackground(.ultraThinMaterial)
|
||||||
|
.presentationCornerRadius(16)
|
||||||
|
.onAppear {
|
||||||
|
refreshAccounts()
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.onChange(of: currentAccount.account?.id) {
|
.onChange(of: currentAccount.account?.id) {
|
||||||
refreshAccounts()
|
refreshAccounts()
|
||||||
|
|
Loading…
Reference in a new issue