feat: restore the compose toolbar layout using SwiftUI

This commit is contained in:
CMK 2022-10-18 19:01:31 +08:00
parent 4367e8eaba
commit f1b5c52815
20 changed files with 1007 additions and 110 deletions

View File

@ -3048,7 +3048,7 @@
DB025B8E278D6448002F581E /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 8;
buildActionMask = 12;
files = (
);
inputFileListPaths = (
@ -3059,14 +3059,14 @@
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [[ -f \"${PODS_ROOT}/Sourcery/bin/sourcery\" ]]; then\n \"${PODS_ROOT}/Sourcery/bin/sourcery\" --config ./MastodonSDK/Sources/CoreDataStack\nelse\n echo \"warning: Sourcery is not installed. Run 'pod install --repo-update' to install it.\"\nfi\n";
};
DB3D100425BAA71500EAA174 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 8;
buildActionMask = 12;
files = (
);
inputFileListPaths = (
@ -3077,14 +3077,14 @@
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [[ -f \"${PODS_ROOT}/SwiftGen/bin/swiftgen\" ]]; then\n \"${PODS_ROOT}/SwiftGen/bin/swiftgen\" \nelse\n echo \"warning: SwiftGen is not installed. Run 'pod install --repo-update' to install it.\"\nfi\n";
};
DB697DD2278F48D5004EF2F7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 8;
buildActionMask = 12;
files = (
);
inputFileListPaths = (
@ -3095,7 +3095,7 @@
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [[ -f \"${PODS_ROOT}/Sourcery/bin/sourcery\" ]]; then\n \"${PODS_ROOT}/Sourcery/bin/sourcery\" --config ./Mastodon\nelse\n echo \"warning: Sourcery is not installed. Run 'pod install --repo-update' to install it.\"\nfi\n";
};

View File

@ -112,12 +112,12 @@
<key>NotificationService.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>18</integer>
<integer>17</integer>
</dict>
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>17</integer>
<integer>18</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -207,24 +207,6 @@ extension ComposeViewController {
// self.title = title
// }
// .store(in: &disposeBag)
// self.setupBackgroundColor(theme: ThemeService.shared.currentTheme.value)
// ThemeService.shared.currentTheme
// .receive(on: RunLoop.main)
// .sink { [weak self] theme in
// guard let self = self else { return }
// self.setupBackgroundColor(theme: theme)
// }
// .store(in: &disposeBag)
//
//
// scrollView.translatesAutoresizingMaskIntoConstraints = false
// view.addSubview(scrollView)
// NSLayoutConstraint.activate([
// scrollView.topAnchor.constraint(equalTo: view.topAnchor),
// scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
// scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
// scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
// ])
//
// composeToolbarView.translatesAutoresizingMaskIntoConstraints = false
// view.addSubview(composeToolbarView)
@ -286,89 +268,7 @@ extension ComposeViewController {
// // update layout when keyboard show/dismiss
// view.layoutIfNeeded()
//
// let keyboardHasShortcutBar = CurrentValueSubject<Bool, Never>(traitCollection.userInterfaceIdiom == .pad) // update default value later
// let keyboardEventPublishers = Publishers.CombineLatest3(
// KeyboardResponderService.shared.isShow,
// KeyboardResponderService.shared.state,
// KeyboardResponderService.shared.endFrame
// )
// Publishers.CombineLatest3(
// keyboardEventPublishers,
// viewModel.$isCustomEmojiComposing,
// viewModel.$autoCompleteInfo
// )
// .sink(receiveValue: { [weak self] keyboardEvents, isCustomEmojiComposing, autoCompleteInfo in
// guard let self = self else { return }
//
// let (isShow, state, endFrame) = keyboardEvents
//
// switch self.traitCollection.userInterfaceIdiom {
// case .pad:
// keyboardHasShortcutBar.value = state != .floating
// default:
// keyboardHasShortcutBar.value = false
// }
//
// let extraMargin: CGFloat = {
// var margin = self.composeToolbarView.frame.height
// if autoCompleteInfo != nil {
// margin += ComposeViewController.minAutoCompleteVisibleHeight
// }
// return margin
// }()
//
// guard isShow, state == .dock else {
// self.tableView.contentInset.bottom = extraMargin
// self.tableView.verticalScrollIndicatorInsets.bottom = extraMargin
//
// if let superView = self.autoCompleteViewController.tableView.superview {
// let autoCompleteTableViewBottomInset: CGFloat = {
// let tableViewFrameInWindow = superView.convert(self.autoCompleteViewController.tableView.frame, to: nil)
// let padding = tableViewFrameInWindow.maxY + self.composeToolbarView.frame.height + AutoCompleteViewController.chevronViewHeight - self.view.frame.maxY
// return max(0, padding)
// }()
// self.autoCompleteViewController.tableView.contentInset.bottom = autoCompleteTableViewBottomInset
// self.autoCompleteViewController.tableView.verticalScrollIndicatorInsets.bottom = autoCompleteTableViewBottomInset
// }
//
// UIView.animate(withDuration: 0.3) {
// self.composeToolbarViewBottomLayoutConstraint.constant = self.view.safeAreaInsets.bottom
// if self.view.window != nil {
// self.view.layoutIfNeeded()
// }
// }
// return
// }
// // isShow AND dock state
// self.systemKeyboardHeight = endFrame.height
//
// // adjust inset for auto-complete
// let autoCompleteTableViewBottomInset: CGFloat = {
// guard let superview = self.autoCompleteViewController.tableView.superview else { return .zero }
// let tableViewFrameInWindow = superview.convert(self.autoCompleteViewController.tableView.frame, to: nil)
// let padding = tableViewFrameInWindow.maxY + self.composeToolbarView.frame.height + AutoCompleteViewController.chevronViewHeight - endFrame.minY
// return max(0, padding)
// }()
// self.autoCompleteViewController.tableView.contentInset.bottom = autoCompleteTableViewBottomInset
// self.autoCompleteViewController.tableView.verticalScrollIndicatorInsets.bottom = autoCompleteTableViewBottomInset
//
// // adjust inset for tableView
// let contentFrame = self.view.convert(self.tableView.frame, to: nil)
// let padding = contentFrame.maxY + extraMargin - endFrame.minY
// guard padding > 0 else {
// self.tableView.contentInset.bottom = self.view.safeAreaInsets.bottom + extraMargin
// self.tableView.verticalScrollIndicatorInsets.bottom = self.view.safeAreaInsets.bottom + extraMargin
// return
// }
//
// self.tableView.contentInset.bottom = padding - self.view.safeAreaInsets.bottom
// self.tableView.verticalScrollIndicatorInsets.bottom = padding - self.view.safeAreaInsets.bottom
// UIView.animate(withDuration: 0.3) {
// self.composeToolbarViewBottomLayoutConstraint.constant = endFrame.height
// self.view.layoutIfNeeded()
// }
// })
// .store(in: &disposeBag)
//
// // bind auto-complete
// viewModel.$autoCompleteInfo

View File

@ -0,0 +1,9 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"provides-namespace" : true
}
}

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "Earth.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -0,0 +1,169 @@
%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 2.000122 2.000000 cm
0.000000 0.000000 0.000000 scn
8.945436 19.952877 m
8.950368 19.945572 l
9.295332 19.981556 9.645513 20.000000 10.000000 20.000000 c
15.522847 20.000000 20.000000 15.522847 20.000000 10.000000 c
20.000000 4.477153 15.522847 0.000000 10.000000 0.000000 c
6.790722 0.000000 3.934541 1.511787 2.104761 3.862055 c
2.102194 3.862638 l
2.102672 3.864738 l
0.784842 5.558613 0.000000 7.687653 0.000000 10.000000 c
0.000000 15.161964 3.911163 19.410429 8.931705 19.943607 c
8.945436 19.952877 l
h
10.000000 18.500000 m
9.946768 18.500000 9.893649 18.499510 9.840650 18.498537 c
9.963233 18.254343 10.094863 17.965696 10.214363 17.648212 c
10.561299 16.726484 10.880171 15.367099 10.314304 14.162127 c
9.791718 13.049316 8.889565 12.761408 8.224188 12.589492 c
8.139534 12.567652 l
7.483193 12.398458 7.230809 12.333397 7.046710 12.053902 c
6.877729 11.797358 6.903327 11.471569 7.108089 10.804317 c
7.122483 10.757413 7.138054 10.707805 7.154294 10.656069 c
7.235397 10.397685 7.333165 10.086211 7.384129 9.793275 c
7.447527 9.428862 7.465442 8.965590 7.232083 8.517794 c
7.000589 8.073575 6.693745 7.770780 6.331198 7.573263 c
5.990655 7.387735 5.637942 7.317377 5.374053 7.270582 c
5.281080 7.254177 l
4.766211 7.163565 4.519922 7.120219 4.280048 6.863250 c
4.093846 6.663777 3.973670 6.311463 3.903486 5.785102 c
3.874918 5.570853 3.857739 5.358463 3.839978 5.138891 c
3.830442 5.021761 l
3.810462 4.779471 3.785685 4.500609 3.731205 4.261164 c
3.730906 4.259850 l
5.284881 2.563602 7.518231 1.500000 10.000000 1.500000 c
11.577014 1.500000 13.053720 1.929466 14.319545 2.677820 c
14.221224 2.777969 14.114439 2.895618 14.009129 3.028202 c
13.669640 3.455608 13.224341 4.191939 13.378761 5.060995 c
13.453023 5.478927 13.677018 5.828774 13.893493 6.097116 c
14.114051 6.370518 14.380263 6.623110 14.613050 6.837366 c
14.668355 6.888268 14.721365 6.936671 14.772196 6.983084 c
14.950412 7.145808 15.101837 7.284072 15.231435 7.419845 c
15.404221 7.600864 15.441820 7.682460 15.443790 7.686735 c
15.511713 7.911400 15.428436 8.070621 15.337708 8.140779 c
15.292102 8.176043 15.230948 8.201571 15.147898 8.202232 c
15.064073 8.202900 14.928219 8.177752 14.746777 8.062835 c
14.537054 7.930006 14.232018 7.847993 13.911026 7.977239 c
13.643642 8.084899 13.495515 8.290975 13.424360 8.408617 c
13.280478 8.646499 13.199624 8.954817 13.146976 9.180877 c
13.106362 9.355261 13.067616 9.553251 13.032258 9.733932 c
13.018108 9.806237 13.004500 9.875771 12.991533 9.939910 c
12.941022 10.189741 12.898354 10.368218 12.857431 10.479053 c
12.856843 10.480482 12.851788 10.492748 12.838216 10.517543 c
12.823483 10.544457 12.802644 10.579025 12.774174 10.622349 c
12.716190 10.710581 12.640428 10.814299 12.546493 10.938749 c
12.512385 10.983936 12.475714 11.032014 12.437285 11.082394 c
12.276200 11.293579 12.084242 11.545244 11.920969 11.794048 c
11.725189 12.092388 11.503861 12.482321 11.433911 12.898157 c
11.396839 13.118542 11.397423 13.373061 11.488866 13.631610 c
11.582505 13.896370 11.753467 14.114110 11.975435 14.280597 c
12.458843 14.643174 13.168970 15.453171 13.798772 16.239641 c
14.086361 16.598770 14.343374 16.935246 14.534719 17.190622 c
13.222366 18.019987 11.667240 18.500000 10.000000 18.500000 c
h
15.727353 16.280794 m
15.529826 16.017342 15.265779 15.671862 14.969622 15.302032 c
14.367900 14.550627 13.570269 13.617192 12.920100 13.114614 c
12.945479 13.015734 13.020371 12.852727 13.175053 12.617016 c
13.306167 12.417215 13.456026 12.220543 13.614124 12.013055 c
13.656691 11.957191 13.700173 11.900127 13.743729 11.842422 c
13.916128 11.614019 14.155027 11.295321 14.264583 10.998598 c
14.350787 10.765120 14.412687 10.480006 14.461784 10.237164 c
14.479100 10.151520 14.495111 10.069643 14.510527 9.990811 c
14.536025 9.860416 14.559895 9.738358 14.585339 9.621376 c
15.187048 9.793123 15.787111 9.689411 16.255274 9.327401 c
16.863905 8.856771 17.118000 8.041076 16.879692 7.252826 c
16.770346 6.891145 16.515705 6.592863 16.316484 6.384149 c
16.147512 6.207124 15.944934 6.022339 15.761238 5.854778 c
15.715802 5.813333 15.671200 5.772646 15.628872 5.733688 c
15.398922 5.522042 15.205485 5.334450 15.060962 5.155299 c
14.912354 4.971087 14.865835 4.856014 14.855629 4.798573 c
14.816802 4.580065 14.923186 4.289124 15.183693 3.961153 c
15.301805 3.812452 15.427599 3.687178 15.525196 3.598549 c
15.536726 3.588078 15.547768 3.578207 15.558244 3.568960 c
17.360012 5.127576 18.500000 7.430659 18.500000 10.000000 c
18.500000 12.488004 17.431046 14.726340 15.727353 16.280794 c
h
1.500000 10.000000 m
1.500000 8.601643 1.837670 7.282152 2.435920 6.118621 c
2.520806 6.676047 2.697947 7.366606 3.183541 7.886808 c
3.783359 8.529375 4.519145 8.649875 4.981673 8.725623 c
5.027948 8.733203 5.071755 8.740378 5.112145 8.747540 c
5.359830 8.791461 5.503073 8.830262 5.613584 8.890469 c
5.702090 8.938686 5.801398 9.018201 5.901872 9.211002 c
5.916738 9.239530 5.944188 9.318548 5.906326 9.536173 c
5.873906 9.722527 5.813122 9.917411 5.733576 10.172447 c
5.714817 10.232594 5.694809 10.296745 5.674091 10.364261 c
5.488935 10.967622 5.193007 11.966541 5.794037 12.879015 c
6.315677 13.670959 7.154699 13.873423 7.687307 14.001944 c
7.745055 14.015879 7.799201 14.028945 7.848949 14.041800 c
8.411874 14.187244 8.732245 14.322063 8.956565 14.799735 c
9.251945 15.428725 9.124854 16.284683 8.810515 17.119806 c
8.661468 17.515793 8.486593 17.863750 8.348099 18.113476 c
8.304624 18.191868 8.265136 18.259853 8.231707 18.315813 c
4.385974 17.502075 1.500000 14.088065 1.500000 10.000000 c
h
f
n
Q
endstream
endobj
3 0 obj
5594
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
0000005684 00000 n
0000005707 00000 n
0000005880 00000 n
0000005954 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
6013
%%EOF

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x38",
"green" : "0x29",
"red" : "0x2B"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xF9",
"green" : "0xF5",
"red" : "0xF5"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "chat.warning.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View 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 2.000000 1.858978 cm
0.000000 0.000000 0.000000 scn
10.000000 15.641022 m
10.414213 15.641022 10.750000 15.305235 10.750000 14.891022 c
10.750000 8.641022 l
10.750000 8.226809 10.414213 7.891022 10.000000 7.891022 c
9.585787 7.891022 9.250000 8.226809 9.250000 8.641022 c
9.250000 14.891022 l
9.250000 15.305235 9.585787 15.641022 10.000000 15.641022 c
h
10.000000 4.643219 m
10.552285 4.643219 11.000000 5.090935 11.000000 5.643219 c
11.000000 6.195504 10.552285 6.643219 10.000000 6.643219 c
9.447715 6.643219 9.000000 6.195504 9.000000 5.643219 c
9.000000 5.090935 9.447715 4.643219 10.000000 4.643219 c
h
10.000000 20.141022 m
15.522848 20.141022 20.000000 15.663870 20.000000 10.141022 c
20.000000 4.618174 15.522848 0.141022 10.000000 0.141022 c
8.381707 0.141022 6.817824 0.526447 5.412859 1.253002 c
1.587041 0.185684 l
0.922123 0.000010 0.232581 0.388512 0.046906 1.053431 c
-0.014536 1.273458 -0.014506 1.506115 0.046948 1.725969 c
1.114612 5.548796 l
0.386366 6.955047 0.000000 8.520757 0.000000 10.141022 c
0.000000 15.663870 4.477152 20.141022 10.000000 20.141022 c
h
10.000000 18.641022 m
5.305580 18.641022 1.500000 14.835442 1.500000 10.141022 c
1.500000 8.671413 1.872775 7.257639 2.573033 6.003563 c
2.723677 5.733776 l
1.610960 1.749634 l
5.597552 2.861805 l
5.867086 2.711519 l
7.120057 2.012886 8.532184 1.641022 10.000000 1.641022 c
14.694420 1.641022 18.500000 5.446602 18.500000 10.141022 c
18.500000 14.835442 14.694420 18.641022 10.000000 18.641022 c
h
f
n
Q
endstream
endobj
3 0 obj
1552
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
0000001642 00000 n
0000001665 00000 n
0000001838 00000 n
0000001912 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
1971
%%EOF

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "emoji.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -0,0 +1,99 @@
%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 1.998444 1.997925 cm
0.000000 0.000000 0.000000 scn
10.001551 20.003113 m
15.525254 20.003113 20.003101 15.525267 20.003101 10.001562 c
20.003101 4.477859 15.525254 0.000013 10.001551 0.000013 c
4.477847 0.000013 0.000000 4.477859 0.000000 10.001562 c
0.000000 15.525267 4.477847 20.003113 10.001551 20.003113 c
h
10.001551 18.503113 m
5.306274 18.503113 1.500000 14.696838 1.500000 10.001562 c
1.500000 5.306286 5.306274 1.500013 10.001551 1.500013 c
14.696827 1.500013 18.503101 5.306286 18.503101 10.001562 c
18.503101 14.696838 14.696827 18.503113 10.001551 18.503113 c
h
6.463291 7.218245 m
7.312427 6.140525 8.603443 5.499995 10.001535 5.499995 c
11.397759 5.499995 12.687231 6.138799 13.536489 7.214072 c
13.793221 7.539129 14.264852 7.594518 14.589909 7.337786 c
14.914966 7.081055 14.970354 6.609422 14.713623 6.284365 c
13.582860 4.852667 11.861678 3.999996 10.001535 3.999996 c
8.138899 3.999996 6.415668 4.854965 5.285066 6.289920 c
5.028717 6.615278 5.084659 7.086845 5.410017 7.343195 c
5.735374 7.599545 6.206941 7.543602 6.463291 7.218245 c
h
7.001998 13.250921 m
7.691962 13.250921 8.251287 12.691595 8.251287 12.001632 c
8.251287 11.311668 7.691962 10.752343 7.001998 10.752343 c
6.312035 10.752343 5.752709 11.311668 5.752709 12.001632 c
5.752709 12.691595 6.312035 13.250921 7.001998 13.250921 c
h
13.001999 13.250921 m
13.691962 13.250921 14.251287 12.691595 14.251287 12.001632 c
14.251287 11.311668 13.691962 10.752343 13.001999 10.752343 c
12.312036 10.752343 11.752709 11.311668 11.752709 12.001632 c
11.752709 12.691595 12.312036 13.250921 13.001999 13.250921 c
h
f
n
Q
endstream
endobj
3 0 obj
1663
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
0000001753 00000 n
0000001776 00000 n
0000001949 00000 n
0000002023 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
2082
%%EOF

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "media.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -0,0 +1,111 @@
%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 3.000000 3.000000 cm
0.000000 0.000000 0.000000 scn
14.750000 18.000000 m
16.544926 18.000000 18.000000 16.544926 18.000000 14.750000 c
18.000000 3.250000 l
18.000000 1.455074 16.544926 0.000000 14.750000 0.000000 c
3.250000 0.000000 l
1.455075 0.000000 0.000000 1.455074 0.000000 3.250000 c
0.000000 14.750000 l
0.000000 16.544926 1.455075 18.000000 3.250000 18.000000 c
14.750000 18.000000 l
h
15.330538 1.598593 m
9.524668 7.285182 l
9.259618 7.544744 8.850125 7.568357 8.558795 7.356009 c
8.475204 7.285225 l
2.668451 1.598949 l
2.850401 1.534863 3.046129 1.500000 3.250000 1.500000 c
14.750000 1.500000 l
14.953493 1.500000 15.148874 1.534733 15.330538 1.598593 c
9.524668 7.285182 l
15.330538 1.598593 l
h
14.750000 16.500000 m
3.250000 16.500000 l
2.283502 16.500000 1.500000 15.716498 1.500000 14.750000 c
1.500000 3.250000 l
1.500000 3.041599 1.536428 2.841706 1.603264 2.656342 c
7.425784 8.357008 l
8.258866 9.172708 9.567461 9.211498 10.445769 8.473416 c
10.574176 8.356878 l
16.396372 2.655334 l
16.463440 2.840982 16.500000 3.041222 16.500000 3.250000 c
16.500000 14.750000 l
16.500000 15.716498 15.716498 16.500000 14.750000 16.500000 c
h
12.252115 14.500000 m
13.495924 14.500000 14.504230 13.491693 14.504230 12.247885 c
14.504230 11.004076 13.495924 9.995770 12.252115 9.995770 c
11.008307 9.995770 10.000000 11.004076 10.000000 12.247885 c
10.000000 13.491693 11.008307 14.500000 12.252115 14.500000 c
h
12.252115 13.000000 m
11.836734 13.000000 11.500000 12.663266 11.500000 12.247885 c
11.500000 11.832503 11.836734 11.495770 12.252115 11.495770 c
12.667497 11.495770 13.004230 11.832503 13.004230 12.247885 c
13.004230 12.663266 12.667497 13.000000 12.252115 13.000000 c
h
f
n
Q
endstream
endobj
3 0 obj
1768
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
0000001858 00000 n
0000001881 00000 n
0000002054 00000 n
0000002128 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
2187
%%EOF

View File

@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "poll.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -0,0 +1,113 @@
%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 2.000000 1.998138 cm
0.000000 0.000000 0.000000 scn
9.751870 20.002289 m
11.271687 20.002289 12.503741 18.770235 12.503741 17.250418 c
12.503741 2.751883 l
12.503741 1.232067 11.271687 0.000013 9.751870 0.000013 c
8.232054 0.000013 7.000000 1.232067 7.000000 2.751883 c
7.000000 17.250418 l
7.000000 18.770235 8.232054 20.002289 9.751870 20.002289 c
h
16.751871 15.002289 m
18.271687 15.002289 19.503740 13.770235 19.503740 12.250419 c
19.503740 2.751883 l
19.503740 1.232067 18.271687 0.000013 16.751871 0.000013 c
15.232055 0.000013 14.000000 1.232067 14.000000 2.751883 c
14.000000 12.250419 l
14.000000 13.770235 15.232055 15.002289 16.751871 15.002289 c
h
2.751871 10.002289 m
4.271687 10.002289 5.503741 8.770235 5.503741 7.250419 c
5.503741 2.751883 l
5.503741 1.232067 4.271687 0.000013 2.751871 0.000013 c
1.232054 0.000013 0.000000 1.232067 0.000000 2.751883 c
0.000000 7.250419 l
0.000000 8.770235 1.232054 10.002289 2.751871 10.002289 c
h
9.751870 18.502289 m
9.060481 18.502289 8.500000 17.941807 8.500000 17.250418 c
8.500000 2.751883 l
8.500000 2.060493 9.060481 1.500013 9.751870 1.500013 c
10.443259 1.500013 11.003741 2.060493 11.003741 2.751883 c
11.003741 17.250418 l
11.003741 17.941807 10.443259 18.502289 9.751870 18.502289 c
h
16.751871 13.502289 m
16.060482 13.502289 15.500000 12.941808 15.500000 12.250419 c
15.500000 2.751883 l
15.500000 2.060493 16.060482 1.500013 16.751871 1.500013 c
17.443260 1.500013 18.003740 2.060493 18.003740 2.751883 c
18.003740 12.250419 l
18.003740 12.941808 17.443260 13.502289 16.751871 13.502289 c
h
2.751871 8.502289 m
2.060482 8.502289 1.500000 7.941808 1.500000 7.250419 c
1.500000 2.751883 l
1.500000 2.060493 2.060482 1.500013 2.751871 1.500013 c
3.443260 1.500013 4.003741 2.060493 4.003741 2.751883 c
4.003741 7.250419 l
4.003741 7.941808 3.443260 8.502289 2.751871 8.502289 c
h
f
n
Q
endstream
endobj
3 0 obj
1919
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
0000002009 00000 n
0000002032 00000 n
0000002205 00000 n
0000002279 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
2338
%%EOF

View File

@ -129,6 +129,14 @@ public enum Asset {
public static let star = ImageAsset(name: "ObjectsAndTools/star")
}
public enum Scene {
public enum Compose {
public static let buttonTint = ColorAsset(name: "Scene/Compose/button.tint")
public static let chatWarning = ImageAsset(name: "Scene/Compose/chat.warning")
public static let earth = ImageAsset(name: "Scene/Compose/earth")
public static let emoji = ImageAsset(name: "Scene/Compose/emoji")
public static let media = ImageAsset(name: "Scene/Compose/media")
public static let poll = ImageAsset(name: "Scene/Compose/poll")
}
public enum Discovery {
public static let profileCardBackground = ColorAsset(name: "Scene/Discovery/profile.card.background")
}

View File

@ -102,7 +102,7 @@ extension Mastodon.Entity {
}
extension Mastodon.Entity.Status {
public enum Visibility: RawRepresentable, Codable {
public enum Visibility: RawRepresentable, Codable, Hashable {
case `public`
case unlisted
case `private`

View File

@ -9,6 +9,7 @@ import os.log
import UIKit
import SwiftUI
import Combine
import MastodonCore
public final class ComposeContentViewController: UIViewController {
@ -16,6 +17,7 @@ public final class ComposeContentViewController: UIViewController {
var disposeBag = Set<AnyCancellable>()
public var viewModel: ComposeContentViewModel!
let composeContentToolbarViewModel = ComposeContentToolbarView.ViewModel()
let tableView: ComposeTableView = {
let tableView = ComposeTableView()
@ -25,6 +27,10 @@ public final class ComposeContentViewController: UIViewController {
tableView.tableFooterView = UIView()
return tableView
}()
lazy var composeContentToolbarView = ComposeContentToolbarView(viewModel: composeContentToolbarViewModel)
var composeContentToolbarViewBottomLayoutConstraint: NSLayoutConstraint!
let composeContentToolbarBackgroundView = UIView()
deinit {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
@ -36,6 +42,17 @@ extension ComposeContentViewController {
public override func viewDidLoad() {
super.viewDidLoad()
// setup view
self.setupBackgroundColor(theme: ThemeService.shared.currentTheme.value)
ThemeService.shared.currentTheme
.receive(on: RunLoop.main)
.sink { [weak self] theme in
guard let self = self else { return }
self.setupBackgroundColor(theme: theme)
}
.store(in: &disposeBag)
// setup tableView
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
NSLayoutConstraint.activate([
@ -48,6 +65,110 @@ extension ComposeContentViewController {
tableView.delegate = self
viewModel.setupDataSource(tableView: tableView)
let toolbarHostingView = UIHostingController(rootView: composeContentToolbarView)
toolbarHostingView.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(toolbarHostingView.view)
composeContentToolbarViewBottomLayoutConstraint = view.bottomAnchor.constraint(equalTo: toolbarHostingView.view.bottomAnchor)
NSLayoutConstraint.activate([
toolbarHostingView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
toolbarHostingView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
composeContentToolbarViewBottomLayoutConstraint,
toolbarHostingView.view.heightAnchor.constraint(equalToConstant: ComposeContentToolbarView.toolbarHeight),
])
toolbarHostingView.view.preservesSuperviewLayoutMargins = true
//composeToolbarView.delegate = self
composeContentToolbarBackgroundView.translatesAutoresizingMaskIntoConstraints = false
view.insertSubview(composeContentToolbarBackgroundView, belowSubview: toolbarHostingView.view)
NSLayoutConstraint.activate([
composeContentToolbarBackgroundView.topAnchor.constraint(equalTo: toolbarHostingView.view.topAnchor),
composeContentToolbarBackgroundView.leadingAnchor.constraint(equalTo: toolbarHostingView.view.leadingAnchor),
composeContentToolbarBackgroundView.trailingAnchor.constraint(equalTo: toolbarHostingView.view.trailingAnchor),
view.bottomAnchor.constraint(equalTo: composeContentToolbarBackgroundView.bottomAnchor),
])
let keyboardHasShortcutBar = CurrentValueSubject<Bool, Never>(traitCollection.userInterfaceIdiom == .pad) // update default value later
let keyboardEventPublishers = Publishers.CombineLatest3(
KeyboardResponderService.shared.isShow,
KeyboardResponderService.shared.state,
KeyboardResponderService.shared.endFrame
)
// Publishers.CombineLatest3(
// viewModel.$isCustomEmojiComposing,
// )
keyboardEventPublishers
.sink(receiveValue: { [weak self] keyboardEvents in
guard let self = self else { return }
let (isShow, state, endFrame) = keyboardEvents
// switch self.traitCollection.userInterfaceIdiom {
// case .pad:
// keyboardHasShortcutBar.value = state != .floating
// default:
// keyboardHasShortcutBar.value = false
// }
//
let extraMargin: CGFloat = {
var margin = ComposeContentToolbarView.toolbarHeight
// if autoCompleteInfo != nil {
//// margin += ComposeViewController.minAutoCompleteVisibleHeight
// }
return margin
}()
//
guard isShow, state == .dock else {
self.tableView.contentInset.bottom = extraMargin
self.tableView.verticalScrollIndicatorInsets.bottom = extraMargin
// if let superView = self.autoCompleteViewController.tableView.superview {
// let autoCompleteTableViewBottomInset: CGFloat = {
// let tableViewFrameInWindow = superView.convert(self.autoCompleteViewController.tableView.frame, to: nil)
// let padding = tableViewFrameInWindow.maxY + self.composeToolbarView.frame.height + AutoCompleteViewController.chevronViewHeight - self.view.frame.maxY
// return max(0, padding)
// }()
// self.autoCompleteViewController.tableView.contentInset.bottom = autoCompleteTableViewBottomInset
// self.autoCompleteViewController.tableView.verticalScrollIndicatorInsets.bottom = autoCompleteTableViewBottomInset
// }
UIView.animate(withDuration: 0.3) {
self.composeContentToolbarViewBottomLayoutConstraint.constant = self.view.safeAreaInsets.bottom
if self.view.window != nil {
self.view.layoutIfNeeded()
}
}
return
}
// isShow AND dock state
// self.systemKeyboardHeight = endFrame.height
// adjust inset for auto-complete
// let autoCompleteTableViewBottomInset: CGFloat = {
// guard let superview = self.autoCompleteViewController.tableView.superview else { return .zero }
// let tableViewFrameInWindow = superview.convert(self.autoCompleteViewController.tableView.frame, to: nil)
// let padding = tableViewFrameInWindow.maxY + self.composeToolbarView.frame.height + AutoCompleteViewController.chevronViewHeight - endFrame.minY
// return max(0, padding)
// }()
// self.autoCompleteViewController.tableView.contentInset.bottom = autoCompleteTableViewBottomInset
// self.autoCompleteViewController.tableView.verticalScrollIndicatorInsets.bottom = autoCompleteTableViewBottomInset
// adjust inset for tableView
let contentFrame = self.view.convert(self.tableView.frame, to: nil)
let padding = contentFrame.maxY + extraMargin - endFrame.minY
guard padding > 0 else {
self.tableView.contentInset.bottom = self.view.safeAreaInsets.bottom + extraMargin
self.tableView.verticalScrollIndicatorInsets.bottom = self.view.safeAreaInsets.bottom + extraMargin
return
}
self.tableView.contentInset.bottom = padding - self.view.safeAreaInsets.bottom
self.tableView.verticalScrollIndicatorInsets.bottom = padding - self.view.safeAreaInsets.bottom
UIView.animate(withDuration: 0.3) {
self.composeContentToolbarViewBottomLayoutConstraint.constant = endFrame.height
self.view.layoutIfNeeded()
}
})
.store(in: &disposeBag)
// setup snap behavior
Publishers.CombineLatest(
@ -90,6 +211,20 @@ extension ComposeContentViewController {
}
}
extension ComposeContentViewController {
private func setupBackgroundColor(theme: Theme) {
let backgroundColor = UIColor(dynamicProvider: { traitCollection in
switch traitCollection.userInterfaceStyle {
case .light: return .systemBackground
default: return theme.systemElevatedBackgroundColor
}
})
view.backgroundColor = backgroundColor
tableView.backgroundColor = backgroundColor
composeContentToolbarBackgroundView.backgroundColor = theme.composeToolbarBackgroundColor
}
}
// MARK: - UIScrollViewDelegate
extension ComposeContentViewController {
public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

View File

@ -0,0 +1,57 @@
//
// ComposeContentToolbarView.swift
//
//
// Created by MainasuK on 22/10/18.
//
import SwiftUI
import MastodonCore
import MastodonAsset
import MastodonSDK
extension ComposeContentToolbarView {
class ViewModel: ObservableObject {
// input
@Published var backgroundColor = ThemeService.shared.currentTheme.value.composeToolbarBackgroundColor
@Published var visibility: Mastodon.Entity.Status.Visibility = .public
var allVisibilities: [Mastodon.Entity.Status.Visibility] {
return [.public, .private, .direct]
}
// output
init() {
ThemeService.shared.currentTheme
.map { $0.composeToolbarBackgroundColor }
.assign(to: &$backgroundColor)
}
}
}
extension ComposeContentToolbarView.ViewModel {
enum Action: CaseIterable {
case attachment
case poll
case emoji
case contentWarning
case visibility
var image: UIImage {
switch self {
case .attachment:
return Asset.Scene.Compose.media.image
case .poll:
return Asset.Scene.Compose.poll.image
case .emoji:
return Asset.Scene.Compose.emoji.image
case .contentWarning:
return Asset.Scene.Compose.chatWarning.image
case .visibility:
return Asset.Scene.Compose.earth.image
}
}
}
}

View File

@ -0,0 +1,82 @@
//
// ComposeContentToolbarView.swift
//
//
// Created by MainasuK on 22/10/18.
//
import SwiftUI
import MastodonAsset
struct ComposeContentToolbarView: View {
static var toolbarHeight: CGFloat { 48 }
@ObservedObject var viewModel: ViewModel
var body: some View {
HStack(spacing: .zero) {
ForEach(ComposeContentToolbarView.ViewModel.Action.allCases, id: \.self) { action in
switch action {
case .attachment:
Menu {
Button {
} label: {
Label("Photo Library", systemImage: "photo.on.rectangle")
}
Button {
} label: {
Label("Camera", systemImage: "camera")
}
Button {
} label: {
Label("Browse", systemImage: "ellipsis")
}
} label: {
label(for: action)
}
.frame(width: 48, height: 48)
case .visibility:
Menu {
Picker(selection: $viewModel.visibility) {
ForEach(viewModel.allVisibilities, id: \.self) { visibility in
Label(visibility.rawValue, systemImage: "photo.on.rectangle")
}
} label: {
Text("Select Visibility")
}
} label: {
label(for: action)
}
.frame(width: 48, height: 48)
default:
Button {
} label: {
label(for: action)
}
.frame(width: 48, height: 48)
}
}
Spacer()
Text("Hello")
}
.padding(.leading, 4) // 4 + 12 = 16
.padding(.trailing, 16)
.frame(height: ComposeContentToolbarView.toolbarHeight)
.background(Color(viewModel.backgroundColor))
}
}
extension ComposeContentToolbarView {
func label(for action: ComposeContentToolbarView.ViewModel.Action) -> some View {
Image(uiImage: action.image.withRenderingMode(.alwaysTemplate))
.foregroundColor(Color(Asset.Scene.Compose.buttonTint.color))
.frame(width: 24, height: 24, alignment: .center)
}
}