Post menu and image share

This commit is contained in:
Lumaa 2024-01-21 16:34:26 +01:00
parent e83984aa62
commit b40eb2cf92
5 changed files with 163 additions and 10 deletions

View File

@ -0,0 +1,17 @@
//Made by Lumaa
import Foundation
import SwiftUI
import UIKit
/// Share sheet
struct ShareSheet: UIViewControllerRepresentable {
let image: UIImage
func makeUIViewController(context: Context) -> UIActivityViewController {
UIActivityViewController(activityItems: [image], applicationActivities: nil)
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
}
}

View File

@ -5,11 +5,13 @@ import SwiftUI
struct CompactPostView: View {
@Environment(AccountManager.self) private var accountManager: AccountManager
@State var status: Status
@State var reblogStatus: Status?
@ObservedObject var navigator: Navigator
var pinned: Bool = false
var detailed: Bool = false
var quoted: Bool = false
var imaging: Bool = false
@State private var preferences: UserPreferences = .defaultPreferences
@State private var initialLike: Bool = false
@ -23,13 +25,9 @@ struct CompactPostView: View {
var body: some View {
VStack {
statusPost(status.reblog ?? status)
.contentShape(Rectangle())
.onTapGesture {
navigator.navigate(to: .post(status: status))
}
statusPost(reblogStatus ?? status)
if !quoted {
if !quoted && !imaging {
Rectangle()
.fill(Color.gray.opacity(0.2))
.frame(width: .infinity, height: 1)
@ -49,7 +47,7 @@ struct CompactPostView: View {
await loadEmbeddedStatus(status: status)
if let client = accountManager.getClient() {
if let newStatus: Status = try? await client.get(endpoint: Statuses.status(id: status.id)) {
if let newStatus: Status = try? await client.get(endpoint: Statuses.status(id: status.reblog?.id ?? status.id)) {
status = newStatus
}
}
@ -57,7 +55,7 @@ struct CompactPostView: View {
}
@ViewBuilder
func statusPost(_ status: AnyStatus) -> some View {
func statusPost(_ status: Status) -> some View {
HStack(alignment: .top, spacing: 0) {
// MARK: Profile picture
if status.repliesCount > 0 && preferences.experimental.replySymbol {
@ -121,6 +119,10 @@ struct CompactPostView: View {
.lineLimit(quoted ? 3 : nil)
.fixedSize(horizontal: false, vertical: true)
.font(quoted ? .caption : .callout)
.contentShape(Rectangle())
.onTapGesture {
navigator.navigate(to: .post(status: status))
}
}
if status.card != nil && status.mediaAttachments.isEmpty && !hasQuote {
@ -153,13 +155,19 @@ struct CompactPostView: View {
}
//MARK: Action buttons
if !quoted {
if !quoted && !imaging {
PostInteractor(status: reblogStatus ?? status, isLiked: $isLiked, isReposted: $isReposted, isBookmarked: $isBookmarked)
}
// MARK: Status stats
stats.padding(.top, 5)
}
if !imaging {
PostMenu(status: status)
.offset(x: -10, y: 10)
.contentShape(Rectangle())
}
}
}

View File

@ -0,0 +1,70 @@
//Made by Lumaa
import SwiftUI
struct PostMenu: View {
@Environment(\.colorScheme) private var colorScheme
@Environment(Navigator.self) private var navigator
@Environment(\.displayScale) private var displayScale
var status: Status
var body: some View {
Menu {
Button(role: .destructive) {
print("Delete")
} label: {
Label("status.menu.delete", systemImage: "trash")
}
Button {
print("Edit")
} label: {
Label("status.menu.edit", systemImage: "pencil.and.scribble")
}
Divider()
Menu {
ShareLink(item: URL(string: status.url ?? "https://joinmastodon.org/")!) {
Label("status.menu.share-link", systemImage: "square.and.arrow.up")
}
Button {
Task {
await createImage()
}
} label: {
Label("status.menu.share-image", systemImage: "photo")
}
} label: {
Label("status.menu.share", systemImage: "paperplane")
}
} label: {
Image(systemName: "ellipsis")
.foregroundStyle(Color.white.opacity(0.3))
.font(.body)
}
}
@MainActor
private func createImage() {
let view = HStack {
CompactPostView(status: status, navigator: Navigator(), imaging: true)
.padding(15)
.background(Color.appBackground)
}
.environment(\.colorScheme, colorScheme == .dark ? .dark : .light)
.environment(AccountManager())
.environment(Navigator())
.environment(AppDelegate())
let render = ImageRenderer(content: view)
render.scale = displayScale
render.isOpaque = false
if let image = render.uiImage {
navigator.presentedSheet = .shareImage(image: image)
}
}
}

View File

@ -40,6 +40,7 @@ public enum SheetDestination: Identifiable {
case mastodonLogin(logged: Binding<Bool>)
case post(content: String = "", replyId: String? = nil)
case safari(url: URL)
case shareImage(image: UIImage)
public var id: String {
switch self {
@ -51,6 +52,8 @@ public enum SheetDestination: Identifiable {
return "post"
case .safari:
return "safari"
case .shareImage:
return "shareImage"
}
}
@ -67,6 +70,9 @@ public enum SheetDestination: Identifiable {
case .safari:
return false
case .shareImage:
return false
}
}
}
@ -133,6 +139,8 @@ extension View {
.tint(Color.accentColor)
case let .safari(url):
SfSafariView(url: url)
case let .shareImage(image):
ShareSheet(image: image)
default:
EmptyView()
}

View File

@ -426,6 +426,56 @@
}
}
},
"status.menu.delete" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Delete"
}
}
}
},
"status.menu.edit" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Edit"
}
}
}
},
"status.menu.share" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Share"
}
}
}
},
"status.menu.share-image" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Share as image"
}
}
}
},
"status.menu.share-link" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Share as link"
}
}
}
},
"status.pinned" : {
"localizations" : {
"en" : {