From 83a718b38dd8b1888394b35b198e3bec2f2d91ea Mon Sep 17 00:00:00 2001 From: MaximeE Date: Thu, 17 Mar 2022 16:52:22 +0100 Subject: [PATCH 1/5] 5720: Update UI in location sharing View --- .../location_live_icon.imageset/Contents.json | 23 +++++++ .../location_live_icon.png | Bin 0 -> 542 bytes .../location_live_icon@2x.png | Bin 0 -> 1021 bytes .../location_live_icon@3x.png | Bin 0 -> 1659 bytes Riot/Assets/en.lproj/Vector.strings | 8 ++- Riot/Generated/Images.swift | 1 + Riot/Generated/Strings.swift | 14 +++- .../Room/Location/LocationMarkerView.swift | 9 +++ .../Room/Location/LocationMarkerView.xib | 5 +- .../LocationSharingModels.swift | 3 + .../LocationSharingScreenState.swift | 2 +- .../View/LocationSharingOptionButton.swift | 61 +++++++++++++++++ .../LocationSharingOptionButtonIcon.swift | 48 +++++++++++++ .../View/LocationSharingUserMarkerView.swift | 34 +++++++--- .../View/LocationSharingView.swift | 63 +++++++++++++----- .../View/UserLocationAnnotatonView.swift | 2 +- 16 files changed, 241 insertions(+), 32 deletions(-) create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/Contents.json create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon.png create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@2x.png create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@3x.png create mode 100644 RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift create mode 100644 RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButtonIcon.swift diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/Contents.json new file mode 100644 index 0000000000..0a20c899a3 --- /dev/null +++ b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "location_live_icon.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "location_live_icon@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "location_live_icon@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6aa2e2639f6d228934ebd9356c5fd272b69bcbc9 GIT binary patch literal 542 zcmV+(0^$9MP)18TqmWtqf`KgUg`ao>>I}Ez^mi6S}Yc=$fbMcTiG2L@Eo1s z&H^{DNnZ$FHe@Sr>O@?WO!kaJPo*M>DhmH@b;8GO}rR*(!eU8nFSKXJr zV_}SMn1BzRMNO5)QBIoTYS@mBuOxQiDeyGbIT-N!?~y_Z!l>h($ literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@2x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4ed19fb09fefefa280dc517fca543265895993ef GIT binary patch literal 1021 zcmV!1&^00009a7bBm000&x z000&x0ZCFM@Bjb+0drDELIAGL9O(c600d`2O+f$vv5yPrEjmkJIL`w35@ z=HZD~e2xVbLNLa+Ti-U(&{OMtTl-d10R%Z<9(Pli11g$`=zx`P2e#p+Iwa~tsB@Sd zU~Fk3f+G{MEv#q)Jb%O3$#aeA1~7Fr5fhwn!iFY*`zInOh~&I-ZUu zLsxM4Jn>y_#{;5GMZ*TrEe1jz8(G+oZ@C;6ly-JEu&D+#Es)nBVI3f>0G$&wEv21M zaanW;J#rBpiv{A|SqCKVYDnaNY9W6sizx0BS0(7Qh_J#r6gNM8`w?k(27S#q0_C@g zgzi{K-K+9^=Nfpw7ECA_f`=J01sO2vmC&Rwj|9j(xFWjp7#S>dav1mZ#EtWRMemMDvFf#1ltz20T%sgKibR7iH`jeETB$dr5FbX{eJ-2?Tgn##StnS#&~3 zUX{W(w&ee85qzS5k4HMsEkoS-$%ob7#r`$vxh3F*3PX#CO7u~Pe1R+3;C5qmNAZnfhvDQUh_9`30O z_TCOl)_1@o^OSVfo1;*%B#2S<8BkLOxXd+tY3M)&9J)Psf~Fe|qVhDSPS48VtXGOT za2YzbfUg!bsO(=`lWa1)d8SM;RJ(v#u%ZE78c|f=nD%pCosJxq^^C^pM_~&&(a-|E zC7|mB%^_D<4d~XELdD<*9uKqJ=5r^b+>n(+PET+WC@R7}+r~+m?})&doTvP>p=sG6 z>^trk3cXuyvz^R12aK9*hQUpy6C4-#FD2?6_d3sbA0J8?G|TsMJ;RykG%;OA|CsomH$hd$Sx8=A` rYAzaAG+_!o-Ni=c$#3HvlJocrSz_i({_LHs00000NkvXXu0mjfojk!& literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@3x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..cabf83a926263e005805a6e7573247084f2cf40a GIT binary patch literal 1659 zcmV->288*EP)H;mZK~w%wT_8?6K*TN(I}3<%2aufwe8m-% ztx&u#aNrO9qtAPI@*{b`5y1T*2%2cmo;^<-ST1JfiTio!%8@I#u3Q`(94u+iSGazX zpUjmh_1#yl^30Wrzvj-BBii$b41z1qTKZ}seW=MrTZF6Rn*8WCDcwjvryWw?;JOG) zSMHr&H#9O%7wOYW^48F#a^)AN*FB}+DnDbLigti&H+SW-wo1g@l_{EyJ?nKKlNRXn zno?lzlHiTfh`9D%Ms&W$<YTb$=XoQP?UN$A*f5 zHSl%^%HQUPKE|0x->f*o!ue^I&o^Wj=>FKds0y@QpaxNP0y7S!Q8^Z!C2%-N7=m{Z zdTE`iWEryN^1-~H&hHdlyO`+p-8x&G}Vf@C^WM}Y3XYqD+723+RYDJ{-n|1+Y?|>v@`o$$U9m1B$kIgU`2y8>%6iP;S~soT7uyneHli6b zV@yU7xa%(1#&xp;*w5Z9p{^CsOUieQv!IUw*|>JyfeE;{0!kuxCKMD2+uTyc*i}j? z4E2ed$O84f3drY*EPAeZXkLu+_6wjO%(BP;+sGp73q4qEA{}|svA%Of4h`bgKp<1j zfpW=NR->LHj^{G6&X~2IO^S~7t$^Imnou)X{{(cnQ5wid53WlW-2b9@;upe*J{zvJ zyqEYMopkpjKV@Co5ci%da-v6Tz;6zO))6=0WkyaqA80tDI=AkCv==ctk_G(@&ZDev z*>>M&HwLWVBnfdy|p>Q5S2s^CF%H|!^rDUr)J9WFO-HQz~}5&X|v{udJs-s zIj4AbvhzduhPoqz)HVaYr8G+NvpAMxDX!yZ< ze(q{!O-pJAxfwJNFH+o7&6rkE8ndPLmpLA};Zhfk@DhwyU(rh;^s*$Q1lYeD>3dUI z8?y9mSs`9;AVBp^ta43@K(itT=g1|tCr$n6WC+;8ke!4}6(3?4A4WYeFS8Z!e=;>0;g6fnLeJhbsI=@r@%zFO* z55*dZE59n|^e1}8?kOj&MjvA|pPo?%ocufPkA+nq#@lIB>*B;LYb{&=!8rqe&)%m$ zG#Vxf+;{ZbkKHU6hH@TB1I?me09G&Y>>qRihxbksBC;^RMR zWNZ}zbWuaWX)dahOET&ga!Eq`mr5LdvXuw7QQzu?8j#ud(5QG+vj@7hxq{K+LPHmAO$ugh{{e2eRAwe6TYCTi002ovPDHLk FV1h-*4hH}L literal 0 HcmV?d00001 diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index af5aa32bea..931f07e754 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -2062,8 +2062,6 @@ Tap the + to start adding people."; "location_sharing_close_action" = "Close"; -"location_sharing_share_action" = "Share"; - "location_sharing_post_failure_title" = "We couldn’t send your location"; "location_sharing_post_failure_subtitle" = "%@ could not send your location. Please try again later."; @@ -2088,6 +2086,12 @@ Tap the + to start adding people."; "location_sharing_settings_toggle_title" = "Enable location sharing"; +"location_sharing_live_share_title" = "Share live location"; + +"location_sharing_static_share_title" = "Send my current location"; + +"location_sharing_pin_drop_share_title" = "Send this location"; + // MARK: - MatrixKit diff --git a/Riot/Generated/Images.swift b/Riot/Generated/Images.swift index df3b02a276..d64969d94d 100644 --- a/Riot/Generated/Images.swift +++ b/Riot/Generated/Images.swift @@ -169,6 +169,7 @@ internal class Asset: NSObject { internal static let videoCall = ImageAsset(name: "video_call") internal static let voiceCallHangonIcon = ImageAsset(name: "voice_call_hangon_icon") internal static let voiceCallHangupIcon = ImageAsset(name: "voice_call_hangup_icon") + internal static let locationLiveIcon = ImageAsset(name: "location_live_icon") internal static let locationMarkerIcon = ImageAsset(name: "location_marker_icon") internal static let locationShareIcon = ImageAsset(name: "location_share_icon") internal static let locationUserMarker = ImageAsset(name: "location_user_marker") diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index ca1a6125a1..193cc718d7 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -2731,6 +2731,10 @@ public class VectorL10n: NSObject { public static var locationSharingInvalidAuthorizationSettings: String { return VectorL10n.tr("Vector", "location_sharing_invalid_authorization_settings") } + /// Share live location + public static var locationSharingLiveShareTitle: String { + return VectorL10n.tr("Vector", "location_sharing_live_share_title") + } /// %@ could not load the map. Please try again later. public static func locationSharingLoadingMapErrorTitle(_ p1: String) -> String { return VectorL10n.tr("Vector", "location_sharing_loading_map_error_title", p1) @@ -2751,6 +2755,10 @@ public class VectorL10n: NSObject { public static var locationSharingOpenOpenStreetMaps: String { return VectorL10n.tr("Vector", "location_sharing_open_open_street_maps") } + /// Send this location + public static var locationSharingPinDropShareTitle: String { + return VectorL10n.tr("Vector", "location_sharing_pin_drop_share_title") + } /// %@ could not send your location. Please try again later. public static func locationSharingPostFailureSubtitle(_ p1: String) -> String { return VectorL10n.tr("Vector", "location_sharing_post_failure_subtitle", p1) @@ -2767,9 +2775,9 @@ public class VectorL10n: NSObject { public static var locationSharingSettingsToggleTitle: String { return VectorL10n.tr("Vector", "location_sharing_settings_toggle_title") } - /// Share - public static var locationSharingShareAction: String { - return VectorL10n.tr("Vector", "location_sharing_share_action") + /// Send my current location + public static var locationSharingStaticShareTitle: String { + return VectorL10n.tr("Vector", "location_sharing_static_share_title") } /// Location public static var locationSharingTitle: String { diff --git a/Riot/Modules/Room/Location/LocationMarkerView.swift b/Riot/Modules/Room/Location/LocationMarkerView.swift index caf101a1ba..c7c3eb59a0 100644 --- a/Riot/Modules/Room/Location/LocationMarkerView.swift +++ b/Riot/Modules/Room/Location/LocationMarkerView.swift @@ -20,14 +20,23 @@ import Mapbox class LocationMarkerView: MGLAnnotationView, NibLoadable { + @IBOutlet private var markerBackground: UIImageView! @IBOutlet private var avatarView: UserAvatarView! + private static var usernameColorGenerator = UserNameColorGenerator() + private let theme: Theme = ThemeService.shared().theme + override func awakeFromNib() { super.awakeFromNib() translatesAutoresizingMaskIntoConstraints = false } func setAvatarData(_ avatarData: AvatarViewDataProtocol) { + Self.usernameColorGenerator.defaultColor = theme.colors.primaryContent + Self.usernameColorGenerator.userNameColors = theme.colors.namesAndAvatars + let image = Asset.Images.locationUserMarker.image.withRenderingMode(.alwaysTemplate) + markerBackground.image = image + markerBackground.tintColor = Self.usernameColorGenerator.color(from: avatarData.matrixItemId) avatarView.fill(with: avatarData) } } diff --git a/Riot/Modules/Room/Location/LocationMarkerView.xib b/Riot/Modules/Room/Location/LocationMarkerView.xib index 837db55030..a71c32515d 100644 --- a/Riot/Modules/Room/Location/LocationMarkerView.xib +++ b/Riot/Modules/Room/Location/LocationMarkerView.xib @@ -1,9 +1,9 @@ - + - + @@ -65,6 +65,7 @@ + diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift index cb9843a469..069719e243 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift @@ -54,6 +54,9 @@ struct LocationSharingViewState: BindableState { /// Map annotation to focus on var highlightedAnnotation: UserLocationAnnotation? + /// Indicates whether the user has moved around the map to drop a pin somewhere other than their current location + var isPinDropSharing: Bool = false + var showLoadingIndicator: Bool = false /// True to indicate to show and follow current user location diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift index 208b7c2da2..c5aa78c864 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift @@ -36,7 +36,7 @@ enum MockLocationSharingScreenState: MockScreenState, CaseIterable { let mapStyleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx")! let viewModel = LocationSharingViewModel(mapStyleURL: mapStyleURL, - avatarData: AvatarInput(mxContentUri: "", matrixItemId: "", displayName: "Alice"), + avatarData: AvatarInput(mxContentUri: "", matrixItemId: "alice:matrix.org", displayName: "Alice"), location: location) return ([viewModel], AnyView(LocationSharingView(context: viewModel.context) diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift new file mode 100644 index 0000000000..9247da8826 --- /dev/null +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift @@ -0,0 +1,61 @@ +// +// Copyright 2022 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 SwiftUI + +@available(iOS 14.0, *) +struct LocationSharingOptionButton: View { + + // MARK: - Properties + + // MARK: Private + + @Environment(\.theme) private var theme: ThemeSwiftUI + + let text: String + let action: () -> (Void) + @ViewBuilder var content: Content + + var body: some View { + Button(action: action) { + HStack(spacing: 18) { + content + .frame(width: 40, height: 40) + Text(text) + .font(theme.fonts.body) + .foregroundColor(theme.colors.primaryContent) + } + } + } +} + +@available(iOS 14.0, *) +struct LocationSharingOptionButton_Previews: PreviewProvider { + static var previews: some View { + VStack { + LocationSharingOptionButton(text: "Share my current location") { + + } content: { + LocationSharingUserMarkerView(isMarker: false, avatarData: AvatarInput(mxContentUri: "", matrixItemId: "test", displayName: "Nicolas")) + } + LocationSharingOptionButton(text: "Share live location") { + + } content: { + LocationSharingOptionButtonIcon(fillColor: Color.purple, image: Asset.Images.locationLiveIcon.image) + } + } + } +} diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButtonIcon.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButtonIcon.swift new file mode 100644 index 0000000000..5cb69a2e32 --- /dev/null +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButtonIcon.swift @@ -0,0 +1,48 @@ +// +// Copyright 2022 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 SwiftUI + +@available(iOS 14.0, *) +struct LocationSharingOptionButtonIcon: View { + + // MARK: - Properties + + // MARK: Private + + @Environment(\.theme) private var theme: ThemeSwiftUI + + let fillColor: Color + let image: UIImage + + var body: some View { + ZStack { + Circle() + .fill(fillColor) + .frame(width: 40, height: 40) + Image(uiImage: image) + .renderingMode(.template) + .foregroundColor(Color.white) + } + } +} + +@available(iOS 14.0, *) +struct LocationSharingOptionButtonIcon_Previews: PreviewProvider { + static var previews: some View { + LocationSharingOptionButtonIcon(fillColor: Color.green, image: Asset.Images.locationMarkerIcon.image) + } +} diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift index 26bc101d3a..361e76fcf4 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift @@ -27,19 +27,35 @@ struct LocationSharingUserMarkerView: View { @State private var frame: CGRect = .zero + private var usernameColorGenerator: UserNameColorGenerator { + let usernameColorGenerator = UserNameColorGenerator() + let theme = ThemeService.shared().theme + usernameColorGenerator.defaultColor = theme.textPrimaryColor + usernameColorGenerator.userNameColors = theme.userNameColors + return usernameColorGenerator + } + // MARK: Public + let isMarker: Bool let avatarData: AvatarInputProtocol var body: some View { + let fillColor: Color = Color(usernameColorGenerator.color(from:avatarData.matrixItemId)) ZStack { - Image(uiImage: Asset.Images.locationUserMarker.image) - AvatarImage(avatarData: avatarData, size: .large) - .offset(y: -1.5) + Circle() + .fill(fillColor) + .frame(width: 40, height: 40) + if isMarker { + Rectangle() + .rotation(Angle(degrees: 45)) + .fill(fillColor) + .frame(width: 7, height: 7) + .offset(x: 0, y: 19) + } + AvatarImage(avatarData: avatarData, size: .small) } .background(ViewFrameReader(frame: $frame)) - .padding(.bottom, frame.height) - .accentColor(theme.colors.accent) } } @@ -49,9 +65,11 @@ struct LocationSharingUserMarkerView: View { struct LocationSharingUserMarkerView_Previews: PreviewProvider { static var previews: some View { let avatarData = AvatarInput(mxContentUri: "", - matrixItemId: "", + matrixItemId: "test", displayName: "Alice") - - LocationSharingUserMarkerView(avatarData: avatarData) + VStack(alignment: .center, spacing: 15) { + LocationSharingUserMarkerView(isMarker: true, avatarData: avatarData) + LocationSharingUserMarkerView(isMarker: false, avatarData: avatarData) + } } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift index 317c20b025..f3f7e417ec 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift @@ -32,16 +32,22 @@ struct LocationSharingView: View { var body: some View { NavigationView { - ZStack(alignment: .bottom) { - LocationSharingMapView(tileServerMapURL: context.viewState.mapStyleURL, - annotations: context.viewState.annotations, - highlightedAnnotation: context.viewState.highlightedAnnotation, - userAvatarData: context.viewState.userAvatarData, - showsUserLocation: context.viewState.showsUserLocation, - userLocation: $context.userLocation, - errorSubject: context.viewState.errorSubject) - .ignoresSafeArea() - MapCreditsView() + VStack { + ZStack(alignment: .bottom) { + LocationSharingMapView(tileServerMapURL: context.viewState.mapStyleURL, + annotations: context.viewState.annotations, + highlightedAnnotation: context.viewState.highlightedAnnotation, + userAvatarData: context.viewState.userAvatarData, + showsUserLocation: context.viewState.showsUserLocation, + userLocation: $context.userLocation, + errorSubject: context.viewState.errorSubject) + .ignoresSafeArea() + MapCreditsView() + } + if context.viewState.shareButtonVisible { + buttonsView + .cornerRadius(5) + } } .toolbar { ToolbarItem(placement: .navigationBarLeading) { @@ -63,11 +69,6 @@ struct LocationSharingView: View { .accessibilityIdentifier("LocationSharingView.shareButton") } .disabled(!context.viewState.shareButtonEnabled) - } else { - Button(VectorL10n.locationSharingShareAction, action: { - context.send(viewAction: .share) - }) - .disabled(!context.viewState.shareButtonEnabled) } } } @@ -84,6 +85,38 @@ struct LocationSharingView: View { .navigationViewStyle(StackNavigationViewStyle()) } + var buttonsView: some View { + VStack(alignment: .leading, spacing: 15) { + if !context.viewState.isPinDropSharing { + LocationSharingOptionButton(text: VectorL10n.locationSharingStaticShareTitle) { + context.send(viewAction: .share) + } content: { + LocationSharingUserMarkerView(isMarker: false, avatarData: context.viewState.userAvatarData) + } + .disabled(!context.viewState.shareButtonEnabled) + // Disable for now until live location sharing is done + if BuildSettings.liveLocationSharingEnabled { + LocationSharingOptionButton(text: VectorL10n.locationSharingLiveShareTitle) { + // TODO: - Start live location sharing + } content: { + LocationSharingOptionButtonIcon(fillColor: Color.purple, image: Asset.Images.locationLiveIcon.image) + } + .disabled(!context.viewState.shareButtonEnabled) + } + } else { + LocationSharingOptionButton(text: VectorL10n.locationSharingPinDropShareTitle) { + // TODO: - Pin drop sharing action + } content: { + LocationSharingOptionButtonIcon(fillColor: + theme.colors.primaryContent, image: Asset.Images.locationMarkerIcon.image) + } + .disabled(!context.viewState.shareButtonEnabled) + } + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding() + } + @ViewBuilder private var activityIndicator: some View { if context.viewState.showLoadingIndicator { diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift index 6835ca50c4..e713508bdc 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift @@ -45,7 +45,7 @@ class UserLocationAnnotatonView: MGLUserLocationAnnotationView { private func addUserMarkerView(with avatarData: AvatarInputProtocol) { - guard let avatarImageView = UIHostingController(rootView: LocationSharingUserMarkerView(avatarData: avatarData)).view else { + guard let avatarImageView = UIHostingController(rootView: LocationSharingUserMarkerView(isMarker: true, avatarData: avatarData)).view else { return } From 9ca2b1dda38a14269548382d5933af2c161a2ecf Mon Sep 17 00:00:00 2001 From: MaximeE Date: Thu, 17 Mar 2022 16:56:53 +0100 Subject: [PATCH 2/5] 5720: Changelog --- changelog.d/5720.change | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5720.change diff --git a/changelog.d/5720.change b/changelog.d/5720.change new file mode 100644 index 0000000000..0b0eeee509 --- /dev/null +++ b/changelog.d/5720.change @@ -0,0 +1 @@ +Location Sharing: Update UI on location sharing view From e805e415f3acbc36d6a27696ce968846876096dd Mon Sep 17 00:00:00 2001 From: MaximeE Date: Wed, 23 Mar 2022 15:48:19 +0100 Subject: [PATCH 3/5] 5720: Rework some location sharing related view --- DesignKit/Source/ColorValues.swift | 6 +++ DesignKit/Source/Colors.swift | 7 +++ DesignKit/Source/ColorsSwiftUI.swift | 8 +++ DesignKit/Source/ColorsUIkit.swift | 8 +++ .../Variants/Colors/Dark/DarkColors.swift | 4 +- .../Variants/Colors/Light/LightColors.swift | 4 +- .../location_live_icon.imageset/Contents.json | 23 +++++++++ .../location_live_icon.png | Bin 0 -> 1456 bytes .../location_live_icon@2x.png | Bin 0 -> 2803 bytes .../location_live_icon@3x.png | Bin 0 -> 4067 bytes .../location_pin_icon.imageset/Contents.json | 23 +++++++++ .../location_pin_icon.png | Bin 0 -> 1151 bytes .../location_pin_icon@2x.png | Bin 0 -> 1979 bytes .../location_pin_icon@3x.png | Bin 0 -> 2907 bytes .../Contents.json | 3 ++ Riot/Generated/Images.swift | 2 + .../Room/Location/LocationMarkerView.swift | 14 ++--- .../Room/Location/LocationMarkerView.xib | 4 +- .../Location/RoomTimelineLocationView.swift | 5 +- .../Views/Cell/ThreadTableViewCell.swift | 3 +- Riot/Utils/UserNameColorGenerator.swift | 9 ++++ .../Common/Avatar/View/AvatarImage.swift | 13 +++-- .../Avatar/ViewModel/AvatarViewModel.swift | 4 +- ....swift => ThemeUsersColorsExtension.swift} | 2 +- .../Modules/Common/Util/BorderModifier.swift | 37 ++++++++++++++ .../LocationSharingCoordinator.swift | 3 +- .../LocationSharingModels.swift | 3 ++ .../LocationSharingScreenState.swift | 3 +- .../LocationSharingViewModel.swift | 5 +- ....swift => LocationSharingMarkerView.swift} | 46 +++++++---------- .../View/LocationSharingOptionButton.swift | 24 +++++---- .../LocationSharingOptionButtonIcon.swift | 48 ------------------ .../View/LocationSharingView.swift | 22 ++++---- .../View/UserLocationAnnotatonView.swift | 9 +++- .../View/TemplateRoomChatBubbleView.swift | 2 +- 35 files changed, 218 insertions(+), 126 deletions(-) create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/Contents.json create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon.png create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@2x.png create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@3x.png create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/Contents.json create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/location_pin_icon.png create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/location_pin_icon@2x.png create mode 100644 Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/location_pin_icon@3x.png rename RiotSwiftUI/Modules/Common/Theme/{ThemeNamesColorsExtension.swift => ThemeUsersColorsExtension.swift} (94%) create mode 100644 RiotSwiftUI/Modules/Common/Util/BorderModifier.swift rename RiotSwiftUI/Modules/Room/LocationSharing/View/{LocationSharingUserMarkerView.swift => LocationSharingMarkerView.swift} (50%) delete mode 100644 RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButtonIcon.swift diff --git a/DesignKit/Source/ColorValues.swift b/DesignKit/Source/ColorValues.swift index 5694a55039..b362ced8eb 100644 --- a/DesignKit/Source/ColorValues.swift +++ b/DesignKit/Source/ColorValues.swift @@ -47,4 +47,10 @@ public struct ColorValues: Colors { public let background: UIColor public let namesAndAvatars: [UIColor] + + // MARK: - Others colors + + public let white: UIColor + + public let purple: UIColor } diff --git a/DesignKit/Source/Colors.swift b/DesignKit/Source/Colors.swift index aaa5a936c4..605d7619cb 100644 --- a/DesignKit/Source/Colors.swift +++ b/DesignKit/Source/Colors.swift @@ -68,4 +68,11 @@ public protocol Colors { /// - Avatars default states that include first name letter var namesAndAvatars: [ColorType] { get } + // MARK: - Others colors + + /// White + var white: ColorType { get } + + /// Purple + var purple: ColorType { get } } diff --git a/DesignKit/Source/ColorsSwiftUI.swift b/DesignKit/Source/ColorsSwiftUI.swift index 701aee5376..2224adf7de 100644 --- a/DesignKit/Source/ColorsSwiftUI.swift +++ b/DesignKit/Source/ColorsSwiftUI.swift @@ -49,6 +49,12 @@ public struct ColorSwiftUI: Colors { public let namesAndAvatars: [Color] + // MARK: - Others colors + + public let white: Color + + public let purple: Color + init(values: ColorValues) { accent = Color(values.accent) alert = Color(values.alert) @@ -63,5 +69,7 @@ public struct ColorSwiftUI: Colors { navigation = Color(values.navigation) background = Color(values.background) namesAndAvatars = values.namesAndAvatars.map({ Color($0) }) + white = Color(values.white) + purple = Color(values.purple) } } diff --git a/DesignKit/Source/ColorsUIkit.swift b/DesignKit/Source/ColorsUIkit.swift index 47c6b38a93..daff2b390e 100644 --- a/DesignKit/Source/ColorsUIkit.swift +++ b/DesignKit/Source/ColorsUIkit.swift @@ -48,6 +48,12 @@ import UIKit public let namesAndAvatars: [UIColor] + // MARK: - Others colors + + public let white: UIColor + + public let purple: UIColor + init(values: ColorValues) { accent = values.accent alert = values.alert @@ -62,6 +68,8 @@ import UIKit navigation = values.navigation background = values.background namesAndAvatars = values.namesAndAvatars + white = values.white + purple = values.purple } } diff --git a/DesignKit/Variants/Colors/Dark/DarkColors.swift b/DesignKit/Variants/Colors/Dark/DarkColors.swift index b6b0ba5edd..b50a826511 100644 --- a/DesignKit/Variants/Colors/Dark/DarkColors.swift +++ b/DesignKit/Variants/Colors/Dark/DarkColors.swift @@ -42,7 +42,9 @@ public class DarkColors { UIColor(rgb:0x2DC2C5), UIColor(rgb:0x5C56F5), UIColor(rgb:0x74D12C) - ] + ], + white: UIColor(rgb: 0xFFFFFF), + purple: UIColor(rgb: 0x5C56F5) ) public static var uiKit = ColorsUIKit(values: values) diff --git a/DesignKit/Variants/Colors/Light/LightColors.swift b/DesignKit/Variants/Colors/Light/LightColors.swift index 2e7d8147af..9e73de5764 100644 --- a/DesignKit/Variants/Colors/Light/LightColors.swift +++ b/DesignKit/Variants/Colors/Light/LightColors.swift @@ -43,7 +43,9 @@ public class LightColors { UIColor(rgb:0x2DC2C5), UIColor(rgb:0x5C56F5), UIColor(rgb:0x74D12C) - ] + ], + white: UIColor(rgb: 0xFFFFFF), + purple: UIColor(rgb: 0x5C56F5) ) public static var uiKit = ColorsUIKit(values: values) diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/Contents.json new file mode 100644 index 0000000000..0a20c899a3 --- /dev/null +++ b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "location_live_icon.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "location_live_icon@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "location_live_icon@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..80a96f7b18a6354d2f2235b1ad7b3c80a695aac5 GIT binary patch literal 1456 zcmV;h1yA~kP)*ObC|D{XjOvIPqNd%&AECNs|KMcXmg8? zIv-T3SCQb2kF!5EOSN*~z~YOKg0tnyeF+L*3v{di;}K{DIBd5Yx%Y9((`u3CSKkQe z8!aP8U@#;E@qvdRO)J9&&}yI{*U`2o+nM-u{BTNR>~}appij=CPsU~1CO9>*A2v*V z12e*KvPie*a%ZJK+EZ+pfw}(yIYP+5m@5-PK~gVo>aWzAy?qRJQyktV%Gp2_&yb2j zK~hhxaD7sTJ3n;7*tG!Ef?yYe%foG={)J0zB3%tvu`bz&PI_(RbzQ{Yb}Pw-orPrR z%BWTJdXHBnMx2>{VFyNj9X4o_d_2f}Dq)dA)ts$ewLk zQ|qUwAdAz~7cLPdccAj!Bo|+4lrV68 z!=4+k8aWje1cR==AeC}CIApWni!74cE!MqwsWe*zDTD-C3(*klbDnb{NHRUeM!QKj z0V*dYB(C5}lm>cnkQXkN)YwxZK`LpbJA)$X*E!0dGw98GxntTysN*}|pAy8? zg+tTdD5xj<3`Qf7s`M3&$f@gj*BfTm|8Oq`ngPF6?es^hZ>ukLmYjJ-q|pz-bx3@@ zXMKD7EJJc?`_UKGFhIVe8dpK;IgOIi{kC6QZRMa+iW?!48aCZ_=KL*J?|IEb!Y?3K z+$l2Lwekr!Z&~4m{8H{5GA62ij+d(x66BlCOi9M67zI;uY-KC52OvX|3fd{ut&&0t z<$V|Xw`fPR6@9Yi9t>mVw#H1pts0ahZ(uMbzoHJm#sK_e&7a7^1H-kV38c`2LS09sn&+*amY-^uBKf*V~QbF?!H} zR)O=4j1m06uc+ePFgkt^2c}KK+XL>j{O-b1ciHE+iZ`BxrPDJe=bu@Rjm-w%=Zt?@ zi5#J(C*X;Rqi~y9z^4&532zRe+M&@ETU}*U!&+UB=#nU1^y_%XDMoI5`3L^fVXiw~ z3$ca>Izg9ebdZR+w$jaz5n=n^5c{ZhTAVc*+k`^ldGSzEH~s^*@pB<_IP7fz0000< KMNUMnLSTYjSEADZ literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@2x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f9b203ee18f9d530fb22a3740da15f7936945118 GIT binary patch literal 2803 zcmVnn9q}&x=iHe z#VtE&jlntH1(`!5-x{Yi#+ngWm9|zvnsa46NK?U+OtShj<)sNBl|@*FZZXNOfe#XvbKYjiDR~M;C#FjwVIw#w5ofE%8TNomy92g#H zze+I?i$JJs#mSB_Mu%xTfYWrkQtpYP(hU>nk>_SV+N_QuF5qA?M4lg(H!BH5Ns4wM!R=Rh0ChSm zCMSw5Li=miTdAivLvaCB9U3eLj$@4GKJdIB(s%^gsZ`!@hNo7t!+0iUYV5vI$-O364UGWC&IB7c>l)jG(c0hIa=NR4mODo;{ zYn%7a)QP@}nMA^%zKdDv>QY|^efZV&7Oy`r6R_j8z!?55BvC#GW7a`LEU)3ORkeS5 z?|UpCoZ$xw)xG*o>ndp`RlxUlCABIaIcf>#lUlu}%Eo>8fgO;-BR|p;h@EBN z&azw6+F~hgcCfqtVk+rFcq2+z{8$QFcVsd^hf^!gufq}^1-B_ZrQN6=b zsU6ObV&guUv?E=w77nkxY>A3%PS@ywG*HZz94D!4BnBN8-k|ecx$xN?3ki*2He|0^ zi~U`}$wq(WNI_-eAmK96s_WH(vmaQDTV1*~@<3Gq=#d}SOCKcY(Feg9_0irQ`qhd$ zg`W%a5r%!=Q4biC8O6qZGFd-4-G>a0gcx!%S6g+KX8}2*i~|Sj+dO~bXmd)PZ82pv zaf9|KHm+2vADbycz=uM~us#HyufDT2Q1w%yx*U+^I3x7cDDUJ75X@`%J;yYR88xqh)FaQKV1R7df9-6-{OgPKgsQLQJN0jZ_y= z<&m;IYeWj0@t!8>gE^549UxuK=TY{OF*T{57$$_zVvbwXHBu$nDjTO7NYr}Y@L)VC zj3Rxif`GEG`Cy65xVYp}!Ad($feer$;64Yiku#{;DPnVn&!VLW5wps#aXL-{L`984LBi9zAng-73uD`|Y zn=82PEz^l%gG*v>Of9?}50c4%gTca5Qcy`*RMX(AZ}t5OK70E6;`a|-!``=6-O0GY z;v%Q-ey_^?=)WrT*?*HSBZ0(&hpg4=&+R{#>Hq&r?mm@Db$2PG5brULFh^4hc;BIs zwzvGxb-LGge!gD_<#pO5fQ?0lfJuAybp306DsZwc)jl$y&IqK-HhxgDVGps9;V*b^ z9`dN@lxd>&SRH{?!)UgJI~77*2k(uy6>E6J@Nqrz>_po~uGT3|x$PXmpS9p+ZIi;g#)_ z)w7dA8!uq4SUpkNMlPdVxbRgj<+?lKu_sR1I-#?BwP>ggwcSZIF%Ee^ z!<&l`-Z++ZVmmn&IE*;t0Zo;X`+DaGbc<120wPp-QR(O(A7`Nt&Im zn-hFasO^p6kv#*{1QJ=yfL%HFg5 zA(9LGCTv}K&p=#T7lt(<5P(`+j+5V5iCjD4e5@IPwZQWjs*e;f|0=$DfHYRXGOhny zgSEuE5a{E~8Q!@kHJ`8kz?&UUN;0uI%HjN><+_Cz&P#>0lD3e0ZyY>A(=QH-a6Zqu z)rJ2KgAfie5L^G?Gk*t}SZ*kK{~drI%9uL11u8DA=iS~CCu002ovPDHLk FV1j@ePKN*h literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@3x.png b/Riot/Assets/Images.xcassets/Room/Location/location_live_icon.imageset/location_live_icon@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..68565c599cb77fd3d5cac097a1557a0fdb8aa769 GIT binary patch literal 4067 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 VrCi5${@VZm002ovPDHLkV1fW?&G!HR literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/Contents.json new file mode 100644 index 0000000000..0f1b5bed3e --- /dev/null +++ b/Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "location_pin_icon.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "location_pin_icon@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "location_pin_icon@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/location_pin_icon.png b/Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/location_pin_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..697ac06ee171b8b7a60b154e96f6c595129fdc71 GIT binary patch literal 1151 zcmV-_1c3XAP)DLIg|qj zQY1i};6MQhQm1NKB&0&CRH_6Oagqb5Me;UrTDMux^u2NH#*V$VXIFa=;%N-h@g9W0M$!>buRoEES zN*;eKrfD+tncI-gWIjHYY4)L}1Qvz)r?kRxw1=5yg*Ft}ojy$#L&CyhjmSWX#9I8s zxu8jb0=v`6={8!eo`BTq@c3B3_;%Q(1?_(ajUjXZA#hC!C+@|^yy`Jo>j72p)14B> zXpKQ*kQ!_gXxu6=h)zQW>7GqaS9e#qI6C{ud(`y>b`SwIwmSS#>T!D$T6eL6BG&>j z>?~eHI{l^fSaxxt;3u&2;uu#c|5T}AEVyaCMTFq#-Q5_7?lt!dYqznSUqu+mihJ0K z4mXVTS~~P9g?;wi>v&~PUq%0=>`4<6knj^Vz` z2j8VRdtrl+a@1ToDiIQCvn+FSx7aGq<85Rs{KBv+5BENcZ}z=eF}9Gq4NF`Hmi$02{h;rKa+_ZU7FlnuEo?y# z7VtW|)Ik>&V2KiNi&t7MM#P# z$S&jduxv=bKOg@%V=Ty#tJWg46?x6ILmV-~;`pYVlQ@w`0wMOq_MsQadXuGASs+_c z0h8Eiq?{~S&osA=tq+f<+Tm(jXx~d!7n5qHO3@3+j+Q=*5Uu}Q9ho>#-Cwgd6A{i^ zT+l&>pxR7YM(({-Z9NGh0EftaL&#WIBPc@p{ViA2RRwy`Bh0v7fi&&G7>CLN0 zN9w1Jv!3$eiKh2k%YsMoZwQl93r<@_Y%}>P1squ;h{7c*vRs6(uiO3&@d)(ZrH+2~ RCw2e;002ovPDHLkV1mwiAvXX3 literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/location_pin_icon@2x.png b/Riot/Assets/Images.xcassets/Room/Location/location_pin_icon.imageset/location_pin_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..025ece33f75d8c7cba5830e8634e3705d119559c GIT binary patch literal 1979 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 FV1hYkg)aaA literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_user_marker.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Location/location_user_marker.imageset/Contents.json index 175219374a..86a003473b 100644 --- a/Riot/Assets/Images.xcassets/Room/Location/location_user_marker.imageset/Contents.json +++ b/Riot/Assets/Images.xcassets/Room/Location/location_user_marker.imageset/Contents.json @@ -19,5 +19,8 @@ "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" } } diff --git a/Riot/Generated/Images.swift b/Riot/Generated/Images.swift index 469b4b1e7e..11d31aacff 100644 --- a/Riot/Generated/Images.swift +++ b/Riot/Generated/Images.swift @@ -172,7 +172,9 @@ internal class Asset: NSObject { internal static let voiceCallHangonIcon = ImageAsset(name: "voice_call_hangon_icon") internal static let voiceCallHangupIcon = ImageAsset(name: "voice_call_hangup_icon") internal static let liveLocationIcon = ImageAsset(name: "live_location_icon") + internal static let locationLiveIcon = ImageAsset(name: "location_live_icon") internal static let locationMarkerIcon = ImageAsset(name: "location_marker_icon") + internal static let locationPinIcon = ImageAsset(name: "location_pin_icon") internal static let locationShareIcon = ImageAsset(name: "location_share_icon") internal static let locationUserMarker = ImageAsset(name: "location_user_marker") internal static let pollCheckboxDefault = ImageAsset(name: "poll_checkbox_default") diff --git a/Riot/Modules/Room/Location/LocationMarkerView.swift b/Riot/Modules/Room/Location/LocationMarkerView.swift index c7c3eb59a0..3eb46427ee 100644 --- a/Riot/Modules/Room/Location/LocationMarkerView.swift +++ b/Riot/Modules/Room/Location/LocationMarkerView.swift @@ -20,23 +20,17 @@ import Mapbox class LocationMarkerView: MGLAnnotationView, NibLoadable { - @IBOutlet private var markerBackground: UIImageView! + @IBOutlet private var backgroundImageView: UIImageView! @IBOutlet private var avatarView: UserAvatarView! - private static var usernameColorGenerator = UserNameColorGenerator() - private let theme: Theme = ThemeService.shared().theme - override func awakeFromNib() { super.awakeFromNib() translatesAutoresizingMaskIntoConstraints = false } - func setAvatarData(_ avatarData: AvatarViewDataProtocol) { - Self.usernameColorGenerator.defaultColor = theme.colors.primaryContent - Self.usernameColorGenerator.userNameColors = theme.colors.namesAndAvatars - let image = Asset.Images.locationUserMarker.image.withRenderingMode(.alwaysTemplate) - markerBackground.image = image - markerBackground.tintColor = Self.usernameColorGenerator.color(from: avatarData.matrixItemId) + func setAvatarData(_ avatarData: AvatarViewDataProtocol, avatarBackgroundColor: UIColor) { + backgroundImageView.image = Asset.Images.locationUserMarker.image + backgroundImageView.tintColor = avatarBackgroundColor avatarView.fill(with: avatarData) } } diff --git a/Riot/Modules/Room/Location/LocationMarkerView.xib b/Riot/Modules/Room/Location/LocationMarkerView.xib index a71c32515d..ba9cacb271 100644 --- a/Riot/Modules/Room/Location/LocationMarkerView.xib +++ b/Riot/Modules/Room/Location/LocationMarkerView.xib @@ -1,8 +1,6 @@ - - @@ -65,7 +63,7 @@ - + diff --git a/Riot/Modules/Room/Location/RoomTimelineLocationView.swift b/Riot/Modules/Room/Location/RoomTimelineLocationView.swift index 5ffb88e154..cb2fb91469 100644 --- a/Riot/Modules/Room/Location/RoomTimelineLocationView.swift +++ b/Riot/Modules/Room/Location/RoomTimelineLocationView.swift @@ -39,6 +39,7 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat private var mapView: MGLMapView! private var annotationView: LocationMarkerView? + private static var usernameColorGenerator = UserNameColorGenerator() // MARK: Public @@ -82,7 +83,8 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat annotationView = LocationMarkerView.loadFromNib() if let userAvatarData = userAvatarData { - annotationView?.setAvatarData(userAvatarData) + let avatarBackgroundColor = Self.usernameColorGenerator.color(from: userAvatarData.matrixItemId) + annotationView?.setAvatarData(userAvatarData, avatarBackgroundColor: avatarBackgroundColor) } if let annotations = mapView.annotations { @@ -99,6 +101,7 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat // MARK: - Themable func update(theme: Theme) { + Self.usernameColorGenerator.update(theme: theme) descriptionLabel.textColor = theme.colors.primaryContent descriptionLabel.font = theme.fonts.footnote descriptionIcon.tintColor = theme.colors.accent diff --git a/Riot/Modules/Threads/ThreadList/Views/Cell/ThreadTableViewCell.swift b/Riot/Modules/Threads/ThreadList/Views/Cell/ThreadTableViewCell.swift index 48a7f8cf9d..b99eec0c35 100644 --- a/Riot/Modules/Threads/ThreadList/Views/Cell/ThreadTableViewCell.swift +++ b/Riot/Modules/Threads/ThreadList/Views/Cell/ThreadTableViewCell.swift @@ -94,8 +94,7 @@ extension ThreadTableViewCell: Themable { func update(theme: Theme) { self.theme = theme - Self.usernameColorGenerator.defaultColor = theme.colors.primaryContent - Self.usernameColorGenerator.userNameColors = theme.colors.namesAndAvatars + Self.usernameColorGenerator.update(theme: theme) updateRootMessageSenderColor() rootMessageAvatarView.backgroundColor = .clear if let attributedText = rootMessageContentLabel.attributedText { diff --git a/Riot/Utils/UserNameColorGenerator.swift b/Riot/Utils/UserNameColorGenerator.swift index 3e5c2adcd6..9e34361f85 100644 --- a/Riot/Utils/UserNameColorGenerator.swift +++ b/Riot/Utils/UserNameColorGenerator.swift @@ -48,3 +48,12 @@ final class UserNameColorGenerator: NSObject { return self.userNameColors[senderNameColorIndex] } } + +// MARK: - Themable +extension UserNameColorGenerator: Themable { + + func update(theme: Theme) { + self.defaultColor = theme.colors.primaryContent + self.userNameColors = theme.colors.namesAndAvatars + } +} diff --git a/RiotSwiftUI/Modules/Common/Avatar/View/AvatarImage.swift b/RiotSwiftUI/Modules/Common/Avatar/View/AvatarImage.swift index 5bed53bd5e..54a8901555 100644 --- a/RiotSwiftUI/Modules/Common/Avatar/View/AvatarImage.swift +++ b/RiotSwiftUI/Modules/Common/Avatar/View/AvatarImage.swift @@ -27,7 +27,14 @@ struct AvatarImage: View { var mxContentUri: String? var matrixItemId: String var displayName: String? - var size: AvatarSize + var size: AvatarSize? + + var sizeValue: CGFloat? { + guard let size = size else { + return nil + } + return CGFloat(size.rawValue) + } var body: some View { Group { @@ -42,7 +49,7 @@ struct AvatarImage: View { .resizable() } } - .frame(width: CGFloat(size.rawValue), height: CGFloat(size.rawValue)) + .frame(width: sizeValue, height: sizeValue) .clipShape(Circle()) .onAppear { viewModel.inject(dependencies: dependencies) @@ -59,7 +66,7 @@ struct AvatarImage: View { @available(iOS 14.0, *) extension AvatarImage { - init(avatarData: AvatarInputProtocol, size: AvatarSize) { + init(avatarData: AvatarInputProtocol, size: AvatarSize?) { self.init( mxContentUri: avatarData.mxContentUri, matrixItemId: avatarData.matrixItemId, diff --git a/RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarViewModel.swift b/RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarViewModel.swift index 2b49dc2897..fd8216d6f9 100644 --- a/RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarViewModel.swift +++ b/RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarViewModel.swift @@ -40,7 +40,7 @@ class AvatarViewModel: InjectableObject, ObservableObject { matrixItemId: String, displayName: String?, colorCount: Int, - avatarSize: AvatarSize) { + avatarSize: AvatarSize?) { let placeholderViewModel = PlaceholderAvatarViewModel(displayName: displayName, matrixItemId: matrixItemId, @@ -52,7 +52,7 @@ class AvatarViewModel: InjectableObject, ObservableObject { return } - avatarService.avatarImage(mxContentUri: mxContentUri, avatarSize: avatarSize) + avatarService.avatarImage(mxContentUri: mxContentUri, avatarSize: avatarSize ?? .large) .sink { completion in guard case let .failure(error) = completion else { return } UILog.error("[AvatarService] Failed to retrieve avatar: \(error)") diff --git a/RiotSwiftUI/Modules/Common/Theme/ThemeNamesColorsExtension.swift b/RiotSwiftUI/Modules/Common/Theme/ThemeUsersColorsExtension.swift similarity index 94% rename from RiotSwiftUI/Modules/Common/Theme/ThemeNamesColorsExtension.swift rename to RiotSwiftUI/Modules/Common/Theme/ThemeUsersColorsExtension.swift index ae52e2ec71..de81faac83 100644 --- a/RiotSwiftUI/Modules/Common/Theme/ThemeNamesColorsExtension.swift +++ b/RiotSwiftUI/Modules/Common/Theme/ThemeUsersColorsExtension.swift @@ -23,7 +23,7 @@ extension ThemeSwiftUI { /// Get the stable display name color based on userId. /// - Parameter userId: The user id used to hash. /// - Returns: The SwiftUI color for the associated userId. - func displayNameColor(for userId: String) -> Color { + func displayUserColor(for userId: String) -> Color { let senderNameColorIndex = Int(userId.vc_hashCode % Int32(colors.namesAndAvatars.count)) return colors.namesAndAvatars[senderNameColorIndex] } diff --git a/RiotSwiftUI/Modules/Common/Util/BorderModifier.swift b/RiotSwiftUI/Modules/Common/Util/BorderModifier.swift new file mode 100644 index 0000000000..e6da415b42 --- /dev/null +++ b/RiotSwiftUI/Modules/Common/Util/BorderModifier.swift @@ -0,0 +1,37 @@ +// +// Copyright 2022 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 SwiftUI + +@available(iOS 14.0, *) +struct BorderModifier: ViewModifier { + + var color: Color + var borderWidth: CGFloat + var shape: Shape + + func body(content: Content) -> some View { + content + .overlay(shape.stroke(color, lineWidth: borderWidth)) + } +} + +@available(iOS 14.0, *) +extension View { + func shapedBorder(color: Color, borderWidth: CGFloat, shape: Shape) -> some View { + modifier(BorderModifier(color: color, borderWidth: borderWidth, shape: shape)) + } +} diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift b/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift index ef7c29daec..85adbc669b 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift @@ -49,7 +49,8 @@ final class LocationSharingCoordinator: Coordinator, Presentable { let viewModel = LocationSharingViewModel(mapStyleURL: BuildSettings.tileServerMapStyleURL, avatarData: parameters.avatarData, - location: parameters.location) + location: parameters.location, + isLiveLocationSharingEnabled: BuildSettings.liveLocationSharingEnabled) let view = LocationSharingView(context: viewModel.context) .addDependency(AvatarService.instantiate(mediaManager: parameters.mediaManager)) diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift index 069719e243..84a8e0534d 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift @@ -62,6 +62,9 @@ struct LocationSharingViewState: BindableState { /// True to indicate to show and follow current user location var showsUserLocation: Bool = false + /// Used to hide live location sharing features until is finished + var isLiveLocationSharingEnabled: Bool + var shareButtonVisible: Bool { return self.displayExistingLocation == false } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift index c5aa78c864..0c9b218533 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift @@ -37,7 +37,8 @@ enum MockLocationSharingScreenState: MockScreenState, CaseIterable { let mapStyleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx")! let viewModel = LocationSharingViewModel(mapStyleURL: mapStyleURL, avatarData: AvatarInput(mxContentUri: "", matrixItemId: "alice:matrix.org", displayName: "Alice"), - location: location) + location: location, + isLiveLocationSharingEnabled: true) return ([viewModel], AnyView(LocationSharingView(context: viewModel.context) .addDependency(MockAvatarService.example))) diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift index 807c5605c6..ac02e04e3c 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift @@ -35,7 +35,7 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie // MARK: - Setup - init(mapStyleURL: URL, avatarData: AvatarInputProtocol, location: CLLocationCoordinate2D? = nil) { + init(mapStyleURL: URL, avatarData: AvatarInputProtocol, location: CLLocationCoordinate2D? = nil, isLiveLocationSharingEnabled: Bool) { var userAnnotation: UserLocationAnnotation? var annotations: [UserLocationAnnotation] = [] @@ -60,7 +60,8 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie userAnnotation: userAnnotation, annotations: annotations, highlightedAnnotation: highlightedAnnotation, - showsUserLocation: showsUserLocation) + showsUserLocation: showsUserLocation, + isLiveLocationSharingEnabled: isLiveLocationSharingEnabled) super.init(initialViewState: viewState) diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift similarity index 50% rename from RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift rename to RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift index 361e76fcf4..9af3050efd 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift @@ -17,7 +17,7 @@ import SwiftUI @available(iOS 14.0, *) -struct LocationSharingUserMarkerView: View { +struct LocationSharingMarkerView: View { // MARK: - Properties @@ -25,37 +25,21 @@ struct LocationSharingUserMarkerView: View { @Environment(\.theme) private var theme: ThemeSwiftUI - @State private var frame: CGRect = .zero - - private var usernameColorGenerator: UserNameColorGenerator { - let usernameColorGenerator = UserNameColorGenerator() - let theme = ThemeService.shared().theme - usernameColorGenerator.defaultColor = theme.textPrimaryColor - usernameColorGenerator.userNameColors = theme.userNameColors - return usernameColorGenerator - } - // MARK: Public - let isMarker: Bool - let avatarData: AvatarInputProtocol + let backgroundColor: Color + @ViewBuilder var markerImage: Content var body: some View { - let fillColor: Color = Color(usernameColorGenerator.color(from:avatarData.matrixItemId)) ZStack { - Circle() - .fill(fillColor) - .frame(width: 40, height: 40) - if isMarker { - Rectangle() - .rotation(Angle(degrees: 45)) - .fill(fillColor) - .frame(width: 7, height: 7) - .offset(x: 0, y: 19) - } - AvatarImage(avatarData: avatarData, size: .small) + Rectangle() + .rotation(Angle(degrees: 45)) + .fill(backgroundColor) + .frame(width: 7, height: 7) + .offset(x: 0, y: 22) + markerImage + .frame(width: 42, height: 42) } - .background(ViewFrameReader(frame: $frame)) } } @@ -68,8 +52,14 @@ struct LocationSharingUserMarkerView_Previews: PreviewProvider { matrixItemId: "test", displayName: "Alice") VStack(alignment: .center, spacing: 15) { - LocationSharingUserMarkerView(isMarker: true, avatarData: avatarData) - LocationSharingUserMarkerView(isMarker: false, avatarData: avatarData) + LocationSharingMarkerView(backgroundColor: .green) { + AvatarImage(avatarData: avatarData, size: nil) + .shapedBorder(color: Color.green, borderWidth: 3, shape: Circle()) + } + LocationSharingMarkerView(backgroundColor: .green) { + AvatarImage(avatarData: avatarData, size: nil) + .shapedBorder(color: Color.green, borderWidth: 3, shape: Circle()) + } } } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift index 2c64a32589..434fd48cb6 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift @@ -27,12 +27,12 @@ struct LocationSharingOptionButton: View { let text: String let action: () -> (Void) - @ViewBuilder var content: Content + @ViewBuilder var buttonIcon: Content var body: some View { Button(action: action) { HStack(spacing: 18) { - content + buttonIcon .frame(width: 40, height: 40) Text(text) .font(theme.fonts.body) @@ -45,16 +45,22 @@ struct LocationSharingOptionButton: View { @available(iOS 14.0, *) struct LocationSharingOptionButton_Previews: PreviewProvider { static var previews: some View { - VStack { - LocationSharingOptionButton(text: "Share my current location") { + VStack(alignment: .leading) { + LocationSharingOptionButton(text: VectorL10n.locationSharingStaticShareTitle) { - } content: { - LocationSharingUserMarkerView(isMarker: false, avatarData: AvatarInput(mxContentUri: "", matrixItemId: "test", displayName: "Nicolas")) + } buttonIcon: { + AvatarImage(avatarData: AvatarInput(mxContentUri: nil, matrixItemId: "Alice", displayName: "Alice"), size: nil) + .shapedBorder(color: Color.green, borderWidth: 3, shape: Circle()) } - LocationSharingOptionButton(text: "Share live location") { + LocationSharingOptionButton(text: VectorL10n.locationSharingLiveShareTitle) { - } content: { - LocationSharingOptionButtonIcon(fillColor: Color.purple, image: Asset.Images.liveLocationIcon.image) + } buttonIcon: { + Image(uiImage: Asset.Images.locationLiveIcon.image) + } + LocationSharingOptionButton(text: VectorL10n.locationSharingPinDropShareTitle) { + + } buttonIcon: { + Image(uiImage: Asset.Images.locationPinIcon.image) } } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButtonIcon.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButtonIcon.swift deleted file mode 100644 index 5cb69a2e32..0000000000 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButtonIcon.swift +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright 2022 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 SwiftUI - -@available(iOS 14.0, *) -struct LocationSharingOptionButtonIcon: View { - - // MARK: - Properties - - // MARK: Private - - @Environment(\.theme) private var theme: ThemeSwiftUI - - let fillColor: Color - let image: UIImage - - var body: some View { - ZStack { - Circle() - .fill(fillColor) - .frame(width: 40, height: 40) - Image(uiImage: image) - .renderingMode(.template) - .foregroundColor(Color.white) - } - } -} - -@available(iOS 14.0, *) -struct LocationSharingOptionButtonIcon_Previews: PreviewProvider { - static var previews: some View { - LocationSharingOptionButtonIcon(fillColor: Color.green, image: Asset.Images.locationMarkerIcon.image) - } -} diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift index 43f77cc92d..dc355b83e7 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift @@ -32,7 +32,7 @@ struct LocationSharingView: View { var body: some View { NavigationView { - VStack { + VStack(spacing: 0) { ZStack(alignment: .bottom) { LocationSharingMapView(tileServerMapURL: context.viewState.mapStyleURL, annotations: context.viewState.annotations, @@ -46,7 +46,7 @@ struct LocationSharingView: View { } if context.viewState.shareButtonVisible { buttonsView - .cornerRadius(5) + .cornerRadius(10) } } .toolbar { @@ -90,25 +90,25 @@ struct LocationSharingView: View { if !context.viewState.isPinDropSharing { LocationSharingOptionButton(text: VectorL10n.locationSharingStaticShareTitle) { context.send(viewAction: .share) - } content: { - LocationSharingUserMarkerView(isMarker: false, avatarData: context.viewState.userAvatarData) + } buttonIcon: { + AvatarImage(avatarData: context.viewState.userAvatarData, size: nil) + .shapedBorder(color: theme.displayUserColor(for: context.viewState.userAvatarData.matrixItemId), borderWidth: 3, shape: Circle()) } .disabled(!context.viewState.shareButtonEnabled) - // Disable for now until live location sharing is done - if BuildSettings.liveLocationSharingEnabled { + // Hide for now until live location sharing is finished + if context.viewState.isLiveLocationSharingEnabled { LocationSharingOptionButton(text: VectorL10n.locationSharingLiveShareTitle) { // TODO: - Start live location sharing - } content: { - LocationSharingOptionButtonIcon(fillColor: Color.purple, image: Asset.Images.liveLocationIcon.image) + } buttonIcon: { + Image(uiImage: Asset.Images.locationLiveIcon.image) } .disabled(!context.viewState.shareButtonEnabled) } } else { LocationSharingOptionButton(text: VectorL10n.locationSharingPinDropShareTitle) { // TODO: - Pin drop sharing action - } content: { - LocationSharingOptionButtonIcon(fillColor: - theme.colors.primaryContent, image: Asset.Images.locationMarkerIcon.image) + } buttonIcon: { + Image(uiImage: Asset.Images.locationPinIcon.image) } .disabled(!context.viewState.shareButtonEnabled) } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift index e713508bdc..5c51b0acfd 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift @@ -21,6 +21,10 @@ import Mapbox @available(iOS 14, *) class UserLocationAnnotatonView: MGLUserLocationAnnotationView { + // MARK: Private + + @Environment(\.theme) private var theme: ThemeSwiftUI + // MARK: - Setup init(avatarData: AvatarInputProtocol) { @@ -45,7 +49,10 @@ class UserLocationAnnotatonView: MGLUserLocationAnnotationView { private func addUserMarkerView(with avatarData: AvatarInputProtocol) { - guard let avatarImageView = UIHostingController(rootView: LocationSharingUserMarkerView(isMarker: true, avatarData: avatarData)).view else { + guard let avatarImageView = UIHostingController(rootView: LocationSharingMarkerView(backgroundColor: theme.displayUserColor(for: avatarData.matrixItemId)) { + AvatarImage(avatarData: avatarData, size: nil) + .shapedBorder(color: theme.displayUserColor(for: avatarData.matrixItemId), borderWidth: 3, shape: Circle()) + }).view else { return } diff --git a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomChat/View/TemplateRoomChatBubbleView.swift b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomChat/View/TemplateRoomChatBubbleView.swift index b324a9565f..27c79c9b3f 100644 --- a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomChat/View/TemplateRoomChatBubbleView.swift +++ b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomChat/View/TemplateRoomChatBubbleView.swift @@ -35,7 +35,7 @@ struct TemplateRoomChatBubbleView: View { .accessibility(identifier: "bubbleImage") VStack(alignment: .leading){ Text(bubble.sender.displayName ?? "") - .foregroundColor(theme.displayNameColor(for: bubble.sender.id)) + .foregroundColor(theme.displayUserColor(for: bubble.sender.id)) .font(theme.fonts.bodySB) ForEach(bubble.items) { item in TemplateRoomChatBubbleContentView(bubbleItem: item) From db8c5cc075882347de5bc193396739a00a996855 Mon Sep 17 00:00:00 2001 From: MaximeE Date: Wed, 23 Mar 2022 17:25:30 +0100 Subject: [PATCH 4/5] 5720: Fix issue with cornered buttons view --- .../LocationSharingModels.swift | 2 +- .../LocationSharingViewModel.swift | 2 +- .../Test/UI/LocationSharingUITests.swift | 1 - .../View/LocationSharingView.swift | 28 +++++++++---------- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift index 84a8e0534d..f06d80562c 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift @@ -63,7 +63,7 @@ struct LocationSharingViewState: BindableState { var showsUserLocation: Bool = false /// Used to hide live location sharing features until is finished - var isLiveLocationSharingEnabled: Bool + var isLiveLocationSharingEnabled: Bool = false var shareButtonVisible: Bool { return self.displayExistingLocation == false diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift index ac02e04e3c..bccd953913 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift @@ -35,7 +35,7 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie // MARK: - Setup - init(mapStyleURL: URL, avatarData: AvatarInputProtocol, location: CLLocationCoordinate2D? = nil, isLiveLocationSharingEnabled: Bool) { + init(mapStyleURL: URL, avatarData: AvatarInputProtocol, location: CLLocationCoordinate2D? = nil, isLiveLocationSharingEnabled: Bool = false) { var userAnnotation: UserLocationAnnotation? var annotations: [UserLocationAnnotation] = [] diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/Test/UI/LocationSharingUITests.swift b/RiotSwiftUI/Modules/Room/LocationSharing/Test/UI/LocationSharingUITests.swift index d5040db2f3..469d470049 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/Test/UI/LocationSharingUITests.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/Test/UI/LocationSharingUITests.swift @@ -33,7 +33,6 @@ class LocationSharingUITests: XCTestCase { goToScreenWithIdentifier(MockLocationSharingScreenState.shareUserLocation.title) XCTAssertTrue(app.buttons["Cancel"].exists) - XCTAssertTrue(app.buttons["Share"].exists) XCTAssertTrue(app.otherElements["Map"].exists) } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift index dc355b83e7..0e2c67b550 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift @@ -32,21 +32,21 @@ struct LocationSharingView: View { var body: some View { NavigationView { - VStack(spacing: 0) { - ZStack(alignment: .bottom) { - LocationSharingMapView(tileServerMapURL: context.viewState.mapStyleURL, - annotations: context.viewState.annotations, - highlightedAnnotation: context.viewState.highlightedAnnotation, - userAvatarData: context.viewState.userAvatarData, - showsUserLocation: context.viewState.showsUserLocation, - userLocation: $context.userLocation, - errorSubject: context.viewState.errorSubject) - .ignoresSafeArea() + ZStack(alignment: .bottom) { + LocationSharingMapView(tileServerMapURL: context.viewState.mapStyleURL, + annotations: context.viewState.annotations, + highlightedAnnotation: context.viewState.highlightedAnnotation, + userAvatarData: context.viewState.userAvatarData, + showsUserLocation: context.viewState.showsUserLocation, + userLocation: $context.userLocation, + errorSubject: context.viewState.errorSubject) + VStack(spacing: 0) { MapCreditsView() - } - if context.viewState.shareButtonVisible { - buttonsView - .cornerRadius(10) + if context.viewState.shareButtonVisible { + buttonsView + .background(theme.colors.background) + .clipShape(RoundedCornerShape(radius: 8, corners: [.topLeft, .topRight])) + } } } .toolbar { From 064c97497a7ed4574f23f6308ee08ac9dabf41e5 Mon Sep 17 00:00:00 2001 From: MaximeE Date: Thu, 24 Mar 2022 11:00:29 +0100 Subject: [PATCH 5/5] 5720: Remove useless color, fix some issue with AvatarImage border --- DesignKit/Source/ColorValues.swift | 6 ----- DesignKit/Source/Colors.swift | 8 ------ DesignKit/Source/ColorsSwiftUI.swift | 8 ------ DesignKit/Source/ColorsUIkit.swift | 8 ------ .../Variants/Colors/Dark/DarkColors.swift | 4 +-- .../Variants/Colors/Light/LightColors.swift | 4 +-- .../Common/Avatar/View/AvatarImage.swift | 26 ++++++++++++------- .../Avatar/ViewModel/AvatarViewModel.swift | 4 +-- .../Theme/ThemeUsersColorsExtension.swift | 4 +-- .../View/LocationSharingMarkerView.swift | 12 ++++----- .../View/LocationSharingOptionButton.swift | 6 +++-- .../View/LocationSharingView.swift | 11 +++++--- .../View/UserLocationAnnotatonView.swift | 6 ++--- .../View/TemplateRoomChatBubbleView.swift | 2 +- 14 files changed, 44 insertions(+), 65 deletions(-) diff --git a/DesignKit/Source/ColorValues.swift b/DesignKit/Source/ColorValues.swift index b362ced8eb..5694a55039 100644 --- a/DesignKit/Source/ColorValues.swift +++ b/DesignKit/Source/ColorValues.swift @@ -47,10 +47,4 @@ public struct ColorValues: Colors { public let background: UIColor public let namesAndAvatars: [UIColor] - - // MARK: - Others colors - - public let white: UIColor - - public let purple: UIColor } diff --git a/DesignKit/Source/Colors.swift b/DesignKit/Source/Colors.swift index 605d7619cb..d7c885e59c 100644 --- a/DesignKit/Source/Colors.swift +++ b/DesignKit/Source/Colors.swift @@ -67,12 +67,4 @@ public protocol Colors { /// - Names in chat timeline /// - Avatars default states that include first name letter var namesAndAvatars: [ColorType] { get } - - // MARK: - Others colors - - /// White - var white: ColorType { get } - - /// Purple - var purple: ColorType { get } } diff --git a/DesignKit/Source/ColorsSwiftUI.swift b/DesignKit/Source/ColorsSwiftUI.swift index 2224adf7de..701aee5376 100644 --- a/DesignKit/Source/ColorsSwiftUI.swift +++ b/DesignKit/Source/ColorsSwiftUI.swift @@ -49,12 +49,6 @@ public struct ColorSwiftUI: Colors { public let namesAndAvatars: [Color] - // MARK: - Others colors - - public let white: Color - - public let purple: Color - init(values: ColorValues) { accent = Color(values.accent) alert = Color(values.alert) @@ -69,7 +63,5 @@ public struct ColorSwiftUI: Colors { navigation = Color(values.navigation) background = Color(values.background) namesAndAvatars = values.namesAndAvatars.map({ Color($0) }) - white = Color(values.white) - purple = Color(values.purple) } } diff --git a/DesignKit/Source/ColorsUIkit.swift b/DesignKit/Source/ColorsUIkit.swift index daff2b390e..3add385c36 100644 --- a/DesignKit/Source/ColorsUIkit.swift +++ b/DesignKit/Source/ColorsUIkit.swift @@ -47,12 +47,6 @@ import UIKit public let background: UIColor public let namesAndAvatars: [UIColor] - - // MARK: - Others colors - - public let white: UIColor - - public let purple: UIColor init(values: ColorValues) { accent = values.accent @@ -68,8 +62,6 @@ import UIKit navigation = values.navigation background = values.background namesAndAvatars = values.namesAndAvatars - white = values.white - purple = values.purple } } diff --git a/DesignKit/Variants/Colors/Dark/DarkColors.swift b/DesignKit/Variants/Colors/Dark/DarkColors.swift index b50a826511..b6b0ba5edd 100644 --- a/DesignKit/Variants/Colors/Dark/DarkColors.swift +++ b/DesignKit/Variants/Colors/Dark/DarkColors.swift @@ -42,9 +42,7 @@ public class DarkColors { UIColor(rgb:0x2DC2C5), UIColor(rgb:0x5C56F5), UIColor(rgb:0x74D12C) - ], - white: UIColor(rgb: 0xFFFFFF), - purple: UIColor(rgb: 0x5C56F5) + ] ) public static var uiKit = ColorsUIKit(values: values) diff --git a/DesignKit/Variants/Colors/Light/LightColors.swift b/DesignKit/Variants/Colors/Light/LightColors.swift index 9e73de5764..2e7d8147af 100644 --- a/DesignKit/Variants/Colors/Light/LightColors.swift +++ b/DesignKit/Variants/Colors/Light/LightColors.swift @@ -43,9 +43,7 @@ public class LightColors { UIColor(rgb:0x2DC2C5), UIColor(rgb:0x5C56F5), UIColor(rgb:0x74D12C) - ], - white: UIColor(rgb: 0xFFFFFF), - purple: UIColor(rgb: 0x5C56F5) + ] ) public static var uiKit = ColorsUIKit(values: values) diff --git a/RiotSwiftUI/Modules/Common/Avatar/View/AvatarImage.swift b/RiotSwiftUI/Modules/Common/Avatar/View/AvatarImage.swift index 54a8901555..6d0d444dc9 100644 --- a/RiotSwiftUI/Modules/Common/Avatar/View/AvatarImage.swift +++ b/RiotSwiftUI/Modules/Common/Avatar/View/AvatarImage.swift @@ -27,14 +27,7 @@ struct AvatarImage: View { var mxContentUri: String? var matrixItemId: String var displayName: String? - var size: AvatarSize? - - var sizeValue: CGFloat? { - guard let size = size else { - return nil - } - return CGFloat(size.rawValue) - } + var size: AvatarSize var body: some View { Group { @@ -49,7 +42,7 @@ struct AvatarImage: View { .resizable() } } - .frame(width: sizeValue, height: sizeValue) + .frame(maxWidth: CGFloat(size.rawValue), maxHeight: CGFloat(size.rawValue)) .clipShape(Circle()) .onAppear { viewModel.inject(dependencies: dependencies) @@ -66,7 +59,7 @@ struct AvatarImage: View { @available(iOS 14.0, *) extension AvatarImage { - init(avatarData: AvatarInputProtocol, size: AvatarSize?) { + init(avatarData: AvatarInputProtocol, size: AvatarSize) { self.init( mxContentUri: avatarData.mxContentUri, matrixItemId: avatarData.matrixItemId, @@ -76,6 +69,19 @@ extension AvatarImage { } } +@available(iOS 14.0, *) +extension AvatarImage { + func border(color: Color) -> some View { + modifier(BorderModifier(color: color, borderWidth: 3, shape: Circle())) + } + + /// Use display name color as border color by default + func border() -> some View { + let borderColor = theme.userColor(for: matrixItemId) + return self.border(color: borderColor) + } +} + @available(iOS 14.0, *) struct AvatarImage_Previews: PreviewProvider { static let mxContentUri = "fakeUri" diff --git a/RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarViewModel.swift b/RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarViewModel.swift index fd8216d6f9..00d410f806 100644 --- a/RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarViewModel.swift +++ b/RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarViewModel.swift @@ -40,7 +40,7 @@ class AvatarViewModel: InjectableObject, ObservableObject { matrixItemId: String, displayName: String?, colorCount: Int, - avatarSize: AvatarSize?) { + avatarSize: AvatarSize) { let placeholderViewModel = PlaceholderAvatarViewModel(displayName: displayName, matrixItemId: matrixItemId, @@ -52,7 +52,7 @@ class AvatarViewModel: InjectableObject, ObservableObject { return } - avatarService.avatarImage(mxContentUri: mxContentUri, avatarSize: avatarSize ?? .large) + avatarService.avatarImage(mxContentUri: mxContentUri, avatarSize: avatarSize) .sink { completion in guard case let .failure(error) = completion else { return } UILog.error("[AvatarService] Failed to retrieve avatar: \(error)") diff --git a/RiotSwiftUI/Modules/Common/Theme/ThemeUsersColorsExtension.swift b/RiotSwiftUI/Modules/Common/Theme/ThemeUsersColorsExtension.swift index de81faac83..dc1d93f0ce 100644 --- a/RiotSwiftUI/Modules/Common/Theme/ThemeUsersColorsExtension.swift +++ b/RiotSwiftUI/Modules/Common/Theme/ThemeUsersColorsExtension.swift @@ -20,10 +20,10 @@ import SwiftUI @available(iOS 14.0, *) extension ThemeSwiftUI { - /// Get the stable display name color based on userId. + /// Get the stable display user color based on userId. /// - Parameter userId: The user id used to hash. /// - Returns: The SwiftUI color for the associated userId. - func displayUserColor(for userId: String) -> Color { + func userColor(for userId: String) -> Color { let senderNameColorIndex = Int(userId.vc_hashCode % Int32(colors.namesAndAvatars.count)) return colors.namesAndAvatars[senderNameColorIndex] } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift index 9af3050efd..3c36e7d505 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift @@ -36,9 +36,9 @@ struct LocationSharingMarkerView: View { .rotation(Angle(degrees: 45)) .fill(backgroundColor) .frame(width: 7, height: 7) - .offset(x: 0, y: 22) + .offset(x: 0, y: 21) markerImage - .frame(width: 42, height: 42) + .frame(width: 40, height: 40) } } } @@ -53,12 +53,12 @@ struct LocationSharingUserMarkerView_Previews: PreviewProvider { displayName: "Alice") VStack(alignment: .center, spacing: 15) { LocationSharingMarkerView(backgroundColor: .green) { - AvatarImage(avatarData: avatarData, size: nil) - .shapedBorder(color: Color.green, borderWidth: 3, shape: Circle()) + AvatarImage(avatarData: avatarData, size: .medium) + .border() } LocationSharingMarkerView(backgroundColor: .green) { - AvatarImage(avatarData: avatarData, size: nil) - .shapedBorder(color: Color.green, borderWidth: 3, shape: Circle()) + AvatarImage(avatarData: avatarData, size: .medium) + .border() } } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift index 434fd48cb6..32fde8f48f 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift @@ -49,18 +49,20 @@ struct LocationSharingOptionButton_Previews: PreviewProvider { LocationSharingOptionButton(text: VectorL10n.locationSharingStaticShareTitle) { } buttonIcon: { - AvatarImage(avatarData: AvatarInput(mxContentUri: nil, matrixItemId: "Alice", displayName: "Alice"), size: nil) - .shapedBorder(color: Color.green, borderWidth: 3, shape: Circle()) + AvatarImage(avatarData: AvatarInput(mxContentUri: nil, matrixItemId: "Alice", displayName: "Alice"), size: .medium) + .border() } LocationSharingOptionButton(text: VectorL10n.locationSharingLiveShareTitle) { } buttonIcon: { Image(uiImage: Asset.Images.locationLiveIcon.image) + .resizable() } LocationSharingOptionButton(text: VectorL10n.locationSharingPinDropShareTitle) { } buttonIcon: { Image(uiImage: Asset.Images.locationPinIcon.image) + .resizable() } } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift index 0e2c67b550..ce3ae579c7 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift @@ -91,8 +91,8 @@ struct LocationSharingView: View { LocationSharingOptionButton(text: VectorL10n.locationSharingStaticShareTitle) { context.send(viewAction: .share) } buttonIcon: { - AvatarImage(avatarData: context.viewState.userAvatarData, size: nil) - .shapedBorder(color: theme.displayUserColor(for: context.viewState.userAvatarData.matrixItemId), borderWidth: 3, shape: Circle()) + AvatarImage(avatarData: context.viewState.userAvatarData, size: .medium) + .border() } .disabled(!context.viewState.shareButtonEnabled) // Hide for now until live location sharing is finished @@ -101,6 +101,7 @@ struct LocationSharingView: View { // TODO: - Start live location sharing } buttonIcon: { Image(uiImage: Asset.Images.locationLiveIcon.image) + .resizable() } .disabled(!context.viewState.shareButtonEnabled) } @@ -109,6 +110,7 @@ struct LocationSharingView: View { // TODO: - Pin drop sharing action } buttonIcon: { Image(uiImage: Asset.Images.locationPinIcon.image) + .resizable() } .disabled(!context.viewState.shareButtonEnabled) } @@ -131,6 +133,9 @@ struct LocationSharingView: View { struct LocationSharingView_Previews: PreviewProvider { static let stateRenderer = MockLocationSharingScreenState.stateRenderer static var previews: some View { - stateRenderer.screenGroup() + Group { + stateRenderer.screenGroup().theme(.light).preferredColorScheme(.light) + stateRenderer.screenGroup().theme(.dark).preferredColorScheme(.dark) + } } } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift index 5c51b0acfd..15c8e0593a 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotatonView.swift @@ -49,9 +49,9 @@ class UserLocationAnnotatonView: MGLUserLocationAnnotationView { private func addUserMarkerView(with avatarData: AvatarInputProtocol) { - guard let avatarImageView = UIHostingController(rootView: LocationSharingMarkerView(backgroundColor: theme.displayUserColor(for: avatarData.matrixItemId)) { - AvatarImage(avatarData: avatarData, size: nil) - .shapedBorder(color: theme.displayUserColor(for: avatarData.matrixItemId), borderWidth: 3, shape: Circle()) + guard let avatarImageView = UIHostingController(rootView: LocationSharingMarkerView(backgroundColor: theme.userColor(for: avatarData.matrixItemId)) { + AvatarImage(avatarData: avatarData, size: .medium) + .border() }).view else { return } diff --git a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomChat/View/TemplateRoomChatBubbleView.swift b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomChat/View/TemplateRoomChatBubbleView.swift index 27c79c9b3f..aeea1b2622 100644 --- a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomChat/View/TemplateRoomChatBubbleView.swift +++ b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomChat/View/TemplateRoomChatBubbleView.swift @@ -35,7 +35,7 @@ struct TemplateRoomChatBubbleView: View { .accessibility(identifier: "bubbleImage") VStack(alignment: .leading){ Text(bubble.sender.displayName ?? "") - .foregroundColor(theme.displayUserColor(for: bubble.sender.id)) + .foregroundColor(theme.userColor(for: bubble.sender.id)) .font(theme.fonts.bodySB) ForEach(bubble.items) { item in TemplateRoomChatBubbleContentView(bubbleItem: item)