mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-11 13:59:13 +00:00
Refine polls UI in the timeline (#1474)
* Add summary view in PollRoomTimelineView * Add selectedPollOption action * Handle undisclosed polls * Add more logics in PollRoomTimelineView * Refine ended poll UI * Refine poll layout * More UI refinements * Fix layout issue * Refine progress bar * Add poll mocks and UI tests * Cleanup
This commit is contained in:
parent
f64159670b
commit
25f66d2557
@ -64,6 +64,7 @@
|
|||||||
157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */; };
|
157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */; };
|
||||||
158A2D528CC78C4E7A8ED608 /* MockRoomTimelineControllerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71556206CD5E8B1F53F07178 /* MockRoomTimelineControllerFactory.swift */; };
|
158A2D528CC78C4E7A8ED608 /* MockRoomTimelineControllerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71556206CD5E8B1F53F07178 /* MockRoomTimelineControllerFactory.swift */; };
|
||||||
167D00CAA13FAFB822298021 /* MediaProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A81CCC2516D9CF9322DF01 /* MediaProviderTests.swift */; };
|
167D00CAA13FAFB822298021 /* MediaProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A81CCC2516D9CF9322DF01 /* MediaProviderTests.swift */; };
|
||||||
|
16CBD087038DE3815CDA512C /* PollMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = D38391154120264910D19528 /* PollMock.swift */; };
|
||||||
1702981A8085BE4FB0EC001B /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = D33116993D54FADC0C721C1F /* Application.swift */; };
|
1702981A8085BE4FB0EC001B /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = D33116993D54FADC0C721C1F /* Application.swift */; };
|
||||||
172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */; };
|
172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */; };
|
||||||
1772AFA97DDA51CF1B293A78 /* RoomAttachmentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6A9B9DFEE964962C179DE3 /* RoomAttachmentPicker.swift */; };
|
1772AFA97DDA51CF1B293A78 /* RoomAttachmentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E6A9B9DFEE964962C179DE3 /* RoomAttachmentPicker.swift */; };
|
||||||
@ -1396,6 +1397,7 @@
|
|||||||
D263254AFE5B7993FFBBF324 /* NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NSE.entitlements; sourceTree = "<group>"; };
|
D263254AFE5B7993FFBBF324 /* NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NSE.entitlements; sourceTree = "<group>"; };
|
||||||
D316BB02636AF2174F2580E6 /* SoftLogoutScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
D316BB02636AF2174F2580E6 /* SoftLogoutScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
D33116993D54FADC0C721C1F /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
D33116993D54FADC0C721C1F /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
||||||
|
D38391154120264910D19528 /* PollMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollMock.swift; sourceTree = "<group>"; };
|
||||||
D39D7F513A36C9C1951DB44C /* AnalyticsSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreen.swift; sourceTree = "<group>"; };
|
D39D7F513A36C9C1951DB44C /* AnalyticsSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreen.swift; sourceTree = "<group>"; };
|
||||||
D3D455BC2423D911A62ACFB2 /* NSELogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSELogger.swift; sourceTree = "<group>"; };
|
D3D455BC2423D911A62ACFB2 /* NSELogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSELogger.swift; sourceTree = "<group>"; };
|
||||||
D49B9785E3AD7D1C15A29F2F /* MediaSourceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSourceProxy.swift; sourceTree = "<group>"; };
|
D49B9785E3AD7D1C15A29F2F /* MediaSourceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSourceProxy.swift; sourceTree = "<group>"; };
|
||||||
@ -1913,6 +1915,7 @@
|
|||||||
children = (
|
children = (
|
||||||
69CB8242D69B7E4D0B32E18D /* AggregatedReactionMock.swift */,
|
69CB8242D69B7E4D0B32E18D /* AggregatedReactionMock.swift */,
|
||||||
382B50F7E379B3DBBD174364 /* NotificationSettingsProxyMock.swift */,
|
382B50F7E379B3DBBD174364 /* NotificationSettingsProxyMock.swift */,
|
||||||
|
D38391154120264910D19528 /* PollMock.swift */,
|
||||||
36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */,
|
36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */,
|
||||||
F5D1BAA90F3A073D91B4F16B /* RoomNotificationSettingsProxyMock.swift */,
|
F5D1BAA90F3A073D91B4F16B /* RoomNotificationSettingsProxyMock.swift */,
|
||||||
1ABDE6F66532CBEB0E016F94 /* RoomProxyMock.swift */,
|
1ABDE6F66532CBEB0E016F94 /* RoomProxyMock.swift */,
|
||||||
@ -4515,6 +4518,7 @@
|
|||||||
962A4F8AD6312804E2C6BB6E /* PhotoLibraryPicker.swift in Sources */,
|
962A4F8AD6312804E2C6BB6E /* PhotoLibraryPicker.swift in Sources */,
|
||||||
9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */,
|
9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */,
|
||||||
1BA04D05EBC6646958B1BE60 /* PlaceholderScreenCoordinator.swift in Sources */,
|
1BA04D05EBC6646958B1BE60 /* PlaceholderScreenCoordinator.swift in Sources */,
|
||||||
|
16CBD087038DE3815CDA512C /* PollMock.swift in Sources */,
|
||||||
6B4BF4A6450F55939B49FAEF /* PollOptionView.swift in Sources */,
|
6B4BF4A6450F55939B49FAEF /* PollOptionView.swift in Sources */,
|
||||||
864C0D3A4077BF433DBC691F /* PollRoomTimelineItem.swift in Sources */,
|
864C0D3A4077BF433DBC691F /* PollRoomTimelineItem.swift in Sources */,
|
||||||
153E22E8227F46545E5D681C /* PollRoomTimelineView.swift in Sources */,
|
153E22E8227F46545E5D681C /* PollRoomTimelineView.swift in Sources */,
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"info" : {
|
|
||||||
"author" : "xcode",
|
|
||||||
"version" : 1
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
%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 4.000000 4.000000 cm
|
|
||||||
0.196078 0.196078 0.196078 scn
|
|
||||||
8.000000 0.000000 m
|
|
||||||
9.100000 0.000000 10.000000 0.900000 10.000000 2.000000 c
|
|
||||||
10.000000 14.000000 l
|
|
||||||
10.000000 15.100000 9.100000 16.000000 8.000000 16.000000 c
|
|
||||||
6.900000 16.000000 6.000000 15.100000 6.000000 14.000000 c
|
|
||||||
6.000000 2.000000 l
|
|
||||||
6.000000 0.900000 6.900000 0.000000 8.000000 0.000000 c
|
|
||||||
h
|
|
||||||
2.000000 0.000000 m
|
|
||||||
3.100000 0.000000 4.000000 0.900000 4.000000 2.000000 c
|
|
||||||
4.000000 6.000000 l
|
|
||||||
4.000000 7.100000 3.100000 8.000000 2.000000 8.000000 c
|
|
||||||
0.900000 8.000000 0.000000 7.100000 0.000000 6.000000 c
|
|
||||||
0.000000 2.000000 l
|
|
||||||
0.000000 0.900000 0.900000 0.000000 2.000000 0.000000 c
|
|
||||||
h
|
|
||||||
12.000000 9.000000 m
|
|
||||||
12.000000 2.000000 l
|
|
||||||
12.000000 0.900000 12.900000 0.000000 14.000000 0.000000 c
|
|
||||||
15.100000 0.000000 16.000000 0.900000 16.000000 2.000000 c
|
|
||||||
16.000000 9.000000 l
|
|
||||||
16.000000 10.100000 15.100000 11.000000 14.000000 11.000000 c
|
|
||||||
12.900000 11.000000 12.000000 10.100000 12.000000 9.000000 c
|
|
||||||
h
|
|
||||||
f
|
|
||||||
n
|
|
||||||
Q
|
|
||||||
|
|
||||||
endstream
|
|
||||||
endobj
|
|
||||||
|
|
||||||
3 0 obj
|
|
||||||
1014
|
|
||||||
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
|
|
||||||
0000001104 00000 n
|
|
||||||
0000001127 00000 n
|
|
||||||
0000001300 00000 n
|
|
||||||
0000001374 00000 n
|
|
||||||
trailer
|
|
||||||
<< /ID [ (some) (id) ]
|
|
||||||
/Root 6 0 R
|
|
||||||
/Size 7
|
|
||||||
>>
|
|
||||||
startxref
|
|
||||||
1433
|
|
||||||
%%EOF
|
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "equalizer.pdf",
|
"filename" : "timeline-poll.pdf",
|
||||||
"idiom" : "universal"
|
"idiom" : "universal"
|
||||||
}
|
}
|
||||||
],
|
],
|
121
ElementX/Resources/Assets.xcassets/images/timeline/timeline-poll.imageset/timeline-poll.pdf
vendored
Normal file
121
ElementX/Resources/Assets.xcassets/images/timeline/timeline-poll.imageset/timeline-poll.pdf
vendored
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
%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.750000 2.750000 cm
|
||||||
|
0.105882 0.113725 0.133333 scn
|
||||||
|
4.583333 3.666666 m
|
||||||
|
4.843056 3.666666 5.060764 3.754514 5.236458 3.930208 c
|
||||||
|
5.412153 4.105903 5.500000 4.323611 5.500000 4.583333 c
|
||||||
|
5.500000 9.166666 l
|
||||||
|
5.500000 9.426389 5.412153 9.644096 5.236458 9.819792 c
|
||||||
|
5.060764 9.995485 4.843056 10.083333 4.583333 10.083333 c
|
||||||
|
4.323611 10.083333 4.105903 9.995485 3.930208 9.819792 c
|
||||||
|
3.754514 9.644096 3.666667 9.426389 3.666667 9.166666 c
|
||||||
|
3.666667 4.583333 l
|
||||||
|
3.666667 4.323611 3.754514 4.105903 3.930208 3.930208 c
|
||||||
|
4.105903 3.754514 4.323611 3.666666 4.583333 3.666666 c
|
||||||
|
h
|
||||||
|
8.250000 3.666666 m
|
||||||
|
8.509723 3.666666 8.727430 3.754514 8.903125 3.930208 c
|
||||||
|
9.078819 4.105903 9.166667 4.323611 9.166667 4.583333 c
|
||||||
|
9.166667 11.916666 l
|
||||||
|
9.166667 12.176389 9.078819 12.394097 8.903125 12.569792 c
|
||||||
|
8.727430 12.745486 8.509723 12.833333 8.250000 12.833333 c
|
||||||
|
7.990278 12.833333 7.772570 12.745486 7.596875 12.569792 c
|
||||||
|
7.421181 12.394097 7.333333 12.176389 7.333333 11.916666 c
|
||||||
|
7.333333 4.583333 l
|
||||||
|
7.333333 4.323611 7.421181 4.105903 7.596875 3.930208 c
|
||||||
|
7.772570 3.754514 7.990278 3.666666 8.250000 3.666666 c
|
||||||
|
h
|
||||||
|
11.916667 3.666666 m
|
||||||
|
12.176389 3.666666 12.394097 3.754514 12.569792 3.930208 c
|
||||||
|
12.745486 4.105903 12.833334 4.323611 12.833334 4.583333 c
|
||||||
|
12.833334 6.416666 l
|
||||||
|
12.833334 6.676389 12.745486 6.894097 12.569792 7.069792 c
|
||||||
|
12.394097 7.245486 12.176389 7.333333 11.916667 7.333333 c
|
||||||
|
11.656944 7.333333 11.439237 7.245486 11.263542 7.069792 c
|
||||||
|
11.087848 6.894097 11.000000 6.676389 11.000000 6.416666 c
|
||||||
|
11.000000 4.583333 l
|
||||||
|
11.000000 4.323611 11.087848 4.105903 11.263542 3.930208 c
|
||||||
|
11.439237 3.754514 11.656944 3.666666 11.916667 3.666666 c
|
||||||
|
h
|
||||||
|
1.833333 0.000000 m
|
||||||
|
1.329167 0.000000 0.897569 0.179514 0.538542 0.538542 c
|
||||||
|
0.179514 0.897569 0.000000 1.329166 0.000000 1.833333 c
|
||||||
|
0.000000 14.666667 l
|
||||||
|
0.000000 15.170834 0.179514 15.602430 0.538542 15.961458 c
|
||||||
|
0.897569 16.320486 1.329167 16.500000 1.833333 16.500000 c
|
||||||
|
14.666667 16.500000 l
|
||||||
|
15.170834 16.500000 15.602431 16.320486 15.961458 15.961458 c
|
||||||
|
16.320486 15.602430 16.500000 15.170834 16.500000 14.666667 c
|
||||||
|
16.500000 1.833333 l
|
||||||
|
16.500000 1.329166 16.320486 0.897569 15.961458 0.538542 c
|
||||||
|
15.602431 0.179514 15.170834 0.000000 14.666667 0.000000 c
|
||||||
|
1.833333 0.000000 l
|
||||||
|
h
|
||||||
|
1.833333 1.833333 m
|
||||||
|
14.666667 1.833333 l
|
||||||
|
14.666667 14.666667 l
|
||||||
|
1.833333 14.666667 l
|
||||||
|
1.833333 1.833333 l
|
||||||
|
h
|
||||||
|
f
|
||||||
|
n
|
||||||
|
Q
|
||||||
|
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj
|
||||||
|
2382
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj
|
||||||
|
<< /Annots []
|
||||||
|
/Type /Page
|
||||||
|
/MediaBox [ 0.000000 0.000000 22.000000 22.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
|
||||||
|
0000002472 00000 n
|
||||||
|
0000002495 00000 n
|
||||||
|
0000002668 00000 n
|
||||||
|
0000002742 00000 n
|
||||||
|
trailer
|
||||||
|
<< /ID [ (some) (id) ]
|
||||||
|
/Root 6 0 R
|
||||||
|
/Size 7
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
2801
|
||||||
|
%%EOF
|
@ -93,6 +93,9 @@
|
|||||||
"common_password" = "Password";
|
"common_password" = "Password";
|
||||||
"common_people" = "People";
|
"common_people" = "People";
|
||||||
"common_permalink" = "Permalink";
|
"common_permalink" = "Permalink";
|
||||||
|
"common_poll_final_votes" = "Final votes: %1$@";
|
||||||
|
"common_poll_total_votes" = "Total votes: %1$@";
|
||||||
|
"common_poll_undisclosed_text" = "Results will show after the poll has ended";
|
||||||
"common_privacy_policy" = "Privacy policy";
|
"common_privacy_policy" = "Privacy policy";
|
||||||
"common_reactions" = "Reactions";
|
"common_reactions" = "Reactions";
|
||||||
"common_refreshing" = "Refreshing…";
|
"common_refreshing" = "Refreshing…";
|
||||||
|
@ -41,8 +41,8 @@ internal enum Asset {
|
|||||||
internal static let locationPin = ImageAsset(name: "images/location-pin")
|
internal static let locationPin = ImageAsset(name: "images/location-pin")
|
||||||
internal static let locationPointerFull = ImageAsset(name: "images/location-pointer-full")
|
internal static let locationPointerFull = ImageAsset(name: "images/location-pointer-full")
|
||||||
internal static let locationPointer = ImageAsset(name: "images/location-pointer")
|
internal static let locationPointer = ImageAsset(name: "images/location-pointer")
|
||||||
internal static let equalizer = ImageAsset(name: "images/equalizer")
|
|
||||||
internal static let timelineComposerSendMessage = ImageAsset(name: "images/timeline-composer-send-message")
|
internal static let timelineComposerSendMessage = ImageAsset(name: "images/timeline-composer-send-message")
|
||||||
|
internal static let timelinePoll = ImageAsset(name: "images/timeline-poll")
|
||||||
internal static let timelineReactionAddMore = ImageAsset(name: "images/timeline-reaction-add-more")
|
internal static let timelineReactionAddMore = ImageAsset(name: "images/timeline-reaction-add-more")
|
||||||
internal static let waitingGradient = ImageAsset(name: "images/waiting-gradient")
|
internal static let waitingGradient = ImageAsset(name: "images/waiting-gradient")
|
||||||
}
|
}
|
||||||
|
@ -208,6 +208,16 @@ public enum L10n {
|
|||||||
public static var commonPeople: String { return L10n.tr("Localizable", "common_people") }
|
public static var commonPeople: String { return L10n.tr("Localizable", "common_people") }
|
||||||
/// Permalink
|
/// Permalink
|
||||||
public static var commonPermalink: String { return L10n.tr("Localizable", "common_permalink") }
|
public static var commonPermalink: String { return L10n.tr("Localizable", "common_permalink") }
|
||||||
|
/// Final votes: %1$@
|
||||||
|
public static func commonPollFinalVotes(_ p1: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "common_poll_final_votes", String(describing: p1))
|
||||||
|
}
|
||||||
|
/// Total votes: %1$@
|
||||||
|
public static func commonPollTotalVotes(_ p1: Any) -> String {
|
||||||
|
return L10n.tr("Localizable", "common_poll_total_votes", String(describing: p1))
|
||||||
|
}
|
||||||
|
/// Results will show after the poll has ended
|
||||||
|
public static var commonPollUndisclosedText: String { return L10n.tr("Localizable", "common_poll_undisclosed_text") }
|
||||||
/// Plural format key: "%#@COUNT@"
|
/// Plural format key: "%#@COUNT@"
|
||||||
public static func commonPollVotesCount(_ p1: Int) -> String {
|
public static func commonPollVotesCount(_ p1: Int) -> String {
|
||||||
return L10n.tr("Localizable", "common_poll_votes_count", p1)
|
return L10n.tr("Localizable", "common_poll_votes_count", p1)
|
||||||
|
90
ElementX/Sources/Mocks/PollMock.swift
Normal file
90
ElementX/Sources/Mocks/PollMock.swift
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2023 New Vector Ltd
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension Poll {
|
||||||
|
static func mock(question: String,
|
||||||
|
pollKind: Poll.Kind = .disclosed,
|
||||||
|
options: [Poll.Option],
|
||||||
|
votes: [String: [String]] = [:],
|
||||||
|
ended: Bool = false) -> Self {
|
||||||
|
.init(question: question,
|
||||||
|
kind: pollKind,
|
||||||
|
maxSelections: 1,
|
||||||
|
options: options,
|
||||||
|
votes: votes,
|
||||||
|
endDate: ended ? Date() : nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var disclosed: Self {
|
||||||
|
mock(question: "What country do you like most?",
|
||||||
|
pollKind: .disclosed,
|
||||||
|
options: [.mock(text: "Italy 🇮🇹", votes: 5, allVotes: 10, isWinning: true),
|
||||||
|
.mock(text: "China 🇨🇳", votes: 3, allVotes: 10),
|
||||||
|
.mock(text: "USA 🇺🇸", votes: 2, allVotes: 10)])
|
||||||
|
}
|
||||||
|
|
||||||
|
static var undisclosed: Self {
|
||||||
|
mock(question: "What country do you like most?",
|
||||||
|
pollKind: .undisclosed,
|
||||||
|
options: [.mock(text: "Italy 🇮🇹", votes: 5, allVotes: 10, isWinning: true),
|
||||||
|
.mock(text: "China 🇨🇳", votes: 3, allVotes: 10, isSelected: true),
|
||||||
|
.mock(text: "USA 🇺🇸", votes: 2, allVotes: 10)])
|
||||||
|
}
|
||||||
|
|
||||||
|
static var endedDisclosed: Self {
|
||||||
|
mock(question: "What country do you like most?",
|
||||||
|
pollKind: .disclosed,
|
||||||
|
options: [.mock(text: "Italy 🇮🇹", votes: 5, allVotes: 10, isWinning: true),
|
||||||
|
.mock(text: "China 🇨🇳", votes: 3, allVotes: 10, isSelected: true),
|
||||||
|
.mock(text: "USA 🇺🇸", votes: 2, allVotes: 10)],
|
||||||
|
ended: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var endedUndisclosed: Self {
|
||||||
|
mock(question: "What country do you like most?",
|
||||||
|
pollKind: .undisclosed,
|
||||||
|
options: [.mock(text: "Italy 🇮🇹", votes: 5, allVotes: 10, isWinning: true),
|
||||||
|
.mock(text: "China 🇨🇳", votes: 3, allVotes: 10, isSelected: true),
|
||||||
|
.mock(text: "USA 🇺🇸", votes: 2, allVotes: 10)],
|
||||||
|
ended: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Poll.Option {
|
||||||
|
static func mock(text: String, votes: Int = 0, allVotes: Int = 0, isSelected: Bool = false, isWinning: Bool = false) -> Self {
|
||||||
|
.init(id: UUID().uuidString,
|
||||||
|
text: text,
|
||||||
|
votes: votes,
|
||||||
|
allVotes: allVotes,
|
||||||
|
isSelected: isSelected,
|
||||||
|
isWinning: isWinning)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PollRoomTimelineItem {
|
||||||
|
static func mock(poll: Poll) -> Self {
|
||||||
|
.init(id: .random,
|
||||||
|
poll: poll,
|
||||||
|
body: "poll",
|
||||||
|
timestamp: "Now",
|
||||||
|
isOutgoing: true,
|
||||||
|
isEditable: false,
|
||||||
|
sender: .init(id: "userID"),
|
||||||
|
properties: .init())
|
||||||
|
}
|
||||||
|
}
|
@ -59,6 +59,7 @@ enum RoomScreenViewAction {
|
|||||||
case toggleReaction(key: String, itemID: TimelineItemIdentifier)
|
case toggleReaction(key: String, itemID: TimelineItemIdentifier)
|
||||||
case sendReadReceiptIfNeeded(TimelineItemIdentifier)
|
case sendReadReceiptIfNeeded(TimelineItemIdentifier)
|
||||||
case paginateBackwards
|
case paginateBackwards
|
||||||
|
case selectedPollOption(poll: Poll, optionID: String)
|
||||||
|
|
||||||
case timelineItemMenu(itemID: TimelineItemIdentifier)
|
case timelineItemMenu(itemID: TimelineItemIdentifier)
|
||||||
case timelineItemMenuAction(itemID: TimelineItemIdentifier, action: TimelineItemMenuAction)
|
case timelineItemMenuAction(itemID: TimelineItemIdentifier, action: TimelineItemMenuAction)
|
||||||
|
@ -139,6 +139,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
if state.swiftUITimelineEnabled {
|
if state.swiftUITimelineEnabled {
|
||||||
renderPendingTimelineItems()
|
renderPendingTimelineItems()
|
||||||
}
|
}
|
||||||
|
case .selectedPollOption:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,19 +18,26 @@ import SwiftUI
|
|||||||
|
|
||||||
struct PollOptionView: View {
|
struct PollOptionView: View {
|
||||||
let pollOption: Poll.Option
|
let pollOption: Poll.Option
|
||||||
|
let showVotes: Bool
|
||||||
|
let isFinalResult: Bool
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(alignment: .top, spacing: 8) {
|
HStack(alignment: .firstTextBaseline, spacing: 12) {
|
||||||
FormRowAccessory(kind: .multipleSelection(isSelected: pollOption.isSelected))
|
FormRowAccessory(kind: .multipleSelection(isSelected: pollOption.isSelected))
|
||||||
|
|
||||||
VStack(spacing: 10) {
|
VStack(spacing: 10) {
|
||||||
HStack(alignment: .lastTextBaseline) {
|
HStack(alignment: .lastTextBaseline) {
|
||||||
Text(pollOption.text)
|
Text(pollOption.text)
|
||||||
|
.font(isFinalWinningOption ? .compound.bodyLGSemibold : .compound.bodyLG)
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
|
.foregroundColor(.compound.textPrimary)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
|
if showVotes {
|
||||||
Text(L10n.commonPollVotesCount(pollOption.votes))
|
Text(L10n.commonPollVotesCount(pollOption.votes))
|
||||||
.font(.compound.bodySM)
|
.font(isFinalWinningOption ? .compound.bodySMSemibold : .compound.bodySM)
|
||||||
.foregroundColor(.compound.textSecondary)
|
.foregroundColor(isFinalWinningOption ? .compound.textPrimary : .compound.textSecondary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progressView
|
progressView
|
||||||
@ -41,8 +48,39 @@ struct PollOptionView: View {
|
|||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private var progressView: some View {
|
private var progressView: some View {
|
||||||
ProgressView(value: Double(pollOption.votes) / Double(pollOption.allVotes))
|
PollProgressView(progress: progress)
|
||||||
.progressViewStyle(LinearProgressViewStyle(tint: .compound.textPrimary))
|
}
|
||||||
|
|
||||||
|
private var progress: Double {
|
||||||
|
switch (showVotes, pollOption.allVotes, pollOption.isSelected) {
|
||||||
|
case (true, let allVotes, _) where allVotes > 0:
|
||||||
|
return Double(pollOption.votes) / Double(allVotes)
|
||||||
|
case (false, _, true):
|
||||||
|
return 1
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var isFinalWinningOption: Bool {
|
||||||
|
pollOption.isWinning && isFinalResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct PollProgressView: View {
|
||||||
|
let progress: Double
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
GeometryReader { geometry in
|
||||||
|
ZStack(alignment: .leading) {
|
||||||
|
Capsule()
|
||||||
|
.foregroundColor(.compound.borderDisabled)
|
||||||
|
|
||||||
|
Capsule()
|
||||||
|
.frame(maxWidth: progress * geometry.size.width)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(height: 6)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,13 +92,28 @@ struct PollOptionView_Previews: PreviewProvider {
|
|||||||
text: "Italian 🇮🇹",
|
text: "Italian 🇮🇹",
|
||||||
votes: 1,
|
votes: 1,
|
||||||
allVotes: 10,
|
allVotes: 10,
|
||||||
isSelected: true))
|
isSelected: true,
|
||||||
|
isWinning: false),
|
||||||
|
showVotes: false,
|
||||||
|
isFinalResult: false)
|
||||||
|
|
||||||
PollOptionView(pollOption: .init(id: "2",
|
PollOptionView(pollOption: .init(id: "2",
|
||||||
text: "Chinese 🇨🇳",
|
text: "Chinese 🇨🇳",
|
||||||
votes: 9,
|
votes: 9,
|
||||||
allVotes: 10,
|
allVotes: 10,
|
||||||
isSelected: false))
|
isSelected: false,
|
||||||
|
isWinning: true),
|
||||||
|
showVotes: true,
|
||||||
|
isFinalResult: false)
|
||||||
|
|
||||||
|
PollOptionView(pollOption: .init(id: "2",
|
||||||
|
text: "Chinese 🇨🇳",
|
||||||
|
votes: 9,
|
||||||
|
allVotes: 10,
|
||||||
|
isSelected: false,
|
||||||
|
isWinning: true),
|
||||||
|
showVotes: true,
|
||||||
|
isFinalResult: true)
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ import SwiftUI
|
|||||||
struct PollRoomTimelineView: View {
|
struct PollRoomTimelineView: View {
|
||||||
let timelineItem: PollRoomTimelineItem
|
let timelineItem: PollRoomTimelineItem
|
||||||
@Environment(\.timelineStyle) var timelineStyle
|
@Environment(\.timelineStyle) var timelineStyle
|
||||||
|
@EnvironmentObject private var context: RoomScreenViewModel.Context
|
||||||
|
@ScaledMetric private var summaryPadding = 32
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
TimelineStyler(timelineItem: timelineItem) {
|
TimelineStyler(timelineItem: timelineItem) {
|
||||||
@ -26,10 +28,18 @@ struct PollRoomTimelineView: View {
|
|||||||
questionView
|
questionView
|
||||||
|
|
||||||
ForEach(poll.options, id: \.id) { option in
|
ForEach(poll.options, id: \.id) { option in
|
||||||
Button { } label: {
|
Button {
|
||||||
PollOptionView(pollOption: option)
|
context.send(viewAction: .selectedPollOption(poll: poll, optionID: option.id))
|
||||||
|
} label: {
|
||||||
|
PollOptionView(pollOption: option,
|
||||||
|
showVotes: showVotes,
|
||||||
|
isFinalResult: poll.hasEnded)
|
||||||
|
.foregroundColor(progressBarColor(for: option))
|
||||||
}
|
}
|
||||||
|
.disabled(poll.hasEnded)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
summaryView
|
||||||
}
|
}
|
||||||
.frame(maxWidth: 450)
|
.frame(maxWidth: 450)
|
||||||
}
|
}
|
||||||
@ -42,50 +52,104 @@ struct PollRoomTimelineView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var questionView: some View {
|
private var questionView: some View {
|
||||||
HStack(spacing: 4) {
|
HStack(alignment: .top, spacing: 12) {
|
||||||
Image(Asset.Images.equalizer.name)
|
Image(Asset.Images.timelinePoll.name)
|
||||||
|
|
||||||
Text(poll.question)
|
Text(poll.question)
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
.font(.compound.bodyLGSemibold)
|
.font(.compound.bodyLGSemibold)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
private var summaryView: some View {
|
||||||
|
if let summaryText = poll.summaryText {
|
||||||
|
Text(summaryText)
|
||||||
|
.font(.compound.bodySM)
|
||||||
|
.padding(.leading, showVotes ? 0 : summaryPadding)
|
||||||
|
.foregroundColor(.compound.textSecondary)
|
||||||
|
.frame(maxWidth: .infinity, alignment: showVotes ? .trailing : .leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func progressBarColor(for option: Poll.Option) -> Color {
|
||||||
|
if poll.hasEnded {
|
||||||
|
return option.isWinning ? .compound.textActionAccent : .compound.textDisabled
|
||||||
|
} else {
|
||||||
|
return .compound.textPrimary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var showVotes: Bool {
|
||||||
|
poll.hasEnded || poll.kind == .disclosed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Poll {
|
||||||
|
var summaryText: String? {
|
||||||
|
guard !hasEnded else {
|
||||||
|
return options.first.map {
|
||||||
|
L10n.commonPollFinalVotes($0.allVotes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch kind {
|
||||||
|
case .disclosed:
|
||||||
|
return options.first.map {
|
||||||
|
L10n.commonPollTotalVotes($0.allVotes)
|
||||||
|
}
|
||||||
|
case .undisclosed:
|
||||||
|
return L10n.commonPollUndisclosedText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasEnded: Bool {
|
||||||
|
endDate != nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PollRoomTimelineView_Previews: PreviewProvider {
|
struct PollRoomTimelineView_Previews: PreviewProvider {
|
||||||
static let viewModel = RoomScreenViewModel.mock
|
static let viewModel = RoomScreenViewModel.mock
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
PollRoomTimelineView(timelineItem: .init(id: .random,
|
PollRoomTimelineView(timelineItem: .mock(poll: .disclosed))
|
||||||
poll: .mock,
|
|
||||||
body: "Foo",
|
|
||||||
timestamp: "Now",
|
|
||||||
isOutgoing: false,
|
|
||||||
isEditable: false,
|
|
||||||
sender: .init(id: "Bob"),
|
|
||||||
properties: .init()))
|
|
||||||
.environment(\.timelineStyle, .bubbles)
|
.environment(\.timelineStyle, .bubbles)
|
||||||
.environmentObject(viewModel.context)
|
.environmentObject(viewModel.context)
|
||||||
.previewDisplayName("Poll bubble style")
|
.previewDisplayName("Disclosed, Bubble")
|
||||||
|
|
||||||
PollRoomTimelineView(timelineItem: .init(id: .random,
|
PollRoomTimelineView(timelineItem: .mock(poll: .undisclosed))
|
||||||
poll: .mock,
|
.environment(\.timelineStyle, .bubbles)
|
||||||
body: "Foo",
|
.environmentObject(viewModel.context)
|
||||||
timestamp: "Now",
|
.previewDisplayName("Undisclosed, Bubble")
|
||||||
isOutgoing: false,
|
|
||||||
isEditable: false,
|
PollRoomTimelineView(timelineItem: .mock(poll: .endedDisclosed))
|
||||||
sender: .init(id: "Bob"),
|
.environment(\.timelineStyle, .bubbles)
|
||||||
properties: .init()))
|
.environmentObject(viewModel.context)
|
||||||
|
.previewDisplayName("Ended, Disclosed, Bubble")
|
||||||
|
|
||||||
|
PollRoomTimelineView(timelineItem: .mock(poll: .endedUndisclosed))
|
||||||
|
.environment(\.timelineStyle, .bubbles)
|
||||||
|
.environmentObject(viewModel.context)
|
||||||
|
.previewDisplayName("Ended, Undisclosed, Bubble")
|
||||||
|
|
||||||
|
PollRoomTimelineView(timelineItem: .mock(poll: .disclosed))
|
||||||
.environment(\.timelineStyle, .plain)
|
.environment(\.timelineStyle, .plain)
|
||||||
.environmentObject(viewModel.context)
|
.environmentObject(viewModel.context)
|
||||||
.previewDisplayName("Poll plain style")
|
.previewDisplayName("Disclosed, Plain")
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension Poll {
|
PollRoomTimelineView(timelineItem: .mock(poll: .undisclosed))
|
||||||
static let mock: Self = .init(question: "Do you like polls?",
|
.environment(\.timelineStyle, .plain)
|
||||||
pollKind: .disclosed,
|
.environmentObject(viewModel.context)
|
||||||
maxSelections: 1,
|
.previewDisplayName("Undisclosed, Plain")
|
||||||
options: [.init(id: "1", text: "Yes", votes: 1, allVotes: 3, isSelected: true), .init(id: "2", text: "No", votes: 2, allVotes: 3, isSelected: false)],
|
|
||||||
votes: [:],
|
PollRoomTimelineView(timelineItem: .mock(poll: .endedDisclosed))
|
||||||
endDate: nil)
|
.environment(\.timelineStyle, .plain)
|
||||||
|
.environmentObject(viewModel.context)
|
||||||
|
.previewDisplayName("Ended, Disclosed, Plain")
|
||||||
|
|
||||||
|
PollRoomTimelineView(timelineItem: .mock(poll: .endedUndisclosed))
|
||||||
|
.environment(\.timelineStyle, .plain)
|
||||||
|
.environmentObject(viewModel.context)
|
||||||
|
.previewDisplayName("Ended, Undisclosed, Plain")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,16 @@ enum RoomTimelineItemFixtures {
|
|||||||
TextRoomTimelineItem(text: "Pork buffalo mollit culpa strip steak in leberkas flank cow.",
|
TextRoomTimelineItem(text: "Pork buffalo mollit culpa strip steak in leberkas flank cow.",
|
||||||
senderDisplayName: "Alice")]
|
senderDisplayName: "Alice")]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var disclosedPolls: [RoomTimelineItemProtocol] {
|
||||||
|
[PollRoomTimelineItem.mock(poll: .disclosed),
|
||||||
|
PollRoomTimelineItem.mock(poll: .endedDisclosed)]
|
||||||
|
}
|
||||||
|
|
||||||
|
static var undisclosedPolls: [RoomTimelineItemProtocol] {
|
||||||
|
[PollRoomTimelineItem.mock(poll: .undisclosed),
|
||||||
|
PollRoomTimelineItem.mock(poll: .endedUndisclosed)]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension TextRoomTimelineItem {
|
private extension TextRoomTimelineItem {
|
||||||
|
@ -29,7 +29,7 @@ struct PollRoomTimelineItem: Equatable, EventBasedTimelineItemProtocol {
|
|||||||
|
|
||||||
struct Poll: Equatable {
|
struct Poll: Equatable {
|
||||||
let question: String
|
let question: String
|
||||||
let pollKind: Kind
|
let kind: Kind
|
||||||
let maxSelections: Int
|
let maxSelections: Int
|
||||||
let options: [Option]
|
let options: [Option]
|
||||||
let votes: [String: [String]]
|
let votes: [String: [String]]
|
||||||
@ -46,5 +46,6 @@ struct Poll: Equatable {
|
|||||||
let votes: Int
|
let votes: Int
|
||||||
let allVotes: Int
|
let allVotes: Int
|
||||||
let isSelected: Bool
|
let isSelected: Bool
|
||||||
|
let isWinning: Bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,16 +333,21 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
count + pair.value.count
|
count + pair.value.count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let maxOptionVotes = votes.map(\.value.count).max()
|
||||||
|
|
||||||
let options = answers.map { answer in
|
let options = answers.map { answer in
|
||||||
Poll.Option(id: answer.id,
|
let optionVotesCount = votes[answer.id]?.count
|
||||||
|
|
||||||
|
return Poll.Option(id: answer.id,
|
||||||
text: answer.text,
|
text: answer.text,
|
||||||
votes: votes[answer.id]?.count ?? 0,
|
votes: optionVotesCount ?? 0,
|
||||||
allVotes: allVotes,
|
allVotes: allVotes,
|
||||||
isSelected: votes[answer.id]?.contains(userID) ?? false)
|
isSelected: votes[answer.id]?.contains(userID) ?? false,
|
||||||
|
isWinning: optionVotesCount.map { $0 == maxOptionVotes } ?? false)
|
||||||
}
|
}
|
||||||
|
|
||||||
let poll = Poll(question: question,
|
let poll = Poll(question: question,
|
||||||
pollKind: .init(pollKind: pollKind),
|
kind: .init(pollKind: pollKind),
|
||||||
maxSelections: Int(maxSelections),
|
maxSelections: Int(maxSelections),
|
||||||
options: options,
|
options: options,
|
||||||
votes: votes,
|
votes: votes,
|
||||||
|
@ -322,6 +322,20 @@ class MockScreen: Identifiable {
|
|||||||
emojiProvider: EmojiProvider())
|
emojiProvider: EmojiProvider())
|
||||||
let coordinator = RoomScreenCoordinator(parameters: parameters)
|
let coordinator = RoomScreenCoordinator(parameters: parameters)
|
||||||
|
|
||||||
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
|
return navigationStackCoordinator
|
||||||
|
case .roomWithDisclosedPolls, .roomWithUndisclosedPolls:
|
||||||
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
|
|
||||||
|
let timelineController = MockRoomTimelineController()
|
||||||
|
timelineController.timelineItems = id == .roomWithDisclosedPolls ? RoomTimelineItemFixtures.disclosedPolls : RoomTimelineItemFixtures.undisclosedPolls
|
||||||
|
timelineController.incomingItems = []
|
||||||
|
let parameters = RoomScreenCoordinatorParameters(roomProxy: RoomProxyMock(with: .init(displayName: "Polls timeline", avatarURL: URL.picturesDirectory)),
|
||||||
|
timelineController: timelineController,
|
||||||
|
mediaProvider: MockMediaProvider(),
|
||||||
|
emojiProvider: EmojiProvider())
|
||||||
|
let coordinator = RoomScreenCoordinator(parameters: parameters)
|
||||||
|
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .sessionVerification:
|
case .sessionVerification:
|
||||||
|
@ -45,6 +45,8 @@ enum UITestsScreenIdentifier: String {
|
|||||||
case roomLayoutTop
|
case roomLayoutTop
|
||||||
case roomLayoutMiddle
|
case roomLayoutMiddle
|
||||||
case roomLayoutBottom
|
case roomLayoutBottom
|
||||||
|
case roomWithDisclosedPolls
|
||||||
|
case roomWithUndisclosedPolls
|
||||||
case sessionVerification
|
case sessionVerification
|
||||||
case userSessionScreen
|
case userSessionScreen
|
||||||
case roomDetailsScreen
|
case roomDetailsScreen
|
||||||
|
@ -161,6 +161,18 @@ class RoomScreenUITests: XCTestCase {
|
|||||||
try await app.assertScreenshot(.roomSmallTimelineWithReadReceipts)
|
try await app.assertScreenshot(.roomSmallTimelineWithReadReceipts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testTimelineDisclosedPolls() async throws {
|
||||||
|
let app = Application.launch(.roomWithDisclosedPolls)
|
||||||
|
|
||||||
|
try await app.assertScreenshot(.roomWithDisclosedPolls)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTimelineUndisclosedPolls() async throws {
|
||||||
|
let app = Application.launch(.roomWithUndisclosedPolls)
|
||||||
|
|
||||||
|
try await app.assertScreenshot(.roomWithUndisclosedPolls)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Helper Methods
|
// MARK: - Helper Methods
|
||||||
|
|
||||||
private func performOperation(_ operation: UITestsSignal, using client: UITestsSignalling.Client) async throws {
|
private func performOperation(_ operation: UITestsSignal, using client: UITestsSignalling.Client) async throws {
|
||||||
|
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomWithDisclosedPolls.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomWithDisclosedPolls.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomWithUndisclosedPolls.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomWithUndisclosedPolls.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomWithDisclosedPolls.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomWithDisclosedPolls.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomWithUndisclosedPolls.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomWithUndisclosedPolls.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomWithDisclosedPolls.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomWithDisclosedPolls.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomWithUndisclosedPolls.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomWithUndisclosedPolls.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomWithDisclosedPolls.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomWithDisclosedPolls.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomWithUndisclosedPolls.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomWithUndisclosedPolls.png
(Stored with Git LFS)
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user