mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-02-03 16:07:31 +01:00
Swift format
This commit is contained in:
parent
5871d13eee
commit
16636b12a9
@ -12,9 +12,9 @@ import Timeline
|
|||||||
@main
|
@main
|
||||||
struct IceCubesApp: App {
|
struct IceCubesApp: App {
|
||||||
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
|
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
|
||||||
|
|
||||||
@Environment(\.scenePhase) private var scenePhase
|
@Environment(\.scenePhase) private var scenePhase
|
||||||
|
|
||||||
@StateObject private var appAccountsManager = AppAccountsManager.shared
|
@StateObject private var appAccountsManager = AppAccountsManager.shared
|
||||||
@StateObject private var currentInstance = CurrentInstance.shared
|
@StateObject private var currentInstance = CurrentInstance.shared
|
||||||
@StateObject private var currentAccount = CurrentAccount.shared
|
@StateObject private var currentAccount = CurrentAccount.shared
|
||||||
@ -23,18 +23,18 @@ struct IceCubesApp: App {
|
|||||||
@StateObject private var quickLook = QuickLook()
|
@StateObject private var quickLook = QuickLook()
|
||||||
@StateObject private var theme = Theme.shared
|
@StateObject private var theme = Theme.shared
|
||||||
@StateObject private var sidebarRouterPath = RouterPath()
|
@StateObject private var sidebarRouterPath = RouterPath()
|
||||||
|
|
||||||
@State private var selectedTab: Tab = .timeline
|
@State private var selectedTab: Tab = .timeline
|
||||||
@State private var selectSidebarItem: Tab? = .timeline
|
@State private var selectSidebarItem: Tab? = .timeline
|
||||||
@State private var popToRootTab: Tab = .other
|
@State private var popToRootTab: Tab = .other
|
||||||
@State private var sideBarLoadedTabs: Set<Tab> = Set()
|
@State private var sideBarLoadedTabs: Set<Tab> = Set()
|
||||||
|
|
||||||
private let feedbackGenerator = UISelectionFeedbackGenerator()
|
private let feedbackGenerator = UISelectionFeedbackGenerator()
|
||||||
|
|
||||||
private var availableTabs: [Tab] {
|
private var availableTabs: [Tab] {
|
||||||
appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()
|
appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
appView
|
appView
|
||||||
@ -72,7 +72,7 @@ struct IceCubesApp: App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var appView: some View {
|
private var appView: some View {
|
||||||
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
||||||
@ -81,14 +81,14 @@ struct IceCubesApp: App {
|
|||||||
tabBarView
|
tabBarView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func badgeFor(tab: Tab) -> Int {
|
private func badgeFor(tab: Tab) -> Int {
|
||||||
if tab == .notifications && selectedTab != tab {
|
if tab == .notifications && selectedTab != tab {
|
||||||
return watcher.unreadNotificationsCount + userPreferences.pushNotificationsCount
|
return watcher.unreadNotificationsCount + userPreferences.pushNotificationsCount
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private var sidebarView: some View {
|
private var sidebarView: some View {
|
||||||
SideBarView(selectedTab: $selectedTab,
|
SideBarView(selectedTab: $selectedTab,
|
||||||
popToRootTab: $popToRootTab,
|
popToRootTab: $popToRootTab,
|
||||||
@ -116,7 +116,8 @@ struct IceCubesApp: App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if proxy.frame(in: .global).width > (.maxColumnWidth + .secondaryColumnWidth),
|
if proxy.frame(in: .global).width > (.maxColumnWidth + .secondaryColumnWidth),
|
||||||
currentAccount.account?.id != nil {
|
currentAccount.account?.id != nil
|
||||||
|
{
|
||||||
Divider().edgesIgnoringSafeArea(.all)
|
Divider().edgesIgnoringSafeArea(.all)
|
||||||
NotificationsTab(popToRootTab: $popToRootTab, lockedType: nil)
|
NotificationsTab(popToRootTab: $popToRootTab, lockedType: nil)
|
||||||
.environment(\.isSecondaryColumn, true)
|
.environment(\.isSecondaryColumn, true)
|
||||||
@ -128,7 +129,7 @@ struct IceCubesApp: App {
|
|||||||
sideBarLoadedTabs.removeAll()
|
sideBarLoadedTabs.removeAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var tabBarView: some View {
|
private var tabBarView: some View {
|
||||||
TabView(selection: .init(get: {
|
TabView(selection: .init(get: {
|
||||||
selectedTab
|
selectedTab
|
||||||
@ -154,14 +155,14 @@ struct IceCubesApp: App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setNewClientsInEnv(client: Client) {
|
private func setNewClientsInEnv(client: Client) {
|
||||||
currentAccount.setClient(client: client)
|
currentAccount.setClient(client: client)
|
||||||
currentInstance.setClient(client: client)
|
currentInstance.setClient(client: client)
|
||||||
userPreferences.setClient(client: client)
|
userPreferences.setClient(client: client)
|
||||||
watcher.setClient(client: client)
|
watcher.setClient(client: client)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleScenePhase(scenePhase: ScenePhase) {
|
private func handleScenePhase(scenePhase: ScenePhase) {
|
||||||
switch scenePhase {
|
switch scenePhase {
|
||||||
case .background:
|
case .background:
|
||||||
@ -178,16 +179,16 @@ struct IceCubesApp: App {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupRevenueCat() {
|
private func setupRevenueCat() {
|
||||||
Purchases.logLevel = .error
|
Purchases.logLevel = .error
|
||||||
Purchases.configure(withAPIKey: "appl_JXmiRckOzXXTsHKitQiicXCvMQi")
|
Purchases.configure(withAPIKey: "appl_JXmiRckOzXXTsHKitQiicXCvMQi")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func refreshPushSubs() {
|
private func refreshPushSubs() {
|
||||||
PushNotificationsService.shared.requestPushNotifications()
|
PushNotificationsService.shared.requestPushNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
@CommandsBuilder
|
@CommandsBuilder
|
||||||
private var appMenu: some Commands {
|
private var appMenu: some Commands {
|
||||||
CommandGroup(replacing: .newItem) {
|
CommandGroup(replacing: .newItem) {
|
||||||
@ -214,14 +215,14 @@ struct IceCubesApp: App {
|
|||||||
|
|
||||||
class AppDelegate: NSObject, UIApplicationDelegate {
|
class AppDelegate: NSObject, UIApplicationDelegate {
|
||||||
let themeObserver = ThemeObserverViewController(nibName: nil, bundle: nil)
|
let themeObserver = ThemeObserverViewController(nibName: nil, bundle: nil)
|
||||||
|
|
||||||
func application(_: UIApplication,
|
func application(_: UIApplication,
|
||||||
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool
|
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool
|
||||||
{
|
{
|
||||||
try? AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)
|
try? AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func application(_: UIApplication,
|
func application(_: UIApplication,
|
||||||
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
|
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
|
||||||
{
|
{
|
||||||
@ -231,9 +232,9 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
|||||||
await PushNotificationsService.shared.updateSubscriptions(forceCreate: false)
|
await PushNotificationsService.shared.updateSubscriptions(forceCreate: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) {}
|
func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) {}
|
||||||
|
|
||||||
func application(_: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options _: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
func application(_: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options _: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
||||||
let configuration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
|
let configuration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
|
||||||
if connectingSceneSession.role == .windowApplication {
|
if connectingSceneSession.role == .windowApplication {
|
||||||
@ -246,7 +247,7 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
|||||||
class ThemeObserverViewController: UIViewController {
|
class ThemeObserverViewController: UIViewController {
|
||||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||||
super.traitCollectionDidChange(previousTraitCollection)
|
super.traitCollectionDidChange(previousTraitCollection)
|
||||||
|
|
||||||
print(traitCollection.userInterfaceStyle.rawValue)
|
print(traitCollection.userInterfaceStyle.rawValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ struct QuickLookPreview: UIViewControllerRepresentable {
|
|||||||
let selectedURL: URL
|
let selectedURL: URL
|
||||||
let urls: [URL]
|
let urls: [URL]
|
||||||
|
|
||||||
func makeUIViewController(context: Context) -> UIViewController {
|
func makeUIViewController(context _: Context) -> UIViewController {
|
||||||
return AppQLPreviewController(selectedURL: selectedURL, urls: urls)
|
return AppQLPreviewController(selectedURL: selectedURL, urls: urls)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,65 +24,65 @@ struct QuickLookPreview: UIViewControllerRepresentable {
|
|||||||
class AppQLPreviewController: UIViewController {
|
class AppQLPreviewController: UIViewController {
|
||||||
let selectedURL: URL
|
let selectedURL: URL
|
||||||
let urls: [URL]
|
let urls: [URL]
|
||||||
|
|
||||||
var qlController : QLPreviewController?
|
var qlController: QLPreviewController?
|
||||||
|
|
||||||
init(selectedURL: URL, urls: [URL]) {
|
init(selectedURL: URL, urls: [URL]) {
|
||||||
self.selectedURL = selectedURL
|
self.selectedURL = selectedURL
|
||||||
self.urls = urls
|
self.urls = urls
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
@available(*, unavailable)
|
||||||
|
required init?(coder _: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
if self.qlController == nil {
|
if qlController == nil {
|
||||||
self.qlController = QLPreviewController()
|
qlController = QLPreviewController()
|
||||||
self.qlController?.dataSource = self
|
qlController?.dataSource = self
|
||||||
self.qlController?.delegate = self
|
qlController?.delegate = self
|
||||||
self.qlController?.currentPreviewItemIndex = urls.firstIndex(of: selectedURL) ?? 0
|
qlController?.currentPreviewItemIndex = urls.firstIndex(of: selectedURL) ?? 0
|
||||||
self.present(self.qlController!, animated: true)
|
present(qlController!, animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppQLPreviewController : QLPreviewControllerDataSource {
|
extension AppQLPreviewController: QLPreviewControllerDataSource {
|
||||||
func numberOfPreviewItems(in _: QLPreviewController) -> Int {
|
func numberOfPreviewItems(in _: QLPreviewController) -> Int {
|
||||||
return self.urls.count
|
return urls.count
|
||||||
}
|
}
|
||||||
|
|
||||||
func previewController(_: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
|
func previewController(_: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
|
||||||
return self.urls[index] as QLPreviewItem
|
return urls[index] as QLPreviewItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppQLPreviewController : QLPreviewControllerDelegate {
|
extension AppQLPreviewController: QLPreviewControllerDelegate {
|
||||||
func previewController(_: QLPreviewController, editingModeFor _: QLPreviewItem) -> QLPreviewItemEditingMode {
|
func previewController(_: QLPreviewController, editingModeFor _: QLPreviewItem) -> QLPreviewItemEditingMode {
|
||||||
.createCopy
|
.createCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
func previewControllerWillDismiss(_ controller: QLPreviewController) {
|
func previewControllerWillDismiss(_: QLPreviewController) {
|
||||||
self.dismiss(animated: true)
|
dismiss(animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TransparentBackground: UIViewControllerRepresentable {
|
struct TransparentBackground: UIViewControllerRepresentable {
|
||||||
public func makeUIViewController(context: Context) -> UIViewController {
|
public func makeUIViewController(context _: Context) -> UIViewController {
|
||||||
return TransparentController()
|
return TransparentController()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
|
public func updateUIViewController(_: UIViewController, context _: Context) {}
|
||||||
}
|
|
||||||
|
|
||||||
class TransparentController: UIViewController {
|
class TransparentController: UIViewController {
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
view.backgroundColor = .clear
|
view.backgroundColor = .clear
|
||||||
}
|
}
|
||||||
|
|
||||||
override func willMove(toParent parent: UIViewController?) {
|
override func willMove(toParent parent: UIViewController?) {
|
||||||
super.willMove(toParent: parent)
|
super.willMove(toParent: parent)
|
||||||
parent?.view?.backgroundColor = .clear
|
parent?.view?.backgroundColor = .clear
|
||||||
|
@ -9,7 +9,7 @@ import Timeline
|
|||||||
|
|
||||||
struct NotificationsTab: View {
|
struct NotificationsTab: View {
|
||||||
@Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool
|
@Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool
|
||||||
|
|
||||||
@EnvironmentObject private var theme: Theme
|
@EnvironmentObject private var theme: Theme
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
@EnvironmentObject private var watcher: StreamWatcher
|
@EnvironmentObject private var watcher: StreamWatcher
|
||||||
|
@ -5,13 +5,13 @@ import Status
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct DisplaySettingsView: View {
|
struct DisplaySettingsView: View {
|
||||||
typealias FontState = Theme.FontState
|
typealias FontState = Theme.FontState
|
||||||
|
|
||||||
@Environment(\.colorScheme) private var colorScheme
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
@EnvironmentObject private var theme: Theme
|
@EnvironmentObject private var theme: Theme
|
||||||
@EnvironmentObject private var userPreferences: UserPreferences
|
@EnvironmentObject private var userPreferences: UserPreferences
|
||||||
|
|
||||||
@State private var isFontSelectorPresented = false
|
@State private var isFontSelectorPresented = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
@ -35,21 +35,21 @@ struct DisplaySettingsView: View {
|
|||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
|
||||||
Section("settings.display.section.display") {
|
Section("settings.display.section.display") {
|
||||||
Picker("settings.display.font", selection: .init(get: {
|
Picker("settings.display.font", selection: .init(get: {
|
||||||
userPreferences.chosenFontData != nil ? FontState.custom : FontState.system
|
userPreferences.chosenFontData != nil ? FontState.custom : FontState.system
|
||||||
}, set: { newValue in
|
}, set: { newValue in
|
||||||
switch newValue {
|
switch newValue {
|
||||||
case .system:
|
case .system:
|
||||||
userPreferences.chosenFont = nil
|
userPreferences.chosenFont = nil
|
||||||
case .custom:
|
case .custom:
|
||||||
isFontSelectorPresented = true
|
isFontSelectorPresented = true
|
||||||
}
|
|
||||||
})) {
|
|
||||||
ForEach(FontState.allCases, id: \.rawValue) { fontState in
|
|
||||||
Text(fontState.title).tag(fontState)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.navigationDestination(isPresented: $isFontSelectorPresented, destination: { FontPicker() })
|
})) {
|
||||||
|
ForEach(FontState.allCases, id: \.rawValue) { fontState in
|
||||||
|
Text(fontState.title).tag(fontState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationDestination(isPresented: $isFontSelectorPresented, destination: { FontPicker() })
|
||||||
Picker("settings.display.avatar.position", selection: $theme.avatarPosition) {
|
Picker("settings.display.avatar.position", selection: $theme.avatarPosition) {
|
||||||
ForEach(Theme.AvatarPosition.allCases, id: \.rawValue) { position in
|
ForEach(Theme.AvatarPosition.allCases, id: \.rawValue) { position in
|
||||||
Text(position.description).tag(position)
|
Text(position.description).tag(position)
|
||||||
|
@ -20,13 +20,13 @@ struct IconSelectorView: View {
|
|||||||
case alt9, alt10, alt11, alt12, alt13, alt14
|
case alt9, alt10, alt11, alt12, alt13, alt14
|
||||||
case alt15, alt16, alt17, alt18, alt19, alt20, alt21
|
case alt15, alt16, alt17, alt18, alt19, alt20, alt21
|
||||||
case alt22, alt23, alt24
|
case alt22, alt23, alt24
|
||||||
|
|
||||||
static var officialIcons: [Icon] {
|
static var officialIcons: [Icon] {
|
||||||
[.primary, .alt1, .alt2, .alt3, .alt4, .alt5, .alt6, .alt7, .alt8,
|
[.primary, .alt1, .alt2, .alt3, .alt4, .alt5, .alt6, .alt7, .alt8,
|
||||||
.alt9, .alt10, .alt11, .alt12, .alt13, .alt14,
|
.alt9, .alt10, .alt11, .alt12, .alt13, .alt14,
|
||||||
.alt15, .alt16, .alt17, .alt18, .alt19]
|
.alt15, .alt16, .alt17, .alt18, .alt19]
|
||||||
}
|
}
|
||||||
|
|
||||||
static var albertKinngIcons: [Icon] {
|
static var albertKinngIcons: [Icon] {
|
||||||
[.alt20, .alt21, .alt22, .alt23, .alt24]
|
[.alt20, .alt21, .alt22, .alt23, .alt24]
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ struct IconSelectorView: View {
|
|||||||
Text("Official icons")
|
Text("Official icons")
|
||||||
.font(.scaledHeadline)
|
.font(.scaledHeadline)
|
||||||
}
|
}
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
makeIconGridView(icons: Icon.albertKinngIcons)
|
makeIconGridView(icons: Icon.albertKinngIcons)
|
||||||
} header: {
|
} header: {
|
||||||
@ -72,7 +72,7 @@ struct IconSelectorView: View {
|
|||||||
}
|
}
|
||||||
.background(theme.primaryBackgroundColor)
|
.background(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeIconGridView(icons: [Icon]) -> some View {
|
private func makeIconGridView(icons: [Icon]) -> some View {
|
||||||
LazyVGrid(columns: columns, spacing: 6) {
|
LazyVGrid(columns: columns, spacing: 6) {
|
||||||
ForEach(icons) { icon in
|
ForEach(icons) { icon in
|
||||||
|
@ -37,14 +37,14 @@ class ShareViewController: UIViewController {
|
|||||||
childView.view.frame = self.view.bounds
|
childView.view.frame = self.view.bounds
|
||||||
self.view.addSubview(childView.view)
|
self.view.addSubview(childView.view)
|
||||||
childView.didMove(toParent: self)
|
childView.didMove(toParent: self)
|
||||||
|
|
||||||
childView.view.translatesAutoresizingMaskIntoConstraints = false
|
childView.view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
childView.view.topAnchor.constraint(equalTo: self.view.topAnchor),
|
childView.view.topAnchor.constraint(equalTo: self.view.topAnchor),
|
||||||
childView.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
|
childView.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
|
||||||
childView.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
|
childView.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
|
||||||
childView.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)
|
childView.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ struct AccountDetailHeaderView: View {
|
|||||||
Rectangle()
|
Rectangle()
|
||||||
.frame(height: 200)
|
.frame(height: 200)
|
||||||
.overlay {
|
.overlay {
|
||||||
headerImageView
|
headerImageView
|
||||||
}
|
}
|
||||||
accountInfoView
|
accountInfoView
|
||||||
}
|
}
|
||||||
|
@ -10,18 +10,18 @@ public struct ConversationsListView: View {
|
|||||||
@EnvironmentObject private var watcher: StreamWatcher
|
@EnvironmentObject private var watcher: StreamWatcher
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
@EnvironmentObject private var theme: Theme
|
@EnvironmentObject private var theme: Theme
|
||||||
|
|
||||||
@StateObject private var viewModel = ConversationsListViewModel()
|
@StateObject private var viewModel = ConversationsListViewModel()
|
||||||
|
|
||||||
public init() {}
|
public init() {}
|
||||||
|
|
||||||
private var conversations: [Conversation] {
|
private var conversations: [Conversation] {
|
||||||
if viewModel.isLoadingFirstPage {
|
if viewModel.isLoadingFirstPage {
|
||||||
return Conversation.placeholders()
|
return Conversation.placeholders()
|
||||||
}
|
}
|
||||||
return viewModel.conversations
|
return viewModel.conversations
|
||||||
}
|
}
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
LazyVStack {
|
LazyVStack {
|
||||||
@ -52,7 +52,7 @@ public struct ConversationsListView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if viewModel.nextPage != nil {
|
if viewModel.nextPage != nil {
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
|
@ -13,59 +13,59 @@ public extension Font {
|
|||||||
private static let footnote = onMac ? 15.0 : 13.0
|
private static let footnote = onMac ? 15.0 : 13.0
|
||||||
private static let caption = onMac ? 14.0 : 12.0
|
private static let caption = onMac ? 14.0 : 12.0
|
||||||
private static let onMac = ProcessInfo.processInfo.isiOSAppOnMac
|
private static let onMac = ProcessInfo.processInfo.isiOSAppOnMac
|
||||||
|
|
||||||
private static func customFont(size: CGFloat, relativeTo textStyle: TextStyle) -> Font {
|
private static func customFont(size: CGFloat, relativeTo textStyle: TextStyle) -> Font {
|
||||||
if let chosenFont = UserPreferences.shared.chosenFont {
|
if let chosenFont = UserPreferences.shared.chosenFont {
|
||||||
return .custom(chosenFont.fontName, size: size, relativeTo: textStyle)
|
return .custom(chosenFont.fontName, size: size, relativeTo: textStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
return onMac ? .system(size: size) : .system(textStyle)
|
return onMac ? .system(size: size) : .system(textStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func customUIFont(size: CGFloat) -> UIFont {
|
private static func customUIFont(size: CGFloat) -> UIFont {
|
||||||
if let chosenFont = UserPreferences.shared.chosenFont {
|
if let chosenFont = UserPreferences.shared.chosenFont {
|
||||||
return chosenFont.withSize(size)
|
return chosenFont.withSize(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
return .systemFont(ofSize: size)
|
return .systemFont(ofSize: size)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func userScaledFontSize(baseSize: CGFloat) -> CGFloat {
|
private static func userScaledFontSize(baseSize: CGFloat) -> CGFloat {
|
||||||
if onMac {
|
if onMac {
|
||||||
return UIFontMetrics.default.scaledValue(for: baseSize * UserPreferences.shared.fontSizeScale)
|
return UIFontMetrics.default.scaledValue(for: baseSize * UserPreferences.shared.fontSizeScale)
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseSize
|
return baseSize
|
||||||
}
|
}
|
||||||
|
|
||||||
static var scaledTitle: Font {
|
static var scaledTitle: Font {
|
||||||
customFont(size: userScaledFontSize(baseSize: title), relativeTo: .title)
|
customFont(size: userScaledFontSize(baseSize: title), relativeTo: .title)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var scaledHeadline: Font {
|
static var scaledHeadline: Font {
|
||||||
customFont(size: userScaledFontSize(baseSize: headline), relativeTo: .headline).weight(.semibold)
|
customFont(size: userScaledFontSize(baseSize: headline), relativeTo: .headline).weight(.semibold)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var scaledBody: Font {
|
static var scaledBody: Font {
|
||||||
customFont(size: userScaledFontSize(baseSize: body), relativeTo: .body)
|
customFont(size: userScaledFontSize(baseSize: body), relativeTo: .body)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var scaledBodyUIFont: UIFont {
|
static var scaledBodyUIFont: UIFont {
|
||||||
customUIFont(size: userScaledFontSize(baseSize: body))
|
customUIFont(size: userScaledFontSize(baseSize: body))
|
||||||
}
|
}
|
||||||
|
|
||||||
static var scaledCallout: Font {
|
static var scaledCallout: Font {
|
||||||
customFont(size: userScaledFontSize(baseSize: callout), relativeTo: .callout)
|
customFont(size: userScaledFontSize(baseSize: callout), relativeTo: .callout)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var scaledSubheadline: Font {
|
static var scaledSubheadline: Font {
|
||||||
customFont(size: userScaledFontSize(baseSize: subheadline), relativeTo: .subheadline)
|
customFont(size: userScaledFontSize(baseSize: subheadline), relativeTo: .subheadline)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var scaledFootnote: Font {
|
static var scaledFootnote: Font {
|
||||||
customFont(size: userScaledFontSize(baseSize: footnote), relativeTo: .footnote)
|
customFont(size: userScaledFontSize(baseSize: footnote), relativeTo: .footnote)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var scaledCaption: Font {
|
static var scaledCaption: Font {
|
||||||
customFont(size: userScaledFontSize(baseSize: caption), relativeTo: .caption)
|
customFont(size: userScaledFontSize(baseSize: caption), relativeTo: .caption)
|
||||||
}
|
}
|
||||||
|
@ -2,36 +2,36 @@ import Env
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
public struct FontPicker: UIViewControllerRepresentable {
|
public struct FontPicker: UIViewControllerRepresentable {
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
|
|
||||||
public class Coordinator: NSObject, UIFontPickerViewControllerDelegate {
|
public class Coordinator: NSObject, UIFontPickerViewControllerDelegate {
|
||||||
private let dismiss: DismissAction
|
private let dismiss: DismissAction
|
||||||
|
|
||||||
public init(dismiss: DismissAction) {
|
public init(dismiss: DismissAction) {
|
||||||
self.dismiss = dismiss
|
self.dismiss = dismiss
|
||||||
}
|
|
||||||
|
|
||||||
public func fontPickerViewControllerDidCancel(_ viewController: UIFontPickerViewController) {
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
|
|
||||||
public func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
|
|
||||||
UserPreferences.shared.chosenFont = UIFont(descriptor: viewController.selectedFontDescriptor!, size: 0)
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public init() {}
|
public func fontPickerViewControllerDidCancel(_: UIFontPickerViewController) {
|
||||||
|
dismiss()
|
||||||
public func makeCoordinator() -> Coordinator {
|
|
||||||
Coordinator(dismiss: dismiss)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func makeUIViewController(context: Context) -> UIFontPickerViewController {
|
public func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
|
||||||
let controller = UIFontPickerViewController()
|
UserPreferences.shared.chosenFont = UIFont(descriptor: viewController.selectedFontDescriptor!, size: 0)
|
||||||
controller.delegate = context.coordinator
|
dismiss()
|
||||||
return controller
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public func updateUIViewController(_ viewController: UIFontPickerViewController, context: Context) {}
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
public func makeCoordinator() -> Coordinator {
|
||||||
|
Coordinator(dismiss: dismiss)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func makeUIViewController(context: Context) -> UIFontPickerViewController {
|
||||||
|
let controller = UIFontPickerViewController()
|
||||||
|
controller.delegate = context.coordinator
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateUIViewController(_: UIFontPickerViewController, context _: Context) {}
|
||||||
}
|
}
|
||||||
|
@ -8,21 +8,21 @@ public class Theme: ObservableObject {
|
|||||||
case selectedSet, selectedScheme
|
case selectedSet, selectedScheme
|
||||||
case followSystemColorSchme
|
case followSystemColorSchme
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FontState: Int, CaseIterable {
|
public enum FontState: Int, CaseIterable {
|
||||||
case system
|
case system
|
||||||
case custom
|
case custom
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
public var title: LocalizedStringKey {
|
public var title: LocalizedStringKey {
|
||||||
switch self {
|
switch self {
|
||||||
case .system:
|
case .system:
|
||||||
return "settings.display.font.system"
|
return "settings.display.font.system"
|
||||||
case .custom:
|
case .custom:
|
||||||
return "settings.display.font.custom"
|
return "settings.display.font.custom"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum AvatarPosition: String, CaseIterable {
|
public enum AvatarPosition: String, CaseIterable {
|
||||||
case leading, top
|
case leading, top
|
||||||
|
@ -48,7 +48,7 @@ struct ThemeApplier: ViewModifier {
|
|||||||
setBarsColor(newValue)
|
setBarsColor(newValue)
|
||||||
}
|
}
|
||||||
.onChange(of: theme.selectedScheme) { newValue in
|
.onChange(of: theme.selectedScheme) { newValue in
|
||||||
setWindowUserInterfaceStyle(from: newValue)
|
setWindowUserInterfaceStyle(from: newValue)
|
||||||
}
|
}
|
||||||
.onChange(of: colorScheme) { newColorScheme in
|
.onChange(of: colorScheme) { newColorScheme in
|
||||||
if theme.followSystemColorScheme,
|
if theme.followSystemColorScheme,
|
||||||
@ -64,8 +64,8 @@ struct ThemeApplier: ViewModifier {
|
|||||||
#if canImport(UIKit)
|
#if canImport(UIKit)
|
||||||
private func setWindowUserInterfaceStyle(from colorScheme: ColorScheme) {
|
private func setWindowUserInterfaceStyle(from colorScheme: ColorScheme) {
|
||||||
guard !theme.followSystemColorScheme else {
|
guard !theme.followSystemColorScheme else {
|
||||||
setWindowUserInterfaceStyle(.unspecified)
|
setWindowUserInterfaceStyle(.unspecified)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch colorScheme {
|
switch colorScheme {
|
||||||
case .dark:
|
case .dark:
|
||||||
@ -74,14 +74,14 @@ struct ThemeApplier: ViewModifier {
|
|||||||
setWindowUserInterfaceStyle(.light)
|
setWindowUserInterfaceStyle(.light)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setWindowUserInterfaceStyle(_ userInterfaceStyle: UIUserInterfaceStyle) {
|
private func setWindowUserInterfaceStyle(_ userInterfaceStyle: UIUserInterfaceStyle) {
|
||||||
allWindows()
|
allWindows()
|
||||||
.forEach {
|
.forEach {
|
||||||
$0.overrideUserInterfaceStyle = userInterfaceStyle
|
$0.overrideUserInterfaceStyle = userInterfaceStyle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setWindowTint(_ color: Color) {
|
private func setWindowTint(_ color: Color) {
|
||||||
allWindows()
|
allWindows()
|
||||||
.forEach {
|
.forEach {
|
||||||
|
@ -5,8 +5,8 @@ private struct SecondaryColumnKey: EnvironmentKey {
|
|||||||
static let defaultValue = false
|
static let defaultValue = false
|
||||||
}
|
}
|
||||||
|
|
||||||
extension EnvironmentValues {
|
public extension EnvironmentValues {
|
||||||
public var isSecondaryColumn: Bool {
|
var isSecondaryColumn: Bool {
|
||||||
get { self[SecondaryColumnKey.self] }
|
get { self[SecondaryColumnKey.self] }
|
||||||
set { self[SecondaryColumnKey.self] = newValue }
|
set { self[SecondaryColumnKey.self] = newValue }
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class QuickLook: ObservableObject {
|
|||||||
paths.append(path)
|
paths.append(path)
|
||||||
}
|
}
|
||||||
return paths.sorted { url1, url2 in
|
return paths.sorted { url1, url2 in
|
||||||
return pathOrderMap[url1.lastPathComponent] ?? 0 < pathOrderMap[url2.lastPathComponent] ?? 0
|
pathOrderMap[url1.lastPathComponent] ?? 0 < pathOrderMap[url2.lastPathComponent] ?? 0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
withTransaction(transaction) {
|
withTransaction(transaction) {
|
||||||
|
@ -26,7 +26,7 @@ public class UserPreferences: ObservableObject {
|
|||||||
@AppStorage("app_default_post_visibility") public var appDefaultPostVisibility: Models.Visibility = .pub
|
@AppStorage("app_default_post_visibility") public var appDefaultPostVisibility: Models.Visibility = .pub
|
||||||
@AppStorage("app_default_posts_sensitive") public var appDefaultPostsSensitive = false
|
@AppStorage("app_default_posts_sensitive") public var appDefaultPostsSensitive = false
|
||||||
@AppStorage("autoplay_video") public var autoPlayVideo = true
|
@AppStorage("autoplay_video") public var autoPlayVideo = true
|
||||||
@AppStorage("chosen_font") public private(set) var chosenFontData: Data?
|
@AppStorage("chosen_font") public private(set) var chosenFontData: Data?
|
||||||
|
|
||||||
public var postVisibility: Models.Visibility {
|
public var postVisibility: Models.Visibility {
|
||||||
if useInstanceContentSettings {
|
if useInstanceContentSettings {
|
||||||
@ -68,23 +68,24 @@ public class UserPreferences: ObservableObject {
|
|||||||
Self.sharedDefault?.set(newValue, forKey: "push_notifications_count")
|
Self.sharedDefault?.set(newValue, forKey: "push_notifications_count")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var chosenFont: UIFont? {
|
public var chosenFont: UIFont? {
|
||||||
get {
|
get {
|
||||||
guard let chosenFontData,
|
guard let chosenFontData,
|
||||||
let font = try? NSKeyedUnarchiver.unarchivedObject(ofClass: UIFont.self, from: chosenFontData) else { return nil }
|
let font = try? NSKeyedUnarchiver.unarchivedObject(ofClass: UIFont.self, from: chosenFontData) else { return nil }
|
||||||
|
|
||||||
return font
|
return font
|
||||||
}
|
|
||||||
set {
|
|
||||||
if let font = newValue,
|
|
||||||
let data = try? NSKeyedArchiver.archivedData(withRootObject: font, requiringSecureCoding: false) {
|
|
||||||
chosenFontData = data
|
|
||||||
} else {
|
|
||||||
chosenFontData = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
set {
|
||||||
|
if let font = newValue,
|
||||||
|
let data = try? NSKeyedArchiver.archivedData(withRootObject: font, requiringSecureCoding: false)
|
||||||
|
{
|
||||||
|
chosenFontData = data
|
||||||
|
} else {
|
||||||
|
chosenFontData = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Published public var serverPreferences: ServerPreferences?
|
@Published public var serverPreferences: ServerPreferences?
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ public struct HTMLString: Decodable, Equatable, Hashable {
|
|||||||
// other characters the markdown parser used picks up
|
// other characters the markdown parser used picks up
|
||||||
// when it renders to attributed text
|
// when it renders to attributed text
|
||||||
if let regex = try? NSRegularExpression(pattern: "([\\_\\`\\[\\\\])", options: .caseInsensitive) {
|
if let regex = try? NSRegularExpression(pattern: "([\\_\\`\\[\\\\])", options: .caseInsensitive) {
|
||||||
htmlValue = regex.stringByReplacingMatches(in: htmlValue, options: [], range: NSRange(location: 0, length: htmlValue.count), withTemplate: "\\\\$1")
|
htmlValue = regex.stringByReplacingMatches(in: htmlValue, options: [], range: NSRange(location: 0, length: htmlValue.count), withTemplate: "\\\\$1")
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
asMarkdown = try HTMLParser().parse(html: htmlValue)
|
asMarkdown = try HTMLParser().parse(html: htmlValue)
|
||||||
.toMarkdown()
|
.toMarkdown()
|
||||||
|
@ -32,8 +32,8 @@ struct NotificationRowView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.alignmentGuide(.listRowSeparatorLeading) { viewDimensions in
|
.alignmentGuide(.listRowSeparatorLeading) { _ in
|
||||||
return -100
|
-100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
import DesignSystem
|
||||||
import Models
|
import Models
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import DesignSystem
|
|
||||||
|
|
||||||
extension Models.Notification.NotificationType {
|
extension Models.Notification.NotificationType {
|
||||||
func label(count: Int) -> LocalizedStringKey {
|
func label(count: Int) -> LocalizedStringKey {
|
||||||
@ -42,7 +42,7 @@ extension Models.Notification.NotificationType {
|
|||||||
return "pencil.line"
|
return "pencil.line"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func tintColor() -> Color {
|
func tintColor() -> Color {
|
||||||
switch self {
|
switch self {
|
||||||
case .status, .mention, .update, .poll:
|
case .status, .mention, .update, .poll:
|
||||||
|
@ -103,7 +103,7 @@ public struct NotificationsListView: View {
|
|||||||
bottom: 12,
|
bottom: 12,
|
||||||
trailing: .layoutPadding))
|
trailing: .layoutPadding))
|
||||||
.listRowBackground(notification.type == .mention && lockedType != .mention ?
|
.listRowBackground(notification.type == .mention && lockedType != .mention ?
|
||||||
theme.secondaryBackgroundColor : theme.primaryBackgroundColor)
|
theme.secondaryBackgroundColor : theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,9 +144,9 @@ public struct NotificationsListView: View {
|
|||||||
trailing: .layoutPadding))
|
trailing: .layoutPadding))
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var topPaddingView: some View {
|
private var topPaddingView: some View {
|
||||||
HStack { }
|
HStack {}
|
||||||
.listRowBackground(Color.clear)
|
.listRowBackground(Color.clear)
|
||||||
.listRowSeparator(.hidden)
|
.listRowSeparator(.hidden)
|
||||||
.listRowInsets(.init())
|
.listRowInsets(.init())
|
||||||
|
@ -14,15 +14,15 @@ public struct StatusDetailView: View {
|
|||||||
@Environment(\.openURL) private var openURL
|
@Environment(\.openURL) private var openURL
|
||||||
@StateObject private var viewModel: StatusDetailViewModel
|
@StateObject private var viewModel: StatusDetailViewModel
|
||||||
@State private var isLoaded: Bool = false
|
@State private var isLoaded: Bool = false
|
||||||
|
|
||||||
public init(statusId: String) {
|
public init(statusId: String) {
|
||||||
_viewModel = StateObject(wrappedValue: .init(statusId: statusId))
|
_viewModel = StateObject(wrappedValue: .init(statusId: statusId))
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(remoteStatusURL: URL) {
|
public init(remoteStatusURL: URL) {
|
||||||
_viewModel = StateObject(wrappedValue: .init(remoteStatusURL: remoteStatusURL))
|
_viewModel = StateObject(wrappedValue: .init(remoteStatusURL: remoteStatusURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
ScrollViewReader { proxy in
|
ScrollViewReader { proxy in
|
||||||
ZStack {
|
ZStack {
|
||||||
@ -51,8 +51,8 @@ public struct StatusDetailView: View {
|
|||||||
StatusRowView(viewModel: .init(status: status,
|
StatusRowView(viewModel: .init(status: status,
|
||||||
isCompact: false,
|
isCompact: false,
|
||||||
isFocused: true))
|
isFocused: true))
|
||||||
.padding(.horizontal, .layoutPadding)
|
.padding(.horizontal, .layoutPadding)
|
||||||
.id(status.id)
|
.id(status.id)
|
||||||
Divider()
|
Divider()
|
||||||
.padding(.bottom, .dividerPadding * 2)
|
.padding(.bottom, .dividerPadding * 2)
|
||||||
if !context.descendants.isEmpty {
|
if !context.descendants.isEmpty {
|
||||||
@ -63,7 +63,7 @@ public struct StatusDetailView: View {
|
|||||||
.padding(.vertical, .dividerPadding)
|
.padding(.vertical, .dividerPadding)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case .error:
|
case .error:
|
||||||
ErrorView(title: "status.error.title",
|
ErrorView(title: "status.error.title",
|
||||||
message: "status.error.message",
|
message: "status.error.message",
|
||||||
|
@ -78,7 +78,7 @@ struct StatusEditorAccessoryView: View {
|
|||||||
Image(systemName: "globe")
|
Image(systemName: "globe")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if preferences.isOpenAIEnabled {
|
if preferences.isOpenAIEnabled {
|
||||||
AIMenu.disabled(!viewModel.canPost)
|
AIMenu.disabled(!viewModel.canPost)
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ struct StatusEditorAccessoryView: View {
|
|||||||
Text(isoCode.uppercased())
|
Text(isoCode.uppercased())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var AIMenu: some View {
|
private var AIMenu: some View {
|
||||||
Menu {
|
Menu {
|
||||||
ForEach(StatusEditorAIPrompts.allCases, id: \.self) { prompt in
|
ForEach(StatusEditorAIPrompts.allCases, id: \.self) { prompt in
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import AVKit
|
import AVKit
|
||||||
import SwiftUI
|
|
||||||
import Env
|
import Env
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
class VideoPlayerViewModel: ObservableObject {
|
class VideoPlayerViewModel: ObservableObject {
|
||||||
@Published var player: AVPlayer?
|
@Published var player: AVPlayer?
|
||||||
@ -41,7 +41,7 @@ class VideoPlayerViewModel: ObservableObject {
|
|||||||
struct VideoPlayerView: View {
|
struct VideoPlayerView: View {
|
||||||
@Environment(\.scenePhase) private var scenePhase
|
@Environment(\.scenePhase) private var scenePhase
|
||||||
@EnvironmentObject private var preferences: UserPreferences
|
@EnvironmentObject private var preferences: UserPreferences
|
||||||
|
|
||||||
@StateObject var viewModel: VideoPlayerViewModel
|
@StateObject var viewModel: VideoPlayerViewModel
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
@ -87,7 +87,7 @@ struct StatusActionsView: View {
|
|||||||
}
|
}
|
||||||
.buttonStyle(.borderless)
|
.buttonStyle(.borderless)
|
||||||
.disabled(action == .boost &&
|
.disabled(action == .boost &&
|
||||||
(viewModel.status.visibility == .direct || viewModel.status.visibility == .priv))
|
(viewModel.status.visibility == .direct || viewModel.status.visibility == .priv))
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,8 @@ struct StatusRowContextMenu: View {
|
|||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
if let statusLanguage = viewModel.status.language,
|
if let statusLanguage = viewModel.status.language,
|
||||||
let lanugageName = Locale.current.localizedString(forLanguageCode: statusLanguage) {
|
let lanugageName = Locale.current.localizedString(forLanguageCode: statusLanguage)
|
||||||
|
{
|
||||||
Label("status.action.translate-from-\(lanugageName)", systemImage: "captions.bubble")
|
Label("status.action.translate-from-\(lanugageName)", systemImage: "captions.bubble")
|
||||||
} else {
|
} else {
|
||||||
Label("status.action.translate", systemImage: "captions.bubble")
|
Label("status.action.translate", systemImage: "captions.bubble")
|
||||||
|
@ -317,7 +317,8 @@ public struct StatusRowView: View {
|
|||||||
ProgressView()
|
ProgressView()
|
||||||
} else {
|
} else {
|
||||||
if let statusLanguage = status.language,
|
if let statusLanguage = status.language,
|
||||||
let lanugageName = Locale.current.localizedString(forLanguageCode: statusLanguage) {
|
let lanugageName = Locale.current.localizedString(forLanguageCode: statusLanguage)
|
||||||
|
{
|
||||||
Text("status.action.translate-from-\(lanugageName)")
|
Text("status.action.translate-from-\(lanugageName)")
|
||||||
} else {
|
} else {
|
||||||
Text("status.action.translate")
|
Text("status.action.translate")
|
||||||
@ -389,7 +390,7 @@ public struct StatusRowView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var remoteContentLoadingView: some View {
|
private var remoteContentLoadingView: some View {
|
||||||
ZStack(alignment: .center) {
|
ZStack(alignment: .center) {
|
||||||
VStack {
|
VStack {
|
||||||
|
@ -71,7 +71,7 @@ public class StatusRowViewModel: ObservableObject {
|
|||||||
routerPath.navigate(to: .statusDetail(id: status.reblog?.id ?? status.id))
|
routerPath.navigate(to: .statusDetail(id: status.reblog?.id ?? status.id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func navigateToAccountDetail(account: Account, routerPath: RouterPath) {
|
func navigateToAccountDetail(account: Account, routerPath: RouterPath) {
|
||||||
if isRemote, let url = account.url {
|
if isRemote, let url = account.url {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
@ -85,7 +85,7 @@ public class StatusRowViewModel: ObservableObject {
|
|||||||
routerPath.navigate(to: .accountDetailWithAccount(account: account))
|
routerPath.navigate(to: .accountDetailWithAccount(account: account))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func navigateToMention(mention: Mention, routerPath: RouterPath) {
|
func navigateToMention(mention: Mention, routerPath: RouterPath) {
|
||||||
if isRemote {
|
if isRemote {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user