152 lines
6.0 KiB
Swift
152 lines
6.0 KiB
Swift
//
|
|
// ComposeView.swift
|
|
//
|
|
//
|
|
// Created by MainasuK Cirno on 2021-7-16.
|
|
//
|
|
|
|
import UIKit
|
|
import SwiftUI
|
|
|
|
public struct ComposeView: View {
|
|
|
|
@EnvironmentObject var viewModel: ComposeViewModel
|
|
@State var statusEditorViewWidth: CGFloat = .zero
|
|
|
|
let horizontalMargin: CGFloat = 20
|
|
|
|
public init() { }
|
|
|
|
public var body: some View {
|
|
GeometryReader { proxy in
|
|
List {
|
|
// Content Warning
|
|
if viewModel.isContentWarningComposing {
|
|
ContentWarningEditorView(
|
|
contentWarningContent: $viewModel.contentWarningContent,
|
|
placeholder: viewModel.contentWarningPlaceholder
|
|
)
|
|
.padding(EdgeInsets(top: 6, leading: horizontalMargin, bottom: 6, trailing: horizontalMargin))
|
|
.background(viewModel.contentWarningBackgroundColor)
|
|
.transition(.opacity)
|
|
.listRow(backgroundColor: Color(viewModel.backgroundColor))
|
|
}
|
|
|
|
// Author
|
|
StatusAuthorView(
|
|
avatarImageURL: viewModel.avatarImageURL,
|
|
name: viewModel.authorName,
|
|
username: viewModel.authorUsername
|
|
)
|
|
.padding(EdgeInsets(top: 20, leading: horizontalMargin, bottom: 16, trailing: horizontalMargin))
|
|
.listRow(backgroundColor: Color(viewModel.backgroundColor))
|
|
|
|
// Editor
|
|
StatusEditorView(
|
|
string: $viewModel.statusContent,
|
|
placeholder: viewModel.statusPlaceholder,
|
|
width: statusEditorViewWidth,
|
|
attributedString: viewModel.statusContentAttributedString,
|
|
keyboardType: .twitter,
|
|
viewDidAppear: $viewModel.viewDidAppear
|
|
)
|
|
.frame(width: statusEditorViewWidth)
|
|
.frame(minHeight: 100)
|
|
.padding(EdgeInsets(top: 0, leading: horizontalMargin, bottom: 0, trailing: horizontalMargin))
|
|
.listRow(backgroundColor: Color(viewModel.backgroundColor))
|
|
|
|
// Attachments
|
|
ForEach(viewModel.attachmentViewModels) { attachmentViewModel in
|
|
let descriptionBinding = Binding {
|
|
return attachmentViewModel.descriptionContent
|
|
} set: { newValue in
|
|
attachmentViewModel.descriptionContent = newValue
|
|
}
|
|
|
|
StatusAttachmentView(
|
|
image: attachmentViewModel.thumbnailImage,
|
|
descriptionPlaceholder: attachmentViewModel.descriptionPlaceholder,
|
|
description: descriptionBinding,
|
|
errorPrompt: attachmentViewModel.errorPrompt,
|
|
errorPromptImage: attachmentViewModel.errorPromptImage,
|
|
isUploading: attachmentViewModel.isUploading,
|
|
progressViewTintColor: attachmentViewModel.progressViewTintColor,
|
|
removeButtonAction: {
|
|
self.viewModel.removeAttachmentViewModel(attachmentViewModel)
|
|
}
|
|
)
|
|
}
|
|
.padding(EdgeInsets(top: 16, leading: horizontalMargin, bottom: 0, trailing: horizontalMargin))
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
.listRow(backgroundColor: Color(viewModel.backgroundColor))
|
|
|
|
// bottom padding
|
|
Color.clear
|
|
.frame(height: viewModel.toolbarHeight + 20)
|
|
.listRow(backgroundColor: Color(viewModel.backgroundColor))
|
|
} // end List
|
|
.listStyle(.plain)
|
|
.introspectTableView(customize: { tableView in
|
|
// tableView.keyboardDismissMode = .onDrag
|
|
tableView.verticalScrollIndicatorInsets.bottom = viewModel.toolbarHeight
|
|
})
|
|
.preference(
|
|
key: ComposeListViewFramePreferenceKey.self,
|
|
value: proxy.frame(in: .local)
|
|
)
|
|
.onPreferenceChange(ComposeListViewFramePreferenceKey.self) { frame in
|
|
var frame = frame
|
|
frame.size.width = frame.width - 2 * horizontalMargin
|
|
statusEditorViewWidth = frame.width
|
|
} // end List
|
|
.introspectTableView(customize: { tableView in
|
|
tableView.backgroundColor = .clear
|
|
})
|
|
.overrideBackground(color: Color(viewModel.backgroundColor))
|
|
} // end GeometryReader
|
|
} // end body
|
|
}
|
|
|
|
struct ComposeListViewFramePreferenceKey: PreferenceKey {
|
|
static var defaultValue: CGRect = .zero
|
|
static func reduce(value: inout CGRect, nextValue: () -> CGRect) { }
|
|
}
|
|
|
|
extension View {
|
|
// hack for separator line
|
|
@ViewBuilder
|
|
func listRow(backgroundColor: Color) -> some View {
|
|
// expand list row to edge (set inset)
|
|
// then hide the separator
|
|
if #available(iOS 15, *) {
|
|
frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
|
|
.listRowInsets(EdgeInsets(top: -1, leading: -1, bottom: -1, trailing: -1))
|
|
.background(backgroundColor)
|
|
.listRowSeparator(.hidden) // new API
|
|
} else {
|
|
frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
|
|
.listRowInsets(EdgeInsets(top: -1, leading: -1, bottom: -1, trailing: -1)) // separator line hidden magic
|
|
.background(backgroundColor)
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
func overrideBackground(color: Color) -> some View {
|
|
background(color.ignoresSafeArea())
|
|
}
|
|
}
|
|
|
|
|
|
struct ComposeView_Previews: PreviewProvider {
|
|
|
|
static let viewModel: ComposeViewModel = {
|
|
let viewModel = ComposeViewModel()
|
|
return viewModel
|
|
}()
|
|
|
|
static var previews: some View {
|
|
ComposeView().environmentObject(viewModel)
|
|
}
|
|
|
|
}
|