Editor character count + settings instance rules
This commit is contained in:
parent
1b53180faf
commit
5b9f91abd1
@ -11,6 +11,7 @@ struct IceCubesApp: App {
|
|||||||
|
|
||||||
@Environment(\.scenePhase) private var scenePhase
|
@Environment(\.scenePhase) private var scenePhase
|
||||||
@StateObject private var appAccountsManager = AppAccountsManager()
|
@StateObject private var appAccountsManager = AppAccountsManager()
|
||||||
|
@StateObject private var currenInstance = CurrentInstance()
|
||||||
@StateObject private var currentAccount = CurrentAccount()
|
@StateObject private var currentAccount = CurrentAccount()
|
||||||
@StateObject private var watcher = StreamWatcher()
|
@StateObject private var watcher = StreamWatcher()
|
||||||
@StateObject private var quickLook = QuickLook()
|
@StateObject private var quickLook = QuickLook()
|
||||||
@ -56,6 +57,7 @@ struct IceCubesApp: App {
|
|||||||
.environmentObject(appAccountsManager.currentClient)
|
.environmentObject(appAccountsManager.currentClient)
|
||||||
.environmentObject(quickLook)
|
.environmentObject(quickLook)
|
||||||
.environmentObject(currentAccount)
|
.environmentObject(currentAccount)
|
||||||
|
.environmentObject(currenInstance)
|
||||||
.environmentObject(theme)
|
.environmentObject(theme)
|
||||||
.environmentObject(watcher)
|
.environmentObject(watcher)
|
||||||
.quickLookPreview($quickLook.url, in: quickLook.urls)
|
.quickLookPreview($quickLook.url, in: quickLook.urls)
|
||||||
@ -67,6 +69,7 @@ struct IceCubesApp: App {
|
|||||||
|
|
||||||
private func setNewClientsInEnv(client: Client) {
|
private func setNewClientsInEnv(client: Client) {
|
||||||
currentAccount.setClient(client: client)
|
currentAccount.setClient(client: client)
|
||||||
|
currenInstance.setClient(client: client)
|
||||||
watcher.setClient(client: client)
|
watcher.setClient(client: client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,12 +9,12 @@ import DesignSystem
|
|||||||
struct SettingsTabs: View {
|
struct SettingsTabs: View {
|
||||||
@Environment(\.openURL) private var openURL
|
@Environment(\.openURL) private var openURL
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
|
@EnvironmentObject private var currentInstance: CurrentInstance
|
||||||
@EnvironmentObject private var appAccountsManager: AppAccountsManager
|
@EnvironmentObject private var appAccountsManager: AppAccountsManager
|
||||||
@EnvironmentObject private var theme: Theme
|
@EnvironmentObject private var theme: Theme
|
||||||
|
|
||||||
@State private var signInInProgress = false
|
@State private var signInInProgress = false
|
||||||
@State private var accountData: Account?
|
@State private var accountData: Account?
|
||||||
@State private var instanceData: Instance?
|
|
||||||
@State private var signInServer = IceCubesApp.defaultServer
|
@State private var signInServer = IceCubesApp.defaultServer
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@ -37,7 +37,7 @@ struct SettingsTabs: View {
|
|||||||
if appAccountsManager.currentAccount.oauthToken != nil {
|
if appAccountsManager.currentAccount.oauthToken != nil {
|
||||||
signInInProgress = true
|
signInInProgress = true
|
||||||
await refreshAccountInfo()
|
await refreshAccountInfo()
|
||||||
await refreshInstanceInfo()
|
await currentInstance.fetchCurrentInstance()
|
||||||
signInInProgress = false
|
signInInProgress = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ struct SettingsTabs: View {
|
|||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var instanceSection: some View {
|
private var instanceSection: some View {
|
||||||
if let instanceData {
|
if let instanceData = currentInstance.instance {
|
||||||
Section("Instance info") {
|
Section("Instance info") {
|
||||||
LabeledContent("Name", value: instanceData.title)
|
LabeledContent("Name", value: instanceData.title)
|
||||||
Text(instanceData.shortDescription)
|
Text(instanceData.shortDescription)
|
||||||
@ -87,6 +87,12 @@ struct SettingsTabs: View {
|
|||||||
LabeledContent("Posts", value: "\(instanceData.stats.statusCount)")
|
LabeledContent("Posts", value: "\(instanceData.stats.statusCount)")
|
||||||
LabeledContent("Domains", value: "\(instanceData.stats.domainCount)")
|
LabeledContent("Domains", value: "\(instanceData.stats.domainCount)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Section("Instance rules") {
|
||||||
|
ForEach(instanceData.rules) { rule in
|
||||||
|
Text(rule.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +133,6 @@ struct SettingsTabs: View {
|
|||||||
|
|
||||||
private var signOutButton: some View {
|
private var signOutButton: some View {
|
||||||
Button {
|
Button {
|
||||||
instanceData = nil
|
|
||||||
accountData = nil
|
accountData = nil
|
||||||
appAccountsManager.delete(account: appAccountsManager.currentAccount)
|
appAccountsManager.delete(account: appAccountsManager.currentAccount)
|
||||||
} label: {
|
} label: {
|
||||||
@ -151,7 +156,7 @@ struct SettingsTabs: View {
|
|||||||
let oauthToken = try await client.continueOauthFlow(url: url)
|
let oauthToken = try await client.continueOauthFlow(url: url)
|
||||||
appAccountsManager.add(account: AppAccount(server: client.server, oauthToken: oauthToken))
|
appAccountsManager.add(account: AppAccount(server: client.server, oauthToken: oauthToken))
|
||||||
await refreshAccountInfo()
|
await refreshAccountInfo()
|
||||||
await refreshInstanceInfo()
|
await currentInstance.fetchCurrentInstance()
|
||||||
signInInProgress = false
|
signInInProgress = false
|
||||||
} catch {
|
} catch {
|
||||||
signInInProgress = false
|
signInInProgress = false
|
||||||
@ -161,8 +166,4 @@ struct SettingsTabs: View {
|
|||||||
private func refreshAccountInfo() async {
|
private func refreshAccountInfo() async {
|
||||||
accountData = try? await client.get(endpoint: Accounts.verifyCredentials)
|
accountData = try? await client.get(endpoint: Accounts.verifyCredentials)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func refreshInstanceInfo() async {
|
|
||||||
instanceData = try? await client.get(endpoint: Instances.instance)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
28
Packages/Env/Sources/Env/CurrentInstance.swift
Normal file
28
Packages/Env/Sources/Env/CurrentInstance.swift
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import Foundation
|
||||||
|
import Models
|
||||||
|
import Network
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
public class CurrentInstance: ObservableObject {
|
||||||
|
@Published public private(set) var instance: Instance?
|
||||||
|
|
||||||
|
private var client: Client?
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setClient(client: Client) {
|
||||||
|
self.client = client
|
||||||
|
Task {
|
||||||
|
await fetchCurrentInstance()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func fetchCurrentInstance() async {
|
||||||
|
guard let client = client else { return }
|
||||||
|
Task {
|
||||||
|
instance = try? await client.get(endpoint: Instances.instance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,28 @@ public struct Instance: Codable {
|
|||||||
public let domainCount: Int
|
public let domainCount: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct Configuration: Codable {
|
||||||
|
public struct Statuses: Codable {
|
||||||
|
public let maxCharacters: Int
|
||||||
|
public let maxMediaAttachments: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Polls: Codable {
|
||||||
|
public let maxOptions: Int
|
||||||
|
public let maxCharactersPerOption: Int
|
||||||
|
public let minExpiration: Int
|
||||||
|
public let maxExpiration: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
public let statuses: Statuses
|
||||||
|
public let polls: Polls
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Rule: Codable, Identifiable {
|
||||||
|
public let id: String
|
||||||
|
public let text: String
|
||||||
|
}
|
||||||
|
|
||||||
public let title: String
|
public let title: String
|
||||||
public let shortDescription: String
|
public let shortDescription: String
|
||||||
public let email: String
|
public let email: String
|
||||||
@ -15,4 +37,6 @@ public struct Instance: Codable {
|
|||||||
public let languages: [String]
|
public let languages: [String]
|
||||||
public let registrations: Bool
|
public let registrations: Bool
|
||||||
public let thumbnail: URL?
|
public let thumbnail: URL?
|
||||||
|
public let configuration: Configuration
|
||||||
|
public let rules: [Rule]
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import NukeUI
|
|||||||
public struct StatusEditorView: View {
|
public struct StatusEditorView: View {
|
||||||
@EnvironmentObject private var quicklook: QuickLook
|
@EnvironmentObject private var quicklook: QuickLook
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
|
@EnvironmentObject private var currentInstance: CurrentInstance
|
||||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
|
||||||
@ -196,9 +197,11 @@ public struct StatusEditorView: View {
|
|||||||
Image(systemName: "number")
|
Image(systemName: "number")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visibilityMenu
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
visibilityMenu
|
characterCountView
|
||||||
}
|
}
|
||||||
.padding(.horizontal, DS.Constants.layoutPadding)
|
.padding(.horizontal, DS.Constants.layoutPadding)
|
||||||
.padding(.vertical, 12)
|
.padding(.vertical, 12)
|
||||||
@ -206,6 +209,12 @@ public struct StatusEditorView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var characterCountView: some View {
|
||||||
|
Text("\((currentInstance.instance?.configuration.statuses.maxCharacters ?? 500) - viewModel.statusText.string.utf16.count)")
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
.font(.callout)
|
||||||
|
}
|
||||||
|
|
||||||
private var visibilityMenu: some View {
|
private var visibilityMenu: some View {
|
||||||
Menu {
|
Menu {
|
||||||
ForEach(Models.Visibility.allCases, id: \.self) { visibility in
|
ForEach(Models.Visibility.allCases, id: \.self) { visibility in
|
||||||
|
Loading…
x
Reference in New Issue
Block a user