2022-11-29 11:46:02 +01:00
|
|
|
import Account
|
2023-01-17 11:36:01 +01:00
|
|
|
import AppAccount
|
2023-01-25 13:02:28 +01:00
|
|
|
import Conversations
|
2022-12-20 09:37:07 +01:00
|
|
|
import DesignSystem
|
2023-01-17 11:36:01 +01:00
|
|
|
import Env
|
2023-03-13 13:38:28 +01:00
|
|
|
import Explore
|
2023-02-21 07:23:42 +01:00
|
|
|
import LinkPresentation
|
2023-01-02 19:23:44 +01:00
|
|
|
import Lists
|
2023-11-01 18:58:44 +01:00
|
|
|
import MediaUI
|
2023-02-21 07:23:42 +01:00
|
|
|
import Models
|
2024-01-06 19:27:26 +01:00
|
|
|
import StatusKit
|
2023-01-17 11:36:01 +01:00
|
|
|
import SwiftUI
|
|
|
|
import Timeline
|
2022-11-29 11:46:02 +01:00
|
|
|
|
2023-01-17 07:39:13 +01:00
|
|
|
@MainActor
|
2022-11-29 11:46:02 +01:00
|
|
|
extension View {
|
2023-01-17 15:14:50 +01:00
|
|
|
func withAppRouter() -> some View {
|
2023-02-21 18:52:30 +01:00
|
|
|
navigationDestination(for: RouterDestination.self) { destination in
|
2022-11-29 11:46:02 +01:00
|
|
|
switch destination {
|
|
|
|
case let .accountDetail(id):
|
2023-10-05 08:22:45 +02:00
|
|
|
AccountDetailView(accountId: id, scrollToTopSignal: .constant(0))
|
2022-12-17 13:37:46 +01:00
|
|
|
case let .accountDetailWithAccount(account):
|
2023-10-05 08:22:45 +02:00
|
|
|
AccountDetailView(account: account, scrollToTopSignal: .constant(0))
|
2023-01-25 21:18:34 +01:00
|
|
|
case let .accountSettingsWithAccount(account, appAccount):
|
|
|
|
AccountSettingsView(account: account, appAccount: appAccount)
|
2022-11-29 11:46:02 +01:00
|
|
|
case let .statusDetail(id):
|
|
|
|
StatusDetailView(statusId: id)
|
2023-02-10 18:21:05 +01:00
|
|
|
case let .statusDetailWithStatus(status):
|
|
|
|
StatusDetailView(status: status)
|
2023-01-06 12:14:05 +01:00
|
|
|
case let .remoteStatusDetail(url):
|
|
|
|
StatusDetailView(remoteStatusURL: url)
|
2023-02-10 18:21:05 +01:00
|
|
|
case let .conversationDetail(conversation):
|
|
|
|
ConversationDetailView(conversation: conversation)
|
2022-12-21 20:26:38 +01:00
|
|
|
case let .hashTag(tag, accountId):
|
2023-10-01 09:37:09 +02:00
|
|
|
TimelineView(timeline: .constant(.hashtag(tag: tag, accountId: accountId)),
|
2023-12-30 14:54:09 +01:00
|
|
|
pinnedFilters: .constant([]),
|
2023-09-22 19:33:53 +02:00
|
|
|
selectedTagGroup: .constant(nil),
|
|
|
|
scrollToTopSignal: .constant(0),
|
|
|
|
canFilterTimeline: false)
|
2023-01-02 19:23:44 +01:00
|
|
|
case let .list(list):
|
2023-10-01 09:37:09 +02:00
|
|
|
TimelineView(timeline: .constant(.list(list: list)),
|
2023-12-30 14:54:09 +01:00
|
|
|
pinnedFilters: .constant([]),
|
2023-09-22 19:33:53 +02:00
|
|
|
selectedTagGroup: .constant(nil),
|
|
|
|
scrollToTopSignal: .constant(0),
|
|
|
|
canFilterTimeline: false)
|
2022-12-23 18:47:19 +01:00
|
|
|
case let .following(id):
|
2022-12-28 10:08:41 +01:00
|
|
|
AccountsListView(mode: .following(accountId: id))
|
2022-12-23 18:47:19 +01:00
|
|
|
case let .followers(id):
|
2022-12-24 13:41:25 +01:00
|
|
|
AccountsListView(mode: .followers(accountId: id))
|
2023-01-24 06:35:43 +01:00
|
|
|
case let .favoritedBy(id):
|
|
|
|
AccountsListView(mode: .favoritedBy(statusId: id))
|
2022-12-24 13:41:25 +01:00
|
|
|
case let .rebloggedBy(id):
|
|
|
|
AccountsListView(mode: .rebloggedBy(statusId: id))
|
2023-02-13 07:00:42 +01:00
|
|
|
case let .accountsList(accounts):
|
|
|
|
AccountsListView(mode: .accountsList(accounts: accounts))
|
2023-03-02 20:15:07 +01:00
|
|
|
case .trendingTimeline:
|
2023-09-22 19:33:53 +02:00
|
|
|
TimelineView(timeline: .constant(.trending),
|
2023-12-30 14:54:09 +01:00
|
|
|
pinnedFilters: .constant([]),
|
2023-09-22 19:33:53 +02:00
|
|
|
selectedTagGroup: .constant(nil),
|
|
|
|
scrollToTopSignal: .constant(0),
|
|
|
|
canFilterTimeline: false)
|
2023-09-27 08:38:17 +02:00
|
|
|
case let .trendingLinks(cards):
|
|
|
|
CardsListView(cards: cards)
|
2023-03-02 20:15:07 +01:00
|
|
|
case let .tagsList(tags):
|
|
|
|
TagsListView(tags: tags)
|
2022-11-29 11:46:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-02-21 07:23:42 +01:00
|
|
|
|
2023-02-21 18:52:30 +01:00
|
|
|
func withSheetDestinations(sheetDestinations: Binding<SheetDestination?>) -> some View {
|
2023-01-17 11:36:01 +01:00
|
|
|
sheet(item: sheetDestinations) { destination in
|
2024-01-11 20:02:48 +01:00
|
|
|
switch destination {
|
|
|
|
case let .replyToStatusEditor(status):
|
|
|
|
StatusEditor.MainView(mode: .replyTo(status: status))
|
|
|
|
.withEnvironments()
|
|
|
|
case let .newStatusEditor(visibility):
|
|
|
|
StatusEditor.MainView(mode: .new(visibility: visibility))
|
|
|
|
.withEnvironments()
|
|
|
|
case let .editStatusEditor(status):
|
|
|
|
StatusEditor.MainView(mode: .edit(status: status))
|
|
|
|
.withEnvironments()
|
|
|
|
case let .quoteStatusEditor(status):
|
|
|
|
StatusEditor.MainView(mode: .quote(status: status))
|
|
|
|
.withEnvironments()
|
|
|
|
case let .mentionStatusEditor(account, visibility):
|
|
|
|
StatusEditor.MainView(mode: .mention(account: account, visibility: visibility))
|
|
|
|
.withEnvironments()
|
|
|
|
case .listCreate:
|
|
|
|
ListCreateView()
|
|
|
|
.withEnvironments()
|
|
|
|
case let .listEdit(list):
|
|
|
|
ListEditView(list: list)
|
|
|
|
.withEnvironments()
|
|
|
|
case let .listAddAccount(account):
|
|
|
|
ListAddAccountView(account: account)
|
|
|
|
.withEnvironments()
|
|
|
|
case .addAccount:
|
|
|
|
AddAccountView()
|
|
|
|
.withEnvironments()
|
|
|
|
case .addRemoteLocalTimeline:
|
|
|
|
AddRemoteTimelineView()
|
|
|
|
.withEnvironments()
|
|
|
|
case .addTagGroup:
|
|
|
|
EditTagGroupView()
|
|
|
|
.withEnvironments()
|
|
|
|
case let .statusEditHistory(status):
|
|
|
|
StatusEditHistoryView(statusId: status)
|
|
|
|
.withEnvironments()
|
|
|
|
case .settings:
|
|
|
|
SettingsTabs(popToRootTab: .constant(.settings), isModal: true)
|
|
|
|
.withEnvironments()
|
|
|
|
.preferredColorScheme(Theme.shared.selectedScheme == .dark ? .dark : .light)
|
|
|
|
case .accountPushNotficationsSettings:
|
|
|
|
if let subscription = PushNotificationsService.shared.subscriptions.first(where: { $0.account.token == AppAccountsManager.shared.currentAccount.oauthToken }) {
|
|
|
|
NavigationSheet { PushNotificationsView(subscription: subscription) }
|
|
|
|
.withEnvironments()
|
|
|
|
} else {
|
|
|
|
EmptyView()
|
2023-01-27 12:18:17 +01:00
|
|
|
}
|
2024-01-11 20:02:48 +01:00
|
|
|
case .about:
|
|
|
|
NavigationSheet { AboutView() }
|
|
|
|
.withEnvironments()
|
|
|
|
case .support:
|
|
|
|
NavigationSheet { SupportAppView() }
|
|
|
|
.withEnvironments()
|
|
|
|
case let .report(status):
|
|
|
|
ReportView(status: status)
|
|
|
|
.withEnvironments()
|
|
|
|
case let .shareImage(image, status):
|
|
|
|
ActivityView(image: image, status: status)
|
|
|
|
.withEnvironments()
|
|
|
|
case let .editTagGroup(tagGroup, onSaved):
|
|
|
|
EditTagGroupView(tagGroup: tagGroup, onSaved: onSaved)
|
|
|
|
.withEnvironments()
|
|
|
|
case .timelineContentFilter:
|
|
|
|
NavigationSheet { TimelineContentFilterView() }
|
|
|
|
.presentationDetents([.medium])
|
2024-01-21 11:22:07 +01:00
|
|
|
.presentationBackground(.thinMaterial)
|
2024-01-11 20:02:48 +01:00
|
|
|
.withEnvironments()
|
2022-12-20 09:37:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-02-21 07:23:42 +01:00
|
|
|
|
2023-01-17 07:39:13 +01:00
|
|
|
func withEnvironments() -> some View {
|
2023-09-18 07:01:23 +02:00
|
|
|
environment(CurrentAccount.shared)
|
2023-09-19 09:18:20 +02:00
|
|
|
.environment(UserPreferences.shared)
|
2023-09-18 07:01:23 +02:00
|
|
|
.environment(CurrentInstance.shared)
|
2023-09-18 21:03:52 +02:00
|
|
|
.environment(Theme.shared)
|
2023-09-18 07:01:23 +02:00
|
|
|
.environment(AppAccountsManager.shared)
|
|
|
|
.environment(PushNotificationsService.shared)
|
|
|
|
.environment(AppAccountsManager.shared.currentClient)
|
2023-10-26 06:23:00 +02:00
|
|
|
.environment(QuickLook.shared)
|
2023-01-17 07:39:13 +01:00
|
|
|
}
|
2023-10-01 09:37:09 +02:00
|
|
|
|
2023-09-22 09:31:35 +02:00
|
|
|
func withModelContainer() -> some View {
|
|
|
|
modelContainer(for: [
|
|
|
|
Draft.self,
|
2023-09-22 12:49:25 +02:00
|
|
|
LocalTimeline.self,
|
2023-10-01 09:37:09 +02:00
|
|
|
TagGroup.self,
|
2024-01-05 10:57:26 +01:00
|
|
|
RecentTag.self,
|
2023-09-22 09:31:35 +02:00
|
|
|
])
|
|
|
|
}
|
2022-11-29 11:46:02 +01:00
|
|
|
}
|
2023-02-19 15:29:07 +01:00
|
|
|
|
|
|
|
struct ActivityView: UIViewControllerRepresentable {
|
|
|
|
let image: UIImage
|
|
|
|
let status: Status
|
2023-02-21 07:23:42 +01:00
|
|
|
|
2023-02-19 15:29:07 +01:00
|
|
|
class LinkDelegate: NSObject, UIActivityItemSource {
|
|
|
|
let image: UIImage
|
|
|
|
let status: Status
|
2023-02-21 07:23:42 +01:00
|
|
|
|
2023-02-19 15:29:07 +01:00
|
|
|
init(image: UIImage, status: Status) {
|
|
|
|
self.image = image
|
|
|
|
self.status = status
|
|
|
|
}
|
2023-02-21 07:23:42 +01:00
|
|
|
|
|
|
|
func activityViewControllerLinkMetadata(_: UIActivityViewController) -> LPLinkMetadata? {
|
2023-02-19 15:29:07 +01:00
|
|
|
let imageProvider = NSItemProvider(object: image)
|
|
|
|
let metadata = LPLinkMetadata()
|
|
|
|
metadata.imageProvider = imageProvider
|
|
|
|
metadata.title = status.reblog?.content.asRawText ?? status.content.asRawText
|
|
|
|
return metadata
|
|
|
|
}
|
2023-02-21 07:23:42 +01:00
|
|
|
|
|
|
|
func activityViewControllerPlaceholderItem(_: UIActivityViewController) -> Any {
|
2023-02-19 15:29:07 +01:00
|
|
|
image
|
|
|
|
}
|
2023-02-21 07:23:42 +01:00
|
|
|
|
|
|
|
func activityViewController(_: UIActivityViewController,
|
|
|
|
itemForActivityType _: UIActivity.ActivityType?) -> Any?
|
|
|
|
{
|
2023-02-19 15:29:07 +01:00
|
|
|
nil
|
|
|
|
}
|
|
|
|
}
|
2023-02-21 07:23:42 +01:00
|
|
|
|
|
|
|
func makeUIViewController(context _: UIViewControllerRepresentableContext<ActivityView>) -> UIActivityViewController {
|
2023-09-16 14:15:03 +02:00
|
|
|
UIActivityViewController(activityItems: [image, LinkDelegate(image: image, status: status)],
|
|
|
|
applicationActivities: nil)
|
2023-02-19 15:29:07 +01:00
|
|
|
}
|
2023-02-21 07:23:42 +01:00
|
|
|
|
|
|
|
func updateUIViewController(_: UIActivityViewController, context _: UIViewControllerRepresentableContext<ActivityView>) {}
|
2023-02-19 15:29:07 +01:00
|
|
|
}
|
2023-10-23 19:12:25 +02:00
|
|
|
|
|
|
|
extension URL: Identifiable {
|
|
|
|
public var id: String {
|
|
|
|
absoluteString
|
|
|
|
}
|
|
|
|
}
|