mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 11:58:32 +00:00
App Polish (#1098)
* App polish - Skeleton avatar colour on app switching. - Bug report icon and string. - Semi-bold font on room list timestamps. - Room attachments button spacing and alignment. - Replace link tint with semi-bold font in AnalyticsSettingsScreen. - Semi-bold font on Invites button. - Add padding to media attachment sheet. - Message composer header layout tweaks. - Remove indicator after changing homeserver with an MXID. - Change copy permalink string. - Formatting of link in Analytics Prompt. - Remove indicator after changing homeserver with an MXID. - Change copy permalink string. - Formatting of link in Analytics Prompt. - Only semi-bold the room timestamp when unread. - Tweak the colour of the date separator. - Add activity indicator to toast style user indicator.
This commit is contained in:
@@ -44,12 +44,15 @@ struct AnalyticsPromptScreenStrings {
|
||||
|
||||
init(termsURL: URL) {
|
||||
let content = AttributedString(L10n.screenAnalyticsPromptHelpUsImprove(InfoPlistReader.main.bundleDisplayName))
|
||||
// Create the opt in content with a placeholder.
|
||||
|
||||
// Create the 'read terms' with a placeholder.
|
||||
let linkPlaceholder = "{link}"
|
||||
var readTerms = AttributedString(L10n.screenAnalyticsPromptReadTerms(linkPlaceholder))
|
||||
readTerms.replace(linkPlaceholder,
|
||||
with: L10n.screenAnalyticsPromptReadTermsContentLink,
|
||||
asLinkTo: termsURL)
|
||||
var readTerms = AttributedString(L10n.screenAnalyticsSettingsReadTerms(linkPlaceholder))
|
||||
var linkString = AttributedString(L10n.screenAnalyticsSettingsReadTermsContentLink)
|
||||
linkString.link = termsURL
|
||||
linkString.bold()
|
||||
readTerms.replace(linkPlaceholder, with: linkString)
|
||||
|
||||
optInContent = content + "\n\n" + readTerms
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ struct AnalyticsPromptScreen: View {
|
||||
.font(.compound.bodyLG)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
.tint(.compound.textLinkExternal)
|
||||
|
||||
Divider()
|
||||
.overlay { Color.compound._borderRowSeparator }
|
||||
|
||||
@@ -92,14 +92,6 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
||||
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
|
||||
}
|
||||
|
||||
private func indicateSuccess() {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonSuccess))
|
||||
}
|
||||
|
||||
private func indicateFailure() {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonError))
|
||||
}
|
||||
|
||||
/// Processes an error to either update the flow or display it to the user.
|
||||
private func handleError(_ error: AuthenticationServiceError) {
|
||||
MXLog.info("Error occurred: \(error)")
|
||||
@@ -163,7 +155,6 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
||||
/// Updates the view model with a different homeserver.
|
||||
private func updateViewModel() {
|
||||
viewModel.update(homeserver: authenticationService.homeserver.value)
|
||||
indicateSuccess()
|
||||
}
|
||||
|
||||
/// Shows the forgot password screen.
|
||||
|
||||
@@ -88,10 +88,9 @@ final class BugReportScreenCoordinator: CoordinatorProtocol {
|
||||
private func startLoading(label: String = L10n.commonLoading, progressPublisher: ProgressPublisher) {
|
||||
parameters.userIndicatorController?.submitIndicator(
|
||||
UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
type: .modal(progress: .published(progressPublisher), interactiveDismissDisabled: false),
|
||||
title: label,
|
||||
persistent: true,
|
||||
loaderType: .progress(progressPublisher))
|
||||
persistent: true)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
|
||||
|
||||
private func showLoadingIndicator() {
|
||||
userIndicatorController?.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal(interactiveDismissDisabled: true),
|
||||
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true),
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
}
|
||||
|
||||
@@ -288,10 +288,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
state.bindings.alertInfo = AlertInfo(id: UUID(), title: L10n.errorUnknown)
|
||||
case .some(.success):
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: UUID().uuidString,
|
||||
type: .modal,
|
||||
type: .modal(progress: .none, interactiveDismissDisabled: false),
|
||||
title: L10n.commonCurrentUserLeftRoom,
|
||||
iconName: "checkmark",
|
||||
loaderType: .none))
|
||||
iconName: "checkmark"))
|
||||
callback?(.roomLeft(roomIdentifier: roomId))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ struct HomeScreen: View {
|
||||
Label(L10n.actionInvite, systemImage: "square.and.arrow.up")
|
||||
}
|
||||
Button(action: feedback) {
|
||||
Label(L10n.commonReportABug, systemImage: "questionmark.circle")
|
||||
Label(L10n.commonReportABug, systemImage: "ladybug")
|
||||
}
|
||||
}
|
||||
Section {
|
||||
|
||||
@@ -28,7 +28,7 @@ struct HomeScreenInvitesButton: View {
|
||||
HStack(spacing: 8) {
|
||||
Text(title)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
.font(.compound.bodyMD)
|
||||
.font(.compound.bodyMDSemibold)
|
||||
|
||||
if hasBadge {
|
||||
badge
|
||||
|
||||
@@ -92,7 +92,7 @@ struct HomeScreenRoomCell: View {
|
||||
|
||||
if let timestamp = room.timestamp {
|
||||
Text(timestamp)
|
||||
.font(.compound.bodySM)
|
||||
.font(room.hasUnreads ? .compound.bodySMSemibold : .compound.bodySM)
|
||||
.foregroundColor(room.hasUnreads ? .compound.textActionAccent : .compound.textSecondary)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
|
||||
userIndicatorController?.retractIndicatorWithId(userIndicatorID)
|
||||
}
|
||||
userIndicatorController?.submitIndicator(UserIndicator(id: userIndicatorID,
|
||||
type: .modal(interactiveDismissDisabled: true),
|
||||
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true),
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
|
||||
@@ -102,7 +102,7 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
|
||||
userIndicatorController?.retractIndicatorWithId(userIndicatorID)
|
||||
}
|
||||
userIndicatorController?.submitIndicator(UserIndicator(id: userIndicatorID,
|
||||
type: .modal(interactiveDismissDisabled: true),
|
||||
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true),
|
||||
title: L10n.screenRoomDetailsUpdatingRoom,
|
||||
persistent: true))
|
||||
|
||||
|
||||
@@ -519,7 +519,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
|
||||
private func showLoadingIndicator(with delay: Duration) -> Task<Void, Never> {
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal(interactiveDismissDisabled: true),
|
||||
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true),
|
||||
title: L10n.commonLoading,
|
||||
persistent: true),
|
||||
delay: delay)
|
||||
|
||||
@@ -133,7 +133,7 @@ private struct MessageComposerReplyHeader: View {
|
||||
.overlay(alignment: .topTrailing) {
|
||||
Button(action: action) {
|
||||
Image(systemName: "xmark")
|
||||
.font(.caption2.weight(.medium))
|
||||
.font(.compound.bodySM.weight(.medium))
|
||||
.foregroundColor(.compound.iconTertiary)
|
||||
.padding(16.0)
|
||||
}
|
||||
@@ -151,9 +151,9 @@ private struct MessageComposerEditHeader: View {
|
||||
Spacer()
|
||||
Button(action: action) {
|
||||
Image(systemName: "xmark")
|
||||
.font(.caption2.weight(.medium))
|
||||
.font(.compound.bodySM.weight(.medium))
|
||||
.foregroundColor(.compound.iconTertiary)
|
||||
.padding(12.0)
|
||||
.padding(EdgeInsets(top: 10, leading: 12, bottom: 12, trailing: 14))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,6 +220,17 @@ struct MessageComposer_Previews: PreviewProvider {
|
||||
pasteAction: { _ in },
|
||||
replyCancellationAction: { },
|
||||
editCancellationAction: { })
|
||||
|
||||
MessageComposer(text: .constant(""),
|
||||
focused: .constant(false),
|
||||
sendingDisabled: false,
|
||||
mode: .reply(itemID: UUID().uuidString,
|
||||
replyDetails: .loaded(sender: .init(id: "Kirk"),
|
||||
contentType: .text(.init(body: "Text: Where the wild things are")))),
|
||||
sendAction: { },
|
||||
pasteAction: { _ in },
|
||||
replyCancellationAction: { },
|
||||
editCancellationAction: { })
|
||||
}
|
||||
.padding(.horizontal)
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ struct TimelineReplyView: View {
|
||||
Spacer().frame(width: 4.0)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(sender.displayName ?? sender.id)
|
||||
.font(.compound.bodySMSemibold)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
|
||||
@@ -54,6 +54,7 @@ struct RoomAttachmentPicker: View {
|
||||
PickerLabel(title: L10n.screenRoomAttachmentSourceCamera, systemImageName: "camera.fill")
|
||||
}
|
||||
}
|
||||
.padding(.top, 20)
|
||||
.background {
|
||||
// This is done in the background otherwise GeometryReader tends to expand to
|
||||
// all the space given to it like color or shape.
|
||||
@@ -79,7 +80,16 @@ struct RoomAttachmentPicker: View {
|
||||
.labelStyle(FixedIconSizeLabelStyle())
|
||||
.multilineTextAlignment(.leading)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding()
|
||||
.padding(16)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RoomAttachmentPicker_Previews: PreviewProvider {
|
||||
static let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomProxy: RoomProxyMock(with: .init(displayName: "")))
|
||||
static var previews: some View {
|
||||
RoomAttachmentPicker(context: viewModel.context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,17 +21,22 @@ struct RoomScreen: View {
|
||||
@State private var showReactionsMenuForItemId = ""
|
||||
@State private var dragOver = false
|
||||
|
||||
private let attachmentButtonPadding = 10.0
|
||||
|
||||
var body: some View {
|
||||
timeline
|
||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea()) // Kills the toolbar translucency.
|
||||
.safeAreaInset(edge: .bottom, spacing: 0) {
|
||||
HStack(spacing: 4.0) {
|
||||
HStack(alignment: .bottom, spacing: attachmentButtonPadding) {
|
||||
RoomAttachmentPicker(context: context)
|
||||
.padding(.bottom, 5) // centre align with the send button
|
||||
messageComposer
|
||||
.environmentObject(context)
|
||||
}
|
||||
.padding([.horizontal, .bottom])
|
||||
.padding(.leading, attachmentButtonPadding)
|
||||
.padding(.trailing, 12)
|
||||
.padding(.top, 8)
|
||||
.padding(.bottom)
|
||||
}
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { toolbar }
|
||||
|
||||
@@ -22,7 +22,7 @@ struct SeparatorRoomTimelineView: View {
|
||||
var body: some View {
|
||||
Text(timelineItem.text)
|
||||
.font(.compound.bodySMSemibold)
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.horizontal, 36.0)
|
||||
.padding(.vertical, 8.0)
|
||||
|
||||
@@ -187,7 +187,7 @@ public struct TimelineItemMenu: View {
|
||||
}
|
||||
case .copyPermalink:
|
||||
Button { send(action) } label: {
|
||||
MenuLabel(title: L10n.commonPermalink, systemImageName: "link")
|
||||
MenuLabel(title: L10n.actionCopyLinkToMessage, systemImageName: "link")
|
||||
}
|
||||
case .reply:
|
||||
Button { send(action) } label: {
|
||||
|
||||
+6
-3
@@ -35,12 +35,15 @@ struct AnalyticsSettingsScreenStrings {
|
||||
|
||||
init(termsURL: URL) {
|
||||
let content = AttributedString(L10n.screenAnalyticsSettingsHelpUsImprove(InfoPlistReader.main.bundleDisplayName))
|
||||
|
||||
// Create the 'read terms' with a placeholder.
|
||||
let linkPlaceholder = "{link}"
|
||||
var readTerms = AttributedString(L10n.screenAnalyticsSettingsReadTerms(linkPlaceholder))
|
||||
readTerms.replace(linkPlaceholder,
|
||||
with: L10n.screenAnalyticsSettingsReadTermsContentLink,
|
||||
asLinkTo: termsURL)
|
||||
var linkString = AttributedString(L10n.screenAnalyticsSettingsReadTermsContentLink)
|
||||
linkString.link = termsURL
|
||||
linkString.bold()
|
||||
readTerms.replace(linkPlaceholder, with: linkString)
|
||||
|
||||
sectionFooter = content + "\n\n" + readTerms
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -40,7 +40,6 @@ struct AnalyticsSettingsScreen: View {
|
||||
} footer: {
|
||||
Text(context.viewState.strings.sectionFooter)
|
||||
.compoundFormSectionFooter()
|
||||
.tint(.compound.textLinkExternal)
|
||||
}
|
||||
.compoundFormSection()
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ struct SettingsScreen: View {
|
||||
|
||||
// Report Bug
|
||||
Button { context.send(viewAction: .reportBug) } label: {
|
||||
Label(L10n.actionReportBug, systemImage: "ladybug")
|
||||
Label(L10n.commonReportABug, systemImage: "ladybug")
|
||||
}
|
||||
.buttonStyle(.compoundForm(accessory: .navigationLink))
|
||||
.accessibilityIdentifier("reportBugButton")
|
||||
|
||||
@@ -153,7 +153,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
||||
|
||||
private func showLoadingIndicator() {
|
||||
userIndicatorController?.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal(interactiveDismissDisabled: true),
|
||||
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true),
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user