diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 32c7ac828..cd2d7b3b0 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -71,6 +71,7 @@ 1B2DADC008EE211AF1DA5292 /* NotificationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */; }; 1B4B3E847BF944DB2C1C217F /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE73D571D4F9C36DD45255A /* BackgroundTaskServiceProtocol.swift */; }; 1B88BB631F7FC45A213BB554 /* TimelineItemSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55AEEF8142DF1B59DB40FB93 /* TimelineItemSender.swift */; }; + 1BA04D05EBC6646958B1BE60 /* PlaceholderScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF34A2FD6797535C95AC918D /* PlaceholderScreenCoordinator.swift */; }; 1C409A26A99F0371C47AFA51 /* UserDiscoveryServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F615A00DB223FF3280204D2 /* UserDiscoveryServiceProtocol.swift */; }; 1C9BB74711E5F24C77B7FED0 /* RoomMembersListScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AEA0B743847CFA5B3C38EE4 /* RoomMembersListScreenCoordinator.swift */; }; 1D69E31913DF66426985909B /* EmojiPickerScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11151E78D6BB2B04A8FBD389 /* EmojiPickerScreenViewModelProtocol.swift */; }; @@ -1209,6 +1210,7 @@ BE89A8BD65CCE3FCC925CA14 /* TimelineItemReplyDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemReplyDetails.swift; sourceTree = ""; }; BEA38B9851CFCC4D67F5587D /* EmojiPickerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenCoordinator.swift; sourceTree = ""; }; BEBA759D1347CFFB3D84ED1F /* UserSessionStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStoreProtocol.swift; sourceTree = ""; }; + BF34A2FD6797535C95AC918D /* PlaceholderScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderScreenCoordinator.swift; sourceTree = ""; }; BFDCAC6CAAD65A2C24EA9C4B /* Dictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = ""; }; BFEA446F8618DBA79A9239CC /* MessageForwardingScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreen.swift; sourceTree = ""; }; C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXAttributeScope.swift; sourceTree = ""; }; @@ -2771,6 +2773,7 @@ A448A3A8F764174C60CD0CA1 /* Other */ = { isa = PBXGroup; children = ( + BF34A2FD6797535C95AC918D /* PlaceholderScreenCoordinator.swift */, 854BCEAF2A832176FAACD2CB /* SplashScreenCoordinator.swift */, ); path = Other; @@ -4155,6 +4158,7 @@ 80D00A7C62AAB44F54725C43 /* PermalinkBuilder.swift in Sources */, 962A4F8AD6312804E2C6BB6E /* PhotoLibraryPicker.swift in Sources */, 9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */, + 1BA04D05EBC6646958B1BE60 /* PlaceholderScreenCoordinator.swift in Sources */, DF504B10A4918F971A57BEF2 /* PostHogAnalyticsClient.swift in Sources */, 2835FD52F3F618D07F799B3D /* Publisher.swift in Sources */, 743790BF6A5B0577EA74AF14 /* ReadMarkerRoomTimelineItem.swift in Sources */, diff --git a/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/AppLogo.svg b/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/AppLogo.svg new file mode 100644 index 000000000..726d49f27 --- /dev/null +++ b/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/AppLogo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/Contents.json b/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/Contents.json index 332aaf86f..f0cd05d2c 100644 --- a/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/Contents.json +++ b/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/Contents.json @@ -1,19 +1,8 @@ { "images" : [ { - "filename" : "launch_screen_logo.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "launch_screen_logo@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "launch_screen_logo@3x.png", - "idiom" : "universal", - "scale" : "3x" + "filename" : "AppLogo.svg", + "idiom" : "universal" } ], "info" : { @@ -21,6 +10,6 @@ "version" : 1 }, "properties" : { - "template-rendering-intent" : "template" + "preserves-vector-representation" : true } } diff --git a/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/launch_screen_logo.png b/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/launch_screen_logo.png deleted file mode 100644 index 85d7a6a01..000000000 Binary files a/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/launch_screen_logo.png and /dev/null differ diff --git a/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/launch_screen_logo@2x.png b/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/launch_screen_logo@2x.png deleted file mode 100644 index ac3f21dfb..000000000 Binary files a/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/launch_screen_logo@2x.png and /dev/null differ diff --git a/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/launch_screen_logo@3x.png b/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/launch_screen_logo@3x.png deleted file mode 100644 index e049f4e98..000000000 Binary files a/ElementX/Resources/Assets.xcassets/Images/app-logo.imageset/launch_screen_logo@3x.png and /dev/null differ diff --git a/ElementX/Sources/Application/AppCoordinator.swift b/ElementX/Sources/Application/AppCoordinator.swift index 06e56c886..e516b3fd9 100644 --- a/ElementX/Sources/Application/AppCoordinator.swift +++ b/ElementX/Sources/Application/AppCoordinator.swift @@ -322,7 +322,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate, fatalError("User session not setup") } - let navigationSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: SplashScreenCoordinator()) + let navigationSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: PlaceholderScreenCoordinator()) let userSessionFlowCoordinator = UserSessionFlowCoordinator(userSession: userSession, navigationSplitCoordinator: navigationSplitCoordinator, bugReportService: ServiceLocator.shared.bugReportService, diff --git a/ElementX/Sources/Screens/Other/PlaceholderScreenCoordinator.swift b/ElementX/Sources/Screens/Other/PlaceholderScreenCoordinator.swift new file mode 100644 index 000000000..4578b1809 --- /dev/null +++ b/ElementX/Sources/Screens/Other/PlaceholderScreenCoordinator.swift @@ -0,0 +1,112 @@ +// +// 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 SwiftUI + +class PlaceholderScreenCoordinator: CoordinatorProtocol { + func toPresentable() -> AnyView { + AnyView(PlaceholderScreen()) + } +} + +/// The app's splash screen. This screen is shown after the LaunchScreen +/// until the app is ready to show the relevant coordinator. The design of +/// these 2 screens are matched. +struct PlaceholderScreen: View { + @Environment(\.colorScheme) private var colorScheme + + private let outerShape = RoundedRectangle(cornerRadius: 44) + private var isLight: Bool { colorScheme == .light } + + var body: some View { + image + .accessibilityHidden(true) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background() + .environment(\.backgroundStyle, AnyShapeStyle(Color.compound.bgCanvasDefault)) + .toolbar(.hidden, for: .automatic) + } + + @ViewBuilder + var image: some View { + if isLight { + logo + } else { + darkLogo + } + } + + var logo: some View { + Image(asset: Asset.Images.appLogo) + .padding(24) + .background(.white.opacity(0.4)) + .clipShape(outerShape) + .background { + outerShape.fill(Color.white) + .shadow(color: Color(red: 0.11, green: 0.11, blue: 0.13).opacity(0.08), radius: 16, y: 8) + + outerShape.fill(Color.white) + .shadow(color: Color(red: 0.11, green: 0.11, blue: 0.13).opacity(0.5), radius: 16, y: 8) + .blendMode(.overlay) + } + .overlay { + outerShape + .inset(by: 0.25) + .stroke(.white, lineWidth: 0.5) + } + } + + var darkLogo: some View { + Image(asset: Asset.Images.appLogo) + .shadow(color: .black.opacity(0.2), radius: 0.5, y: 2) + .shadow(color: Color(red: 0.05, green: 0.74, blue: 0.55).opacity(0.2), radius: 16) + .padding(24) + .background { + LinearGradient(stops: [.init(color: .white.opacity(0.05), location: 0.00), + .init(color: .white.opacity(0), location: 1.00)], + startPoint: UnitPoint(x: 0, y: 0), + endPoint: UnitPoint(x: 1, y: 1)) + .blendMode(.multiply) + } + .clipShape(outerShape) + .shadow(color: .black.opacity(0.9), radius: 80, x: 0, y: 1) + .overlay { + outerShape + .inset(by: 0.25) + .stroke(.white.opacity(0.9), lineWidth: 0.5) + .blendMode(.overlay) + } + } +} + +struct PlaceholderScreen_Previews: PreviewProvider { + static var previews: some View { + PlaceholderScreen() + .previewDisplayName("Screen") + + NavigationSplitView { + List { + ForEach("Nothing to see here".split(separator: " "), id: \.self) { word in + Text(word) + } + } + } detail: { + PlaceholderScreen() + } + .previewDisplayName("Split View") + .previewInterfaceOrientation(.landscapeLeft) + } +} diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index 177706596..2dd8c0d0c 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -356,15 +356,19 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol ] if timelineItem is EventBasedMessageTimelineItemProtocol { - actions.append(contentsOf: [.forward(itemID: itemId), .copy]) + actions.append(.forward(itemID: itemId)) } - actions.append(.copyPermalink) - if item.isEditable { actions.append(.edit) } + if timelineItem is EventBasedMessageTimelineItemProtocol { + actions.append(.copy) + } + + actions.append(.copyPermalink) + if item.isOutgoing { actions.append(.redact) } else {