mirror of
https://github.com/lumaa-dev/BubbleApp.git
synced 2025-02-06 13:24:25 +01:00
Post menu and image share
This commit is contained in:
parent
e83984aa62
commit
b40eb2cf92
17
Threaded/Components/ShareSheetController.swift
Normal file
17
Threaded/Components/ShareSheetController.swift
Normal 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) {
|
||||
}
|
||||
}
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
70
Threaded/Components/Status/PostMenu.swift
Normal file
70
Threaded/Components/Status/PostMenu.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
||||
|
@ -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" : {
|
||||
|
Loading…
x
Reference in New Issue
Block a user