Remove old compose rewrite code
This commit is contained in:
parent
6730575aed
commit
e0e9d4a185
@ -1,182 +0,0 @@
|
|||||||
//
|
|
||||||
// AttachmentRowView.swift
|
|
||||||
// ComposeUI
|
|
||||||
//
|
|
||||||
// Created by Shadowfacts on 8/18/24.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import InstanceFeatures
|
|
||||||
import Vision
|
|
||||||
|
|
||||||
struct AttachmentRowView: View {
|
|
||||||
@ObservedObject var attachment: DraftAttachment
|
|
||||||
@State private var isRecognizingText = false
|
|
||||||
@State private var textRecognitionError: (any Error)?
|
|
||||||
|
|
||||||
private var thumbnailSize: CGFloat {
|
|
||||||
#if os(visionOS)
|
|
||||||
120
|
|
||||||
#else
|
|
||||||
80
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
HStack(alignment: .center, spacing: 4) {
|
|
||||||
thumbnailView
|
|
||||||
|
|
||||||
descriptionView
|
|
||||||
}
|
|
||||||
.alertWithData("Text Recognition Failed", data: $textRecognitionError) { _ in
|
|
||||||
Button("OK") {}
|
|
||||||
} message: { error in
|
|
||||||
Text(error.localizedDescription)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: attachments missing descriptions feature
|
|
||||||
|
|
||||||
private var thumbnailView: some View {
|
|
||||||
AttachmentThumbnailView(attachment: attachment)
|
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 8))
|
|
||||||
.frame(width: thumbnailSize, height: thumbnailSize)
|
|
||||||
.contextMenu {
|
|
||||||
EditDrawingButton(attachment: attachment)
|
|
||||||
RecognizeTextButton(attachment: attachment, isRecognizingText: $isRecognizingText, error: $textRecognitionError)
|
|
||||||
DeleteButton(attachment: attachment)
|
|
||||||
} previewIfAvailable: {
|
|
||||||
// TODO: need to fix flash of preview changing size
|
|
||||||
AttachmentThumbnailView(attachment: attachment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private var descriptionView: some View {
|
|
||||||
if isRecognizingText {
|
|
||||||
ProgressView()
|
|
||||||
.progressViewStyle(.circular)
|
|
||||||
} else {
|
|
||||||
InlineAttachmentDescriptionView(attachment: attachment, minHeight: thumbnailSize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct EditDrawingButton: View {
|
|
||||||
@ObservedObject var attachment: DraftAttachment
|
|
||||||
@Environment(\.composeUIConfig.presentDrawing) private var presentDrawing
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
if attachment.drawingData != nil {
|
|
||||||
Button(action: editDrawing) {
|
|
||||||
Label("Edit Drawing", systemImage: "hand.draw")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func editDrawing() {
|
|
||||||
if case .drawing(let drawing) = attachment.data {
|
|
||||||
presentDrawing?(drawing) {
|
|
||||||
attachment.drawing = $0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct RecognizeTextButton: View {
|
|
||||||
@ObservedObject var attachment: DraftAttachment
|
|
||||||
@Binding var isRecognizingText: Bool
|
|
||||||
@Binding var error: (any Error)?
|
|
||||||
@EnvironmentObject private var instanceFeatures: InstanceFeatures
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
if attachment.type == .image {
|
|
||||||
Button {
|
|
||||||
Task {
|
|
||||||
await recognizeText()
|
|
||||||
}
|
|
||||||
} label: {
|
|
||||||
Label("Recognize Text", systemImage: "doc.text.viewfinder")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func recognizeText() async {
|
|
||||||
isRecognizingText = true
|
|
||||||
defer { isRecognizingText = false }
|
|
||||||
|
|
||||||
do {
|
|
||||||
let data = try await getAttachmentData()
|
|
||||||
let observations = try await runRecognizeTextRequest(data: data)
|
|
||||||
if let observations {
|
|
||||||
var text = ""
|
|
||||||
for observation in observations {
|
|
||||||
let result = observation.topCandidates(1).first!
|
|
||||||
text.append(result.string)
|
|
||||||
text.append("\n")
|
|
||||||
}
|
|
||||||
self.attachment.attachmentDescription = text
|
|
||||||
}
|
|
||||||
} catch let error as NSError where error.domain == VNErrorDomain && error.code == 1 {
|
|
||||||
// The perform call throws an error with code 1 if the request is cancelled, which we don't want to show an alert for.
|
|
||||||
return
|
|
||||||
} catch {
|
|
||||||
self.error = error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func getAttachmentData() async throws -> Data {
|
|
||||||
return try await withCheckedThrowingContinuation { continuation in
|
|
||||||
attachment.getData(features: instanceFeatures) { result in
|
|
||||||
switch result {
|
|
||||||
case .success(let (data, _)):
|
|
||||||
continuation.resume(returning: data)
|
|
||||||
case .failure(let error):
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func runRecognizeTextRequest(data: Data) async throws -> [VNRecognizedTextObservation]? {
|
|
||||||
return try await withCheckedThrowingContinuation { continuation in
|
|
||||||
let handler = VNImageRequestHandler(data: data)
|
|
||||||
let request = VNRecognizeTextRequest { request, error in
|
|
||||||
if let error {
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
} else {
|
|
||||||
continuation.resume(returning: request.results as? [VNRecognizedTextObservation])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
request.recognitionLevel = .accurate
|
|
||||||
request.usesLanguageCorrection = true
|
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
|
||||||
try? handler.perform([request])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct DeleteButton: View {
|
|
||||||
let attachment: DraftAttachment
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
Button(role: .destructive, action: removeAttachment) {
|
|
||||||
Label("Delete", systemImage: "trash")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func removeAttachment() {
|
|
||||||
let draft = attachment.draft
|
|
||||||
var array = draft.draftAttachments
|
|
||||||
guard let index = array.firstIndex(of: attachment) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
array.remove(at: index)
|
|
||||||
draft.attachments = NSMutableOrderedSet(array: array)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//#Preview {
|
|
||||||
// AttachmentRowView()
|
|
||||||
//}
|
|
@ -9,6 +9,7 @@ import SwiftUI
|
|||||||
import PhotosUI
|
import PhotosUI
|
||||||
import PencilKit
|
import PencilKit
|
||||||
import GalleryVC
|
import GalleryVC
|
||||||
|
import InstanceFeatures
|
||||||
|
|
||||||
struct AttachmentsSection: View {
|
struct AttachmentsSection: View {
|
||||||
@ObservedObject var draft: Draft
|
@ObservedObject var draft: Draft
|
||||||
@ -24,6 +25,19 @@ struct AttachmentsSection: View {
|
|||||||
// Add 4 to the minItemSize because otherwise drag-and-drop while reordering can alter the contentOffset by that much.
|
// Add 4 to the minItemSize because otherwise drag-and-drop while reordering can alter the contentOffset by that much.
|
||||||
.frame(minHeight: 104)
|
.frame(minHeight: 104)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func insertAttachments(in draft: Draft, at index: Int, itemProviders: [NSItemProvider]) {
|
||||||
|
for provider in itemProviders where provider.canLoadObject(ofClass: DraftAttachment.self) {
|
||||||
|
provider.loadObject(ofClass: DraftAttachment.self) { object, error in
|
||||||
|
guard let attachment = object as? DraftAttachment else { return }
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
DraftsPersistentContainer.shared.viewContext.insert(attachment)
|
||||||
|
attachment.draft = draft
|
||||||
|
draft.attachments.add(attachment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use a UIViewControllerRepresentable so we have something from which to present the gallery VC.
|
// Use a UIViewControllerRepresentable so we have something from which to present the gallery VC.
|
||||||
@ -277,7 +291,7 @@ private struct AddAttachmentButton: View {
|
|||||||
Button("Add photo or video", systemImage: "photo") {
|
Button("Add photo or video", systemImage: "photo") {
|
||||||
presentAssetPicker {
|
presentAssetPicker {
|
||||||
let draft = viewController.draft!
|
let draft = viewController.draft!
|
||||||
AttachmentsListSection.insertAttachments(in: draft, at: draft.attachments.count, itemProviders: $0.map(\.itemProvider))
|
AttachmentsSection.insertAttachments(in: draft, at: draft.attachments.count, itemProviders: $0.map(\.itemProvider))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,3 +322,58 @@ private struct AddAttachmentButton: View {
|
|||||||
.disabled(!enabled)
|
.disabled(!enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AddAttachmentConditionsModifier: ViewModifier {
|
||||||
|
@ObservedObject var draft: Draft
|
||||||
|
@EnvironmentObject private var instanceFeatures: InstanceFeatures
|
||||||
|
|
||||||
|
private var canAddAttachment: Bool {
|
||||||
|
if instanceFeatures.mastodonAttachmentRestrictions {
|
||||||
|
return draft.attachments.count < 4
|
||||||
|
&& draft.draftAttachments.allSatisfy { $0.type == .image }
|
||||||
|
&& draft.poll == nil
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
content
|
||||||
|
.environment(\.canAddAttachment, canAddAttachment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct CanAddAttachmentKey: EnvironmentKey {
|
||||||
|
static let defaultValue = false
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnvironmentValues {
|
||||||
|
var canAddAttachment: Bool {
|
||||||
|
get { self[CanAddAttachmentKey.self] }
|
||||||
|
set { self[CanAddAttachmentKey.self] = newValue }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DropAttachmentModifier: ViewModifier {
|
||||||
|
let draft: Draft
|
||||||
|
@Environment(\.canAddAttachment) private var canAddAttachment
|
||||||
|
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
content
|
||||||
|
.onDrop(of: DraftAttachment.readableTypeIdentifiersForItemProvider, delegate: AttachmentDropDelegate(draft: draft, canAddAttachment: canAddAttachment))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct AttachmentDropDelegate: DropDelegate {
|
||||||
|
let draft: Draft
|
||||||
|
let canAddAttachment: Bool
|
||||||
|
|
||||||
|
func validateDrop(info: DropInfo) -> Bool {
|
||||||
|
canAddAttachment
|
||||||
|
}
|
||||||
|
|
||||||
|
func performDrop(info: DropInfo) -> Bool {
|
||||||
|
AttachmentsSection.insertAttachments(in: draft, at: draft.attachments.count, itemProviders: info.itemProviders(for: DraftAttachment.readableTypeIdentifiersForItemProvider))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,182 +0,0 @@
|
|||||||
//
|
|
||||||
// AttachmentsListSection.swift
|
|
||||||
// ComposeUI
|
|
||||||
//
|
|
||||||
// Created by Shadowfacts on 10/14/24.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import InstanceFeatures
|
|
||||||
import PencilKit
|
|
||||||
|
|
||||||
struct AttachmentsListSection: View {
|
|
||||||
@ObservedObject var draft: Draft
|
|
||||||
@ObservedObject var instanceFeatures: InstanceFeatures
|
|
||||||
@Environment(\.canAddAttachment) private var canAddAttachment
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
attachmentRows
|
|
||||||
|
|
||||||
buttons
|
|
||||||
.foregroundStyle(.tint)
|
|
||||||
#if os(visionOS)
|
|
||||||
.buttonStyle(.bordered)
|
|
||||||
.labelStyle(AttachmentButtonLabelStyle())
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
private var attachmentRows: some View {
|
|
||||||
ForEach(draft.draftAttachments) { attachment in
|
|
||||||
AttachmentRowView(attachment: attachment)
|
|
||||||
}
|
|
||||||
.onMove(perform: moveAttachments)
|
|
||||||
.onDelete(perform: deleteAttachments)
|
|
||||||
.onInsert(of: DraftAttachment.readableTypeIdentifiersForItemProvider) { offset, providers in
|
|
||||||
Self.insertAttachments(in: draft, at: offset, itemProviders: providers)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private var buttons: some View {
|
|
||||||
AddPhotoButton(addAttachments: self.addAttachments)
|
|
||||||
|
|
||||||
AddDrawingButton(draft: draft)
|
|
||||||
|
|
||||||
TogglePollButton(draft: draft)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func insertAttachments(in draft: Draft, at index: Int, itemProviders: [NSItemProvider]) {
|
|
||||||
for provider in itemProviders where provider.canLoadObject(ofClass: DraftAttachment.self) {
|
|
||||||
provider.loadObject(ofClass: DraftAttachment.self) { object, error in
|
|
||||||
guard let attachment = object as? DraftAttachment else { return }
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
DraftsPersistentContainer.shared.viewContext.insert(attachment)
|
|
||||||
attachment.draft = draft
|
|
||||||
draft.attachments.add(attachment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func addAttachments(itemProviders: [NSItemProvider]) {
|
|
||||||
Self.insertAttachments(in: draft, at: draft.attachments.count, itemProviders: itemProviders)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func moveAttachments(from source: IndexSet, to destination: Int) {
|
|
||||||
// just using moveObjects(at:to:) on the draft.attachments NSMutableOrderedSet
|
|
||||||
// results in the order switching back to the previous order and then to the correct one
|
|
||||||
// on the subsequent 2 view updates. creating a new set with the proper order doesn't have that problem
|
|
||||||
var array = draft.draftAttachments
|
|
||||||
array.move(fromOffsets: source, toOffset: destination)
|
|
||||||
draft.attachments = NSMutableOrderedSet(array: array)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func deleteAttachments(at indices: IndexSet) {
|
|
||||||
var array = draft.draftAttachments
|
|
||||||
array.remove(atOffsets: indices)
|
|
||||||
draft.attachments = NSMutableOrderedSet(array: array)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct AddPhotoButton: View {
|
|
||||||
let addAttachments: ([NSItemProvider]) -> Void
|
|
||||||
@Environment(\.composeUIConfig.presentAssetPicker) private var presentAssetPicker
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
if let presentAssetPicker {
|
|
||||||
Button("Add photo or video", systemImage: "photo") {
|
|
||||||
presentAssetPicker { results in
|
|
||||||
addAttachments(results.map(\.itemProvider))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct AddDrawingButton: View {
|
|
||||||
let draft: Draft
|
|
||||||
@Environment(\.composeUIConfig.presentDrawing) private var presentDrawing
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
if let presentDrawing {
|
|
||||||
Button("Add drawing", systemImage: "hand.draw") {
|
|
||||||
presentDrawing(PKDrawing()) { drawing in
|
|
||||||
let attachment = DraftAttachment(context: DraftsPersistentContainer.shared.viewContext)
|
|
||||||
attachment.id = UUID()
|
|
||||||
attachment.drawing = drawing
|
|
||||||
attachment.draft = self.draft
|
|
||||||
self.draft.attachments.add(attachment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct TogglePollButton: View {
|
|
||||||
@ObservedObject var draft: Draft
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
Button(draft.poll == nil ? "Add a poll" : "Remove poll", systemImage: "chart.bar.doc.horizontal") {
|
|
||||||
withAnimation {
|
|
||||||
draft.poll = draft.poll == nil ? Poll(context: DraftsPersistentContainer.shared.viewContext) : nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.disabled(draft.attachments.count > 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AddAttachmentConditionsModifier: ViewModifier {
|
|
||||||
@ObservedObject var draft: Draft
|
|
||||||
@EnvironmentObject private var instanceFeatures: InstanceFeatures
|
|
||||||
|
|
||||||
private var canAddAttachment: Bool {
|
|
||||||
if instanceFeatures.mastodonAttachmentRestrictions {
|
|
||||||
return draft.attachments.count < 4
|
|
||||||
&& draft.draftAttachments.allSatisfy { $0.type == .image }
|
|
||||||
&& draft.poll == nil
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
|
||||||
content
|
|
||||||
.environment(\.canAddAttachment, canAddAttachment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct CanAddAttachmentKey: EnvironmentKey {
|
|
||||||
static let defaultValue = false
|
|
||||||
}
|
|
||||||
|
|
||||||
extension EnvironmentValues {
|
|
||||||
var canAddAttachment: Bool {
|
|
||||||
get { self[CanAddAttachmentKey.self] }
|
|
||||||
set { self[CanAddAttachmentKey.self] = newValue }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DropAttachmentModifier: ViewModifier {
|
|
||||||
let draft: Draft
|
|
||||||
@Environment(\.canAddAttachment) private var canAddAttachment
|
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
|
||||||
content
|
|
||||||
.onDrop(of: DraftAttachment.readableTypeIdentifiersForItemProvider, delegate: AttachmentDropDelegate(draft: draft, canAddAttachment: canAddAttachment))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct AttachmentDropDelegate: DropDelegate {
|
|
||||||
let draft: Draft
|
|
||||||
let canAddAttachment: Bool
|
|
||||||
|
|
||||||
func validateDrop(info: DropInfo) -> Bool {
|
|
||||||
canAddAttachment
|
|
||||||
}
|
|
||||||
|
|
||||||
func performDrop(info: DropInfo) -> Bool {
|
|
||||||
AttachmentsListSection.insertAttachments(in: draft, at: draft.attachments.count, itemProviders: info.itemProviders(for: DraftAttachment.readableTypeIdentifiersForItemProvider))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
@ -92,23 +92,10 @@ struct ComposeView: View {
|
|||||||
ComposeDraftView(draft: draft, focusedField: $focusedField)
|
ComposeDraftView(draft: draft, focusedField: $focusedField)
|
||||||
}
|
}
|
||||||
.padding(8)
|
.padding(8)
|
||||||
// NewHeaderView(draft: draft, instanceFeatures: mastodonController.instanceFeatures)
|
|
||||||
// .listRowInsets(EdgeInsets(top: 8, leading: 8, bottom: 4, trailing: 8))
|
|
||||||
// .listRowSeparator(.hidden)
|
|
||||||
//
|
|
||||||
// ContentWarningTextField(draft: draft, focusedField: $focusedField)
|
|
||||||
// .listRowInsets(EdgeInsets(top: 8, leading: 8, bottom: 4, trailing: 8))
|
|
||||||
// .listRowSeparator(.hidden)
|
|
||||||
//
|
|
||||||
// NewMainTextView(value: $draft.text, focusedField: $focusedField, handleAttachmentDrop: self.addAttachments)
|
|
||||||
// .listRowInsets(EdgeInsets(top: 8, leading: 8, bottom: 4, trailing: 8))
|
|
||||||
// .listRowSeparator(.hidden)
|
|
||||||
//
|
|
||||||
// AttachmentsListSection(draft: draft, instanceFeatures: mastodonController.instanceFeatures)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addAttachments(_ itemProviders: [NSItemProvider]) {
|
private func addAttachments(_ itemProviders: [NSItemProvider]) {
|
||||||
AttachmentsListSection.insertAttachments(in: draft, at: draft.attachments.count, itemProviders: itemProviders)
|
AttachmentsSection.insertAttachments(in: draft, at: draft.attachments.count, itemProviders: itemProviders)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ struct DraftContentEditor: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func addAttachments(_ providers: [NSItemProvider]) {
|
private func addAttachments(_ providers: [NSItemProvider]) {
|
||||||
AttachmentsListSection.insertAttachments(in: draft, at: draft.attachments.count, itemProviders: providers)
|
AttachmentsSection.insertAttachments(in: draft, at: draft.attachments.count, itemProviders: providers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,19 +29,3 @@ struct HeaderView: View {
|
|||||||
}.frame(height: 50)
|
}.frame(height: 50)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NewHeaderView: View {
|
|
||||||
@ObservedObject var draft: Draft
|
|
||||||
@ObservedObject var instanceFeatures: InstanceFeatures
|
|
||||||
@Environment(\.currentAccount) private var currentAccount
|
|
||||||
|
|
||||||
private var charactersRemaining: Int {
|
|
||||||
let limit = instanceFeatures.maxStatusChars
|
|
||||||
let cwCount = draft.contentWarningEnabled ? draft.contentWarning.count : 0
|
|
||||||
return limit - (cwCount + CharacterCounter.count(text: draft.text, for: instanceFeatures))
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
HeaderView(currentAccount: currentAccount, charsRemaining: charactersRemaining)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user