mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-25 17:51:01 +00:00
Account tab + brand color
This commit is contained in:
parent
3d7042832e
commit
8def548913
11 changed files with 113 additions and 8 deletions
|
@ -13,6 +13,7 @@
|
||||||
9F35DB44294F9A7D00B3281A /* Status in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB43294F9A7D00B3281A /* Status */; };
|
9F35DB44294F9A7D00B3281A /* Status in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB43294F9A7D00B3281A /* Status */; };
|
||||||
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4629506F6600B3281A /* NotificationTab.swift */; };
|
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4629506F6600B3281A /* NotificationTab.swift */; };
|
||||||
9F35DB4A29506FA100B3281A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB4929506FA100B3281A /* Notifications */; };
|
9F35DB4A29506FA100B3281A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB4929506FA100B3281A /* Notifications */; };
|
||||||
|
9F35DB4C2952005C00B3281A /* AccountTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4B2952005C00B3281A /* AccountTab.swift */; };
|
||||||
9F398AA62935FE8A00A889F2 /* AppRouteur.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F398AA52935FE8A00A889F2 /* AppRouteur.swift */; };
|
9F398AA62935FE8A00A889F2 /* AppRouteur.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F398AA52935FE8A00A889F2 /* AppRouteur.swift */; };
|
||||||
9F398AA92935FFDB00A889F2 /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 9F398AA82935FFDB00A889F2 /* Account */; };
|
9F398AA92935FFDB00A889F2 /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 9F398AA82935FFDB00A889F2 /* Account */; };
|
||||||
9F398AAB2935FFDB00A889F2 /* Models in Frameworks */ = {isa = PBXBuildFile; productRef = 9F398AAA2935FFDB00A889F2 /* Models */; };
|
9F398AAB2935FFDB00A889F2 /* Models in Frameworks */ = {isa = PBXBuildFile; productRef = 9F398AAA2935FFDB00A889F2 /* Models */; };
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
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>"; };
|
||||||
9F35DB4629506F6600B3281A /* NotificationTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTab.swift; sourceTree = "<group>"; };
|
9F35DB4629506F6600B3281A /* NotificationTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTab.swift; sourceTree = "<group>"; };
|
||||||
9F35DB4829506F7F00B3281A /* Notifications */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Notifications; path = Packages/Notifications; sourceTree = "<group>"; };
|
9F35DB4829506F7F00B3281A /* Notifications */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Notifications; path = Packages/Notifications; sourceTree = "<group>"; };
|
||||||
|
9F35DB4B2952005C00B3281A /* AccountTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTab.swift; sourceTree = "<group>"; };
|
||||||
9F398AA32935F90100A889F2 /* Models */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Models; path = Packages/Models; sourceTree = "<group>"; };
|
9F398AA32935F90100A889F2 /* Models */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Models; path = Packages/Models; sourceTree = "<group>"; };
|
||||||
9F398AA52935FE8A00A889F2 /* AppRouteur.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouteur.swift; sourceTree = "<group>"; };
|
9F398AA52935FE8A00A889F2 /* AppRouteur.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouteur.swift; sourceTree = "<group>"; };
|
||||||
9F398AAC2936005300A889F2 /* Account */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Account; path = Packages/Account; sourceTree = "<group>"; };
|
9F398AAC2936005300A889F2 /* Account */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Account; path = Packages/Account; sourceTree = "<group>"; };
|
||||||
|
@ -95,6 +97,7 @@
|
||||||
9FE151A4293C90EA00E9683D /* Settings */,
|
9FE151A4293C90EA00E9683D /* Settings */,
|
||||||
9F398AB229360A4C00A889F2 /* TimelineTab.swift */,
|
9F398AB229360A4C00A889F2 /* TimelineTab.swift */,
|
||||||
9F35DB4629506F6600B3281A /* NotificationTab.swift */,
|
9F35DB4629506F6600B3281A /* NotificationTab.swift */,
|
||||||
|
9F35DB4B2952005C00B3281A /* AccountTab.swift */,
|
||||||
);
|
);
|
||||||
path = Tabs;
|
path = Tabs;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -199,7 +202,7 @@
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = 1;
|
BuildIndependentTargetsInParallel = 1;
|
||||||
LastSwiftUpdateCheck = 1410;
|
LastSwiftUpdateCheck = 1410;
|
||||||
LastUpgradeCheck = 1410;
|
LastUpgradeCheck = 1420;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
9FBFE638292A715500C250E9 = {
|
9FBFE638292A715500C250E9 = {
|
||||||
CreatedOnToolsVersion = 14.1;
|
CreatedOnToolsVersion = 14.1;
|
||||||
|
@ -245,6 +248,7 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
9FE151A6293C90F900E9683D /* IconSelectorView.swift in Sources */,
|
9FE151A6293C90F900E9683D /* IconSelectorView.swift in Sources */,
|
||||||
|
9F35DB4C2952005C00B3281A /* AccountTab.swift in Sources */,
|
||||||
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
||||||
9FAE4AD32937A0C600772766 /* AppAccountsManager.swift in Sources */,
|
9FAE4AD32937A0C600772766 /* AppAccountsManager.swift in Sources */,
|
||||||
9F398AB329360A4C00A889F2 /* TimelineTab.swift in Sources */,
|
9F398AB329360A4C00A889F2 /* TimelineTab.swift in Sources */,
|
||||||
|
@ -291,6 +295,7 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
|
@ -349,6 +354,7 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
@ -375,8 +381,10 @@
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = IceCubesApp/IceCubesApp.entitlements;
|
CODE_SIGN_ENTITLEMENTS = IceCubesApp/IceCubesApp.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 200;
|
CURRENT_PROJECT_VERSION = 200;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\"";
|
DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\"";
|
||||||
DEVELOPMENT_TEAM = Z6P74P6T99;
|
DEVELOPMENT_TEAM = Z6P74P6T99;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
@ -416,8 +424,10 @@
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = IceCubesApp/IceCubesApp.entitlements;
|
CODE_SIGN_ENTITLEMENTS = IceCubesApp/IceCubesApp.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 200;
|
CURRENT_PROJECT_VERSION = 200;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\"";
|
DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\"";
|
||||||
DEVELOPMENT_TEAM = Z6P74P6T99;
|
DEVELOPMENT_TEAM = Z6P74P6T99;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1410"
|
LastUpgradeVersion = "1420"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -21,12 +21,17 @@ struct IceCubesApp: App {
|
||||||
.tabItem {
|
.tabItem {
|
||||||
Label("Notifications", systemImage: "bell")
|
Label("Notifications", systemImage: "bell")
|
||||||
}
|
}
|
||||||
|
AccountTab()
|
||||||
|
.tabItem {
|
||||||
|
Label("Profile", systemImage: "person.circle")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SettingsTabs()
|
SettingsTabs()
|
||||||
.tabItem {
|
.tabItem {
|
||||||
Label("Settings", systemImage: "gear")
|
Label("Settings", systemImage: "gear")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.tint(.brand)
|
||||||
.environmentObject(appAccountsManager)
|
.environmentObject(appAccountsManager)
|
||||||
.environmentObject(appAccountsManager.currentClient)
|
.environmentObject(appAccountsManager.currentClient)
|
||||||
}
|
}
|
||||||
|
|
45
IceCubesApp/App/Tabs/AccountTab.swift
Normal file
45
IceCubesApp/App/Tabs/AccountTab.swift
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import SwiftUI
|
||||||
|
import Routeur
|
||||||
|
import Network
|
||||||
|
import Account
|
||||||
|
import Models
|
||||||
|
import Shimmer
|
||||||
|
|
||||||
|
struct AccountTab: View {
|
||||||
|
@EnvironmentObject private var client: Client
|
||||||
|
@StateObject private var routeurPath = RouterPath()
|
||||||
|
@State private var loggedUser: Account?
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationStack(path: $routeurPath.path) {
|
||||||
|
if let loggedUser {
|
||||||
|
AccountDetailView(account: loggedUser, isCurrentUser: true)
|
||||||
|
.withAppRouteur()
|
||||||
|
.withSheetDestinations(sheetDestinations: $routeurPath.presentedSheet)
|
||||||
|
} else {
|
||||||
|
AccountDetailView(account: .placeholder())
|
||||||
|
.redacted(reason: .placeholder)
|
||||||
|
.shimmering()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
Task {
|
||||||
|
await fetchUser(client: client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onChange(of: client) { newClient in
|
||||||
|
Task {
|
||||||
|
await fetchUser(client: newClient)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.environmentObject(routeurPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private func fetchUser(client: Client) async {
|
||||||
|
guard client.isAuth else { return }
|
||||||
|
Task {
|
||||||
|
loggedUser = try? await client.get(endpoint: Accounts.verifyCredentials)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,12 +10,16 @@ public struct AccountDetailView: View {
|
||||||
@StateObject private var viewModel: AccountDetailViewModel
|
@StateObject private var viewModel: AccountDetailViewModel
|
||||||
@State private var scrollOffset: CGFloat = 0
|
@State private var scrollOffset: CGFloat = 0
|
||||||
|
|
||||||
|
private let isCurrentUser: Bool
|
||||||
|
|
||||||
public init(accountId: String) {
|
public init(accountId: String) {
|
||||||
_viewModel = StateObject(wrappedValue: .init(accountId: accountId))
|
_viewModel = StateObject(wrappedValue: .init(accountId: accountId))
|
||||||
|
isCurrentUser = false
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(account: Account) {
|
public init(account: Account, isCurrentUser: Bool = false) {
|
||||||
_viewModel = StateObject(wrappedValue: .init(account: account))
|
_viewModel = StateObject(wrappedValue: .init(account: account))
|
||||||
|
self.isCurrentUser = isCurrentUser
|
||||||
}
|
}
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
|
@ -32,7 +36,15 @@ public struct AccountDetailView: View {
|
||||||
.task {
|
.task {
|
||||||
viewModel.client = client
|
viewModel.client = client
|
||||||
await viewModel.fetchAccount()
|
await viewModel.fetchAccount()
|
||||||
await viewModel.fetchStatuses()
|
if viewModel.statuses.isEmpty {
|
||||||
|
await viewModel.fetchStatuses()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.refreshable {
|
||||||
|
Task {
|
||||||
|
await viewModel.fetchAccount()
|
||||||
|
await viewModel.fetchStatuses()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.edgesIgnoringSafeArea(.top)
|
.edgesIgnoringSafeArea(.top)
|
||||||
.navigationTitle(Text(scrollOffset < -20 ? viewModel.title : ""))
|
.navigationTitle(Text(scrollOffset < -20 ? viewModel.title : ""))
|
||||||
|
|
|
@ -18,7 +18,7 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
|
||||||
@Published var title: String = ""
|
@Published var title: String = ""
|
||||||
|
|
||||||
private var account: Account?
|
private var account: Account?
|
||||||
private var statuses: [Status] = []
|
private(set) var statuses: [Status] = []
|
||||||
|
|
||||||
init(accountId: String) {
|
init(accountId: String) {
|
||||||
self.accountId = accountId
|
self.accountId = accountId
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
extension Color {
|
||||||
|
public static var brand: Color {
|
||||||
|
Color("brand", bundle: .module)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "255",
|
||||||
|
"green" : "90",
|
||||||
|
"red" : "89"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public struct App: Codable, Identifiable {
|
public struct InstanceApp: Codable, Identifiable {
|
||||||
public let id: String
|
public let id: String
|
||||||
public let name: String
|
public let name: String
|
||||||
public let website: URL?
|
public let website: URL?
|
|
@ -24,7 +24,7 @@ public class Client: ObservableObject, Equatable {
|
||||||
private let decoder = JSONDecoder()
|
private let decoder = JSONDecoder()
|
||||||
|
|
||||||
/// Only used as a transitionary app while in the oauth flow.
|
/// Only used as a transitionary app while in the oauth flow.
|
||||||
private var oauthApp: Models.App?
|
private var oauthApp: InstanceApp?
|
||||||
|
|
||||||
private var oauthToken: OauthToken?
|
private var oauthToken: OauthToken?
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ public class Client: ObservableObject, Equatable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func oauthURL() async throws -> URL {
|
public func oauthURL() async throws -> URL {
|
||||||
let app: Models.App = try await post(endpoint: Apps.registerApp)
|
let app: InstanceApp = try await post(endpoint: Apps.registerApp)
|
||||||
self.oauthApp = app
|
self.oauthApp = app
|
||||||
return makeURL(endpoint: Oauth.authorize(clientId: app.clientId))
|
return makeURL(endpoint: Oauth.authorize(clientId: app.clientId))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue