mirror of
https://github.com/mastodon/mastodon-ios.git
synced 2025-01-30 17:14:51 +01:00
feat: restore compose poll options
This commit is contained in:
parent
44a8b818e4
commit
0a3f19bdd3
@ -112,12 +112,12 @@
|
||||
<key>NotificationService.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>17</integer>
|
||||
<integer>18</integer>
|
||||
</dict>
|
||||
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>18</integer>
|
||||
<integer>17</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "reorder.dot.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
101
MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Compose/reorder.dot.imageset/reorder.dot.pdf
vendored
Normal file
101
MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Compose/reorder.dot.imageset/reorder.dot.pdf
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
%PDF-1.7
|
||||
|
||||
1 0 obj
|
||||
<< >>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<< /Length 3 0 R >>
|
||||
stream
|
||||
/DeviceRGB CS
|
||||
/DeviceRGB cs
|
||||
q
|
||||
1.000000 0.000000 -0.000000 1.000000 7.000000 4.000000 cm
|
||||
0.000000 0.000000 0.000000 scn
|
||||
8.500000 3.000000 m
|
||||
9.328427 3.000000 10.000000 2.328427 10.000000 1.500000 c
|
||||
10.000000 0.671574 9.328427 0.000000 8.500000 0.000000 c
|
||||
7.671573 0.000000 7.000000 0.671574 7.000000 1.500000 c
|
||||
7.000000 2.328427 7.671573 3.000000 8.500000 3.000000 c
|
||||
h
|
||||
1.500000 3.000000 m
|
||||
2.328427 3.000000 3.000000 2.328427 3.000000 1.500000 c
|
||||
3.000000 0.671574 2.328427 0.000000 1.500000 0.000000 c
|
||||
0.671573 0.000000 0.000000 0.671574 0.000000 1.500000 c
|
||||
0.000000 2.328427 0.671573 3.000000 1.500000 3.000000 c
|
||||
h
|
||||
8.500000 10.000000 m
|
||||
9.328427 10.000000 10.000000 9.328427 10.000000 8.500000 c
|
||||
10.000000 7.671573 9.328427 7.000000 8.500000 7.000000 c
|
||||
7.671573 7.000000 7.000000 7.671573 7.000000 8.500000 c
|
||||
7.000000 9.328427 7.671573 10.000000 8.500000 10.000000 c
|
||||
h
|
||||
1.500000 10.000000 m
|
||||
2.328427 10.000000 3.000000 9.328427 3.000000 8.500000 c
|
||||
3.000000 7.671573 2.328427 7.000000 1.500000 7.000000 c
|
||||
0.671573 7.000000 0.000000 7.671573 0.000000 8.500000 c
|
||||
0.000000 9.328427 0.671573 10.000000 1.500000 10.000000 c
|
||||
h
|
||||
8.500000 17.000000 m
|
||||
9.328427 17.000000 10.000000 16.328426 10.000000 15.500000 c
|
||||
10.000000 14.671573 9.328427 14.000000 8.500000 14.000000 c
|
||||
7.671573 14.000000 7.000000 14.671573 7.000000 15.500000 c
|
||||
7.000000 16.328426 7.671573 17.000000 8.500000 17.000000 c
|
||||
h
|
||||
1.500000 17.000000 m
|
||||
2.328427 17.000000 3.000000 16.328426 3.000000 15.500000 c
|
||||
3.000000 14.671573 2.328427 14.000000 1.500000 14.000000 c
|
||||
0.671573 14.000000 0.000000 14.671573 0.000000 15.500000 c
|
||||
0.000000 16.328426 0.671573 17.000000 1.500000 17.000000 c
|
||||
h
|
||||
f
|
||||
n
|
||||
Q
|
||||
|
||||
endstream
|
||||
endobj
|
||||
|
||||
3 0 obj
|
||||
1644
|
||||
endobj
|
||||
|
||||
4 0 obj
|
||||
<< /Annots []
|
||||
/Type /Page
|
||||
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
|
||||
/Resources 1 0 R
|
||||
/Contents 2 0 R
|
||||
/Parent 5 0 R
|
||||
>>
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
<< /Kids [ 4 0 R ]
|
||||
/Count 1
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<< /Pages 5 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000010 00000 n
|
||||
0000000034 00000 n
|
||||
0000001734 00000 n
|
||||
0000001757 00000 n
|
||||
0000001930 00000 n
|
||||
0000002004 00000 n
|
||||
trailer
|
||||
<< /ID [ (some) (id) ]
|
||||
/Root 6 0 R
|
||||
/Size 7
|
||||
>>
|
||||
startxref
|
||||
2063
|
||||
%%EOF
|
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xF7",
|
||||
"green" : "0xF2",
|
||||
"red" : "0xF2"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.263",
|
||||
"green" : "0.208",
|
||||
"red" : "0.192"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xF7",
|
||||
"green" : "0xF2",
|
||||
"red" : "0xF2"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0.263",
|
||||
"green" : "0.208",
|
||||
"red" : "0.192"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -143,6 +143,7 @@ public enum Asset {
|
||||
public static let people = ImageAsset(name: "Scene/Compose/people")
|
||||
public static let pollFill = ImageAsset(name: "Scene/Compose/poll.fill")
|
||||
public static let poll = ImageAsset(name: "Scene/Compose/poll")
|
||||
public static let reorderDot = ImageAsset(name: "Scene/Compose/reorder.dot")
|
||||
}
|
||||
public enum Discovery {
|
||||
public static let profileCardBackground = ColorAsset(name: "Scene/Discovery/profile.card.background")
|
||||
@ -209,6 +210,7 @@ public enum Asset {
|
||||
}
|
||||
public enum Theme {
|
||||
public enum Mastodon {
|
||||
public static let composePollRowBackground = ColorAsset(name: "Theme/Mastodon/compose.poll.row.background")
|
||||
public static let composeToolbarBackground = ColorAsset(name: "Theme/Mastodon/compose.toolbar.background")
|
||||
public static let contentWarningOverlayBackground = ColorAsset(name: "Theme/Mastodon/content.warning.overlay.background")
|
||||
public static let navigationBarBackground = ColorAsset(name: "Theme/Mastodon/navigation.bar.background")
|
||||
@ -229,6 +231,7 @@ public enum Asset {
|
||||
public static let tabBarItemInactiveIconColor = ColorAsset(name: "Theme/Mastodon/tab.bar.item.inactive.icon.color")
|
||||
}
|
||||
public enum System {
|
||||
public static let composePollRowBackground = ColorAsset(name: "Theme/system/compose.poll.row.background")
|
||||
public static let composeToolbarBackground = ColorAsset(name: "Theme/system/compose.toolbar.background")
|
||||
public static let contentWarningOverlayBackground = ColorAsset(name: "Theme/system/content.warning.overlay.background")
|
||||
public static let navigationBarBackground = ColorAsset(name: "Theme/system/navigation.bar.background")
|
||||
|
@ -21,11 +21,19 @@ extension PollComposeItem {
|
||||
|
||||
public weak var textField: UITextField?
|
||||
|
||||
// input
|
||||
@Published public var text = ""
|
||||
@Published public var shouldBecomeFirstResponder = false
|
||||
|
||||
// output
|
||||
@Published public var backgroundColor = ThemeService.shared.currentTheme.value.composePollRowBackgroundColor
|
||||
|
||||
public override init() {
|
||||
super.init()
|
||||
|
||||
ThemeService.shared.currentTheme
|
||||
.map { $0.composePollRowBackgroundColor }
|
||||
.assign(to: &$backgroundColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,5 +41,6 @@ struct MastodonTheme: Theme {
|
||||
let contentWarningOverlayBackgroundColor = Asset.Theme.Mastodon.contentWarningOverlayBackground.color
|
||||
let profileFieldCollectionViewBackgroundColor = Asset.Theme.Mastodon.profileFieldCollectionViewBackground.color
|
||||
let composeToolbarBackgroundColor = Asset.Theme.Mastodon.composeToolbarBackground.color
|
||||
let composePollRowBackgroundColor = Asset.Theme.Mastodon.composePollRowBackground.color
|
||||
let notificationStatusBorderColor = Asset.Theme.System.notificationStatusBorderColor.color
|
||||
}
|
||||
|
@ -41,5 +41,6 @@ struct SystemTheme: Theme {
|
||||
let contentWarningOverlayBackgroundColor = Asset.Theme.System.contentWarningOverlayBackground.color
|
||||
let profileFieldCollectionViewBackgroundColor = Asset.Theme.System.profileFieldCollectionViewBackground.color
|
||||
let composeToolbarBackgroundColor = Asset.Theme.System.composeToolbarBackground.color
|
||||
let composePollRowBackgroundColor = Asset.Theme.System.composePollRowBackground.color
|
||||
let notificationStatusBorderColor = Asset.Theme.System.notificationStatusBorderColor.color
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public protocol Theme {
|
||||
var contentWarningOverlayBackgroundColor: UIColor { get }
|
||||
var profileFieldCollectionViewBackgroundColor: UIColor { get }
|
||||
var composeToolbarBackgroundColor: UIColor { get }
|
||||
var composePollRowBackgroundColor: UIColor { get }
|
||||
var notificationStatusBorderColor: UIColor { get }
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
//
|
||||
// PollAddOptionRow.swift
|
||||
//
|
||||
//
|
||||
// Created by MainasuK on 2022/10/26.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MastodonAsset
|
||||
import MastodonCore
|
||||
|
||||
public struct PollAddOptionRow: View {
|
||||
|
||||
@StateObject var viewModel = ViewModel()
|
||||
|
||||
public var body: some View {
|
||||
HStack(alignment: .center, spacing: 16) {
|
||||
HStack(alignment: .center, spacing: .zero) {
|
||||
Image(systemName: "plus.circle")
|
||||
.frame(width: 20, height: 20)
|
||||
.padding(.leading, 16)
|
||||
.padding(.trailing, 16 - 10) // 8pt for TextField leading
|
||||
.font(.system(size: 17))
|
||||
PollOptionTextField(
|
||||
text: $viewModel.text,
|
||||
index: 999,
|
||||
delegate: nil
|
||||
) { textField in
|
||||
// do nothing
|
||||
}
|
||||
.hidden()
|
||||
}
|
||||
.background(Color(viewModel.backgroundColor))
|
||||
.cornerRadius(10)
|
||||
.shadow(color: .black.opacity(0.3), radius: 2, x: 0, y: 1)
|
||||
Image(uiImage: Asset.Scene.Compose.reorderDot.image.withRenderingMode(.alwaysTemplate))
|
||||
.foregroundColor(Color(UIColor.label))
|
||||
.hidden()
|
||||
}
|
||||
.background(Color.clear)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension PollAddOptionRow {
|
||||
public class ViewModel: ObservableObject {
|
||||
// input
|
||||
@Published public var text: String = ""
|
||||
|
||||
// output
|
||||
@Published public var backgroundColor = ThemeService.shared.currentTheme.value.composePollRowBackgroundColor
|
||||
|
||||
public init() {
|
||||
ThemeService.shared.currentTheme
|
||||
.map { $0.composePollRowBackgroundColor }
|
||||
.assign(to: &$backgroundColor)
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MastodonAsset
|
||||
import MastodonCore
|
||||
|
||||
public struct PollOptionRow: View {
|
||||
@ -17,19 +18,34 @@ public struct PollOptionRow: View {
|
||||
let configurationHandler: (DeleteBackwardResponseTextField) -> Void
|
||||
|
||||
public var body: some View {
|
||||
PollOptionTextField(
|
||||
text: $viewModel.text,
|
||||
index: index ?? -1,
|
||||
delegate: deleteBackwardResponseTextFieldRelayDelegate
|
||||
) { textField in
|
||||
viewModel.textField = textField
|
||||
configurationHandler(textField)
|
||||
}
|
||||
.onReceive(viewModel.$shouldBecomeFirstResponder) { shouldBecomeFirstResponder in
|
||||
guard shouldBecomeFirstResponder else { return }
|
||||
viewModel.shouldBecomeFirstResponder = false
|
||||
viewModel.textField?.becomeFirstResponder()
|
||||
HStack(alignment: .center, spacing: 16) {
|
||||
HStack(alignment: .center, spacing: .zero) {
|
||||
Image(systemName: "circle")
|
||||
.frame(width: 20, height: 20)
|
||||
.padding(.leading, 16)
|
||||
.padding(.trailing, 16 - 10) // 8pt for TextField leading
|
||||
.font(.system(size: 17))
|
||||
PollOptionTextField(
|
||||
text: $viewModel.text,
|
||||
index: index ?? -1,
|
||||
delegate: deleteBackwardResponseTextFieldRelayDelegate
|
||||
) { textField in
|
||||
viewModel.textField = textField
|
||||
configurationHandler(textField)
|
||||
}
|
||||
.onReceive(viewModel.$shouldBecomeFirstResponder) { shouldBecomeFirstResponder in
|
||||
guard shouldBecomeFirstResponder else { return }
|
||||
viewModel.shouldBecomeFirstResponder = false
|
||||
viewModel.textField?.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
.background(Color(viewModel.backgroundColor))
|
||||
.cornerRadius(10)
|
||||
.shadow(color: .black.opacity(0.3), radius: 2, x: 0, y: 1)
|
||||
Image(uiImage: Asset.Scene.Compose.reorderDot.image.withRenderingMode(.alwaysTemplate))
|
||||
.foregroundColor(Color(UIColor.label))
|
||||
}
|
||||
.background(Color.clear)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,8 +26,11 @@ public struct PollOptionTextField: UIViewRepresentable {
|
||||
textField.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||
textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||||
textField.textInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
|
||||
textField.borderStyle = .roundedRect
|
||||
textField.borderStyle = .none
|
||||
textField.backgroundColor = .clear
|
||||
textField.returnKeyType = .next
|
||||
textField.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 16, weight: .regular))
|
||||
textField.adjustsFontForContentSizeCategory = true
|
||||
return textField
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,7 @@ struct ComposeContentToolbarView: View {
|
||||
}
|
||||
Spacer()
|
||||
Text("Hello")
|
||||
.font(.system(size: 16, weight: .regular))
|
||||
}
|
||||
.padding(.leading, 4) // 4 + 12 = 16
|
||||
.padding(.trailing, 16)
|
||||
|
@ -80,7 +80,7 @@ extension ComposeContentView {
|
||||
metaContent: viewModel.name
|
||||
)
|
||||
Text(viewModel.username)
|
||||
.font(.subheadline)
|
||||
.font(.system(size: 15, weight: .regular))
|
||||
.foregroundColor(.secondary)
|
||||
Spacer()
|
||||
}
|
||||
@ -107,6 +107,12 @@ extension ComposeContentView {
|
||||
// viewModel.customEmojiPickerInputViewModel.configure(textInput: textField)
|
||||
}
|
||||
}
|
||||
if viewModel.maxPollOptionLimit != viewModel.pollOptions.count {
|
||||
PollAddOptionRow()
|
||||
.onTapGesture {
|
||||
viewModel.createNewPollOptionIfCould()
|
||||
}
|
||||
}
|
||||
}
|
||||
VStack(spacing: .zero) {
|
||||
// expire configuration
|
||||
|
Loading…
x
Reference in New Issue
Block a user