mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-06-17 20:50:33 +00:00
Followed Tags + Lists tab. + sidebar customization
This commit is contained in:
parent
6246d7b0a5
commit
0da8228e61
|
@ -83,6 +83,7 @@
|
||||||
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 */; };
|
||||||
|
@ -227,6 +228,7 @@
|
||||||
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>"; };
|
||||||
|
@ -531,6 +533,7 @@
|
||||||
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>";
|
||||||
|
@ -852,6 +855,7 @@
|
||||||
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 */,
|
||||||
);
|
);
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct AppView: View {
|
||||||
|
|
||||||
@State var popToRootTab: Tab = .other
|
@State var popToRootTab: Tab = .other
|
||||||
@State var iosTabs = iOSTabs.shared
|
@State var iosTabs = iOSTabs.shared
|
||||||
|
@State var sidebarTabs = SidebarTabs.shared
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
#if os(visionOS)
|
#if os(visionOS)
|
||||||
|
@ -40,10 +41,15 @@ struct AppView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
var availableTabs: [Tab] {
|
var availableTabs: [Tab] {
|
||||||
if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact {
|
guard appAccountsManager.currentClient.isAuth else {
|
||||||
return appAccountsManager.currentClient.isAuth ? iosTabs.tabs : Tab.loggedOutTab()
|
return Tab.loggedOutTab()
|
||||||
}
|
}
|
||||||
return appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()
|
if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact {
|
||||||
|
return iosTabs.tabs
|
||||||
|
} else if UIDevice.current.userInterfaceIdiom == .vision {
|
||||||
|
return Tab.visionOSTab()
|
||||||
|
}
|
||||||
|
return sidebarTabs.tabs.map{ $0.tab }
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabBarView: some View {
|
var tabBarView: some View {
|
||||||
|
|
|
@ -17,11 +17,13 @@ struct SideBarView<Content: View>: View {
|
||||||
@Environment(StreamWatcher.self) private var watcher
|
@Environment(StreamWatcher.self) private var watcher
|
||||||
@Environment(UserPreferences.self) private var userPreferences
|
@Environment(UserPreferences.self) private var userPreferences
|
||||||
@Environment(RouterPath.self) private var routerPath
|
@Environment(RouterPath.self) private var routerPath
|
||||||
|
|
||||||
@Binding var selectedTab: Tab
|
@Binding var selectedTab: Tab
|
||||||
@Binding var popToRootTab: Tab
|
@Binding var popToRootTab: Tab
|
||||||
var tabs: [Tab]
|
var tabs: [Tab]
|
||||||
@ViewBuilder var content: () -> Content
|
@ViewBuilder var content: () -> Content
|
||||||
|
|
||||||
|
@State private var sidebarTabs = SidebarTabs.shared
|
||||||
|
|
||||||
private func badgeFor(tab: Tab) -> Int {
|
private func badgeFor(tab: Tab) -> Int {
|
||||||
if tab == .notifications, selectedTab != tab,
|
if tab == .notifications, selectedTab != tab,
|
||||||
|
@ -107,7 +109,7 @@ struct SideBarView<Content: View>: View {
|
||||||
|
|
||||||
private var tabsView: some View {
|
private var tabsView: some View {
|
||||||
ForEach(tabs) { tab in
|
ForEach(tabs) { tab in
|
||||||
if tab != .profile {
|
if tab != .profile && sidebarTabs.isEnabled(tab) {
|
||||||
Button {
|
Button {
|
||||||
// ensure keyboard is always dismissed when selecting a tab
|
// ensure keyboard is always dismissed when selecting a tab
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
|
|
|
@ -164,6 +164,10 @@ 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")
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import DesignSystem
|
||||||
|
import Env
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,13 +6,15 @@ import StatusKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
case timeline, notifications, mentions, explore, messages, settings, other
|
case timeline, notifications, mentions, explore, messages, settings, other
|
||||||
case trending, federated, local
|
case trending, federated, local
|
||||||
case profile
|
case profile
|
||||||
case bookmarks
|
case bookmarks
|
||||||
case favorites
|
case favorites
|
||||||
case post
|
case post
|
||||||
|
case followedTags
|
||||||
|
case lists
|
||||||
|
|
||||||
nonisolated var id: Int {
|
nonisolated var id: Int {
|
||||||
rawValue
|
rawValue
|
||||||
|
@ -21,16 +23,9 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
||||||
static func loggedOutTab() -> [Tab] {
|
static func loggedOutTab() -> [Tab] {
|
||||||
[.timeline, .settings]
|
[.timeline, .settings]
|
||||||
}
|
}
|
||||||
|
|
||||||
static func loggedInTabs() -> [Tab] {
|
static func visionOSTab() -> [Tab] {
|
||||||
if UIDevice.current.userInterfaceIdiom == .pad ||
|
[.profile, .timeline, .notifications, .mentions, .explore, .messages, .settings]
|
||||||
UIDevice.current.userInterfaceIdiom == .mac {
|
|
||||||
[.timeline, .trending, .federated, .local, .notifications, .mentions, .explore, .messages, .bookmarks, .favorites, .profile, .settings]
|
|
||||||
} else if UIDevice.current.userInterfaceIdiom == .vision {
|
|
||||||
[.profile, .timeline, .notifications, .mentions, .explore, .messages, .settings]
|
|
||||||
} else {
|
|
||||||
[.timeline, .notifications, .explore, .messages, .profile]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
|
@ -64,6 +59,14 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
||||||
NavigationTab {
|
NavigationTab {
|
||||||
AccountStatusesListView(mode: .favorites)
|
AccountStatusesListView(mode: .favorites)
|
||||||
}
|
}
|
||||||
|
case .followedTags:
|
||||||
|
NavigationTab {
|
||||||
|
FollowedTagsListView()
|
||||||
|
}
|
||||||
|
case .lists:
|
||||||
|
NavigationTab {
|
||||||
|
ListsListView()
|
||||||
|
}
|
||||||
case .post:
|
case .post:
|
||||||
VStack { }
|
VStack { }
|
||||||
case .other:
|
case .other:
|
||||||
|
@ -100,6 +103,10 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
||||||
Label("accessibility.tabs.profile.picker.favorites", systemImage: iconName)
|
Label("accessibility.tabs.profile.picker.favorites", systemImage: iconName)
|
||||||
case .post:
|
case .post:
|
||||||
Label("menu.new-post", systemImage: iconName)
|
Label("menu.new-post", systemImage: iconName)
|
||||||
|
case .followedTags:
|
||||||
|
Label("timeline.filter.tags", systemImage: iconName)
|
||||||
|
case .lists:
|
||||||
|
Label("timeline.filter.lists", systemImage: iconName)
|
||||||
case .other:
|
case .other:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
|
|
||||||
|
@ -134,12 +141,61 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
||||||
"star"
|
"star"
|
||||||
case .post:
|
case .post:
|
||||||
"square.and.pencil"
|
"square.and.pencil"
|
||||||
|
case .followedTags:
|
||||||
|
"tag"
|
||||||
|
case .lists:
|
||||||
|
"list.bullet"
|
||||||
case .other:
|
case .other:
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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: .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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Observable
|
@Observable
|
||||||
class iOSTabs {
|
class iOSTabs {
|
||||||
enum TabEntries: String {
|
enum TabEntries: String {
|
||||||
|
|
|
@ -47558,6 +47558,125 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"settings.general.sidebarEntries" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"be" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ca" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"de" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"en-GB" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"es" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"eu" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"it" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ja" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ko" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nb" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nl" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pl" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pt-BR" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uk" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "needs_review",
|
||||||
|
"value" : "Sidebar Customizations"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"settings.general.swipeactions" : {
|
"settings.general.swipeactions" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"be" : {
|
"be" : {
|
||||||
|
@ -75118,4 +75237,4 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version" : "1.0"
|
"version" : "1.0"
|
||||||
}
|
}
|
46
Packages/Account/Sources/Account/Lists/ListsListView.swift
Normal file
46
Packages/Account/Sources/Account/Lists/ListsListView.swift
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import DesignSystem
|
||||||
|
import Models
|
||||||
|
import SwiftUI
|
||||||
|
import Env
|
||||||
|
|
||||||
|
public struct ListsListView: View {
|
||||||
|
@Environment(CurrentAccount.self) private var currentAccount
|
||||||
|
@Environment(Theme.self) private var theme
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
public var body: some View {
|
||||||
|
List {
|
||||||
|
ForEach(currentAccount.lists) { list in
|
||||||
|
NavigationLink(value: RouterDestination.list(list: list)) {
|
||||||
|
Text(list.title)
|
||||||
|
.font(.scaledHeadline)
|
||||||
|
}
|
||||||
|
#if !os(visionOS)
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
.onDelete { index in
|
||||||
|
if let index = index.first {
|
||||||
|
Task {
|
||||||
|
await currentAccount.deleteList(currentAccount.lists[index])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.task {
|
||||||
|
await currentAccount.fetchLists()
|
||||||
|
}
|
||||||
|
.refreshable {
|
||||||
|
await currentAccount.fetchLists()
|
||||||
|
}
|
||||||
|
#if !os(visionOS)
|
||||||
|
.scrollContentBackground(.hidden)
|
||||||
|
.background(theme.secondaryBackgroundColor)
|
||||||
|
#endif
|
||||||
|
.listStyle(.plain)
|
||||||
|
.navigationTitle("timeline.filter.lists")
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
import DesignSystem
|
||||||
|
import Models
|
||||||
|
import SwiftUI
|
||||||
|
import Env
|
||||||
|
|
||||||
|
public struct FollowedTagsListView: View {
|
||||||
|
@Environment(CurrentAccount.self) private var currentAccount
|
||||||
|
@Environment(Theme.self) private var theme
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
public var body: some View {
|
||||||
|
List(currentAccount.tags) { tag in
|
||||||
|
TagRowView(tag: tag)
|
||||||
|
#if !os(visionOS)
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
#endif
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
}
|
||||||
|
.task {
|
||||||
|
await currentAccount.fetchFollowedTags()
|
||||||
|
}
|
||||||
|
.refreshable {
|
||||||
|
await currentAccount.fetchFollowedTags()
|
||||||
|
}
|
||||||
|
#if !os(visionOS)
|
||||||
|
.scrollContentBackground(.hidden)
|
||||||
|
.background(theme.secondaryBackgroundColor)
|
||||||
|
#endif
|
||||||
|
.listStyle(.plain)
|
||||||
|
.navigationTitle("timeline.filter.tags")
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ import Observation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func deleteList(list: Models.List) async {
|
public func deleteList(_ list: Models.List) async {
|
||||||
guard let client else { return }
|
guard let client else { return }
|
||||||
lists.removeAll(where: { $0.id == list.id })
|
lists.removeAll(where: { $0.id == list.id })
|
||||||
let response = try? await client.delete(endpoint: Lists.list(id: list.id))
|
let response = try? await client.delete(endpoint: Lists.list(id: list.id))
|
||||||
|
|
Loading…
Reference in a new issue