mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Show both defaults and frequent emojis in the timeline item menu, make the list scrollable (#3534)
This commit is contained in:
parent
bce3b3a385
commit
51227fffe3
@ -47,7 +47,6 @@ final class AppSettings {
|
|||||||
case fuzzyRoomListSearchEnabled
|
case fuzzyRoomListSearchEnabled
|
||||||
case enableOnlySignedDeviceIsolationMode
|
case enableOnlySignedDeviceIsolationMode
|
||||||
case knockingEnabled
|
case knockingEnabled
|
||||||
case frequentEmojisEnabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
||||||
@ -281,9 +280,6 @@ final class AppSettings {
|
|||||||
@UserPreference(key: UserDefaultsKeys.knockingEnabled, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.knockingEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
var knockingEnabled
|
var knockingEnabled
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.frequentEmojisEnabled, defaultValue: isDevelopmentBuild, storageType: .userDefaults(store))
|
|
||||||
var frequentEmojisEnabled
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MARK: - Shared
|
// MARK: - Shared
|
||||||
|
@ -50,7 +50,6 @@ protocol DeveloperOptionsProtocol: AnyObject {
|
|||||||
var enableOnlySignedDeviceIsolationMode: Bool { get set }
|
var enableOnlySignedDeviceIsolationMode: Bool { get set }
|
||||||
var elementCallBaseURLOverride: URL? { get set }
|
var elementCallBaseURLOverride: URL? { get set }
|
||||||
var knockingEnabled: Bool { get set }
|
var knockingEnabled: Bool { get set }
|
||||||
var frequentEmojisEnabled: Bool { get set }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppSettings: DeveloperOptionsProtocol { }
|
extension AppSettings: DeveloperOptionsProtocol { }
|
||||||
|
@ -53,10 +53,6 @@ struct DeveloperOptionsScreen: View {
|
|||||||
Toggle(isOn: $context.hideTimelineMedia) {
|
Toggle(isOn: $context.hideTimelineMedia) {
|
||||||
Text("Hide image & video previews")
|
Text("Hide image & video previews")
|
||||||
}
|
}
|
||||||
|
|
||||||
Toggle(isOn: $context.frequentEmojisEnabled) {
|
|
||||||
Text("Show frequently used emojis")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Section("Join rules") {
|
Section("Join rules") {
|
||||||
|
@ -11,6 +11,7 @@ import SwiftUI
|
|||||||
struct TimelineItemMenu: View {
|
struct TimelineItemMenu: View {
|
||||||
@EnvironmentObject private var context: TimelineViewModel.Context
|
@EnvironmentObject private var context: TimelineViewModel.Context
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||||
|
|
||||||
@State private var reactionsFrame = CGRect.zero
|
@State private var reactionsFrame = CGRect.zero
|
||||||
|
|
||||||
@ -109,31 +110,43 @@ struct TimelineItemMenu: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var reactionsSection: some View {
|
private var reactionsSection: some View {
|
||||||
ScrollView(.horizontal) {
|
HStack(spacing: 8) {
|
||||||
HStack(alignment: .center, spacing: 8) {
|
ScrollView(.horizontal) {
|
||||||
ForEach(actions.reactions, id: \.key) {
|
HStack(alignment: .center, spacing: 8) {
|
||||||
reactionButton(for: $0.key)
|
ForEach(actions.reactions, id: \.key) {
|
||||||
}
|
reactionButton(for: $0.key)
|
||||||
|
|
||||||
Button {
|
|
||||||
dismiss()
|
|
||||||
// Otherwise we get errors that a sheet is already presented
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
||||||
context.send(viewAction: .displayEmojiPicker(itemID: item.id))
|
|
||||||
}
|
}
|
||||||
} label: {
|
|
||||||
CompoundIcon(\.reactionAdd, size: .medium, relativeTo: .compound.headingLG)
|
|
||||||
.foregroundColor(.compound.iconSecondary)
|
|
||||||
.padding(10)
|
|
||||||
}
|
}
|
||||||
.accessibilityLabel(L10n.actionReact)
|
.padding(.horizontal)
|
||||||
|
.frame(minWidth: reactionsFrame.width, maxWidth: .infinity, alignment: .center)
|
||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.scrollIndicators(.hidden)
|
||||||
.frame(minWidth: reactionsFrame.width, maxWidth: .infinity, alignment: .center)
|
.scrollBounceBehavior(.basedOnSize, axes: .horizontal)
|
||||||
|
.readFrame($reactionsFrame)
|
||||||
|
.overlay {
|
||||||
|
if horizontalSizeClass == .compact {
|
||||||
|
LinearGradient(stops: [.init(color: .clear, location: 0.0),
|
||||||
|
.init(color: .clear, location: 0.9),
|
||||||
|
.init(color: .compound.bgCanvasDefault, location: 1.0)],
|
||||||
|
startPoint: .leading,
|
||||||
|
endPoint: .trailing)
|
||||||
|
.allowsHitTesting(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
dismiss()
|
||||||
|
// Otherwise we get errors that a sheet is already presented
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||||
|
context.send(viewAction: .displayEmojiPicker(itemID: item.id))
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
CompoundIcon(\.reactionAdd, size: .medium, relativeTo: .compound.headingLG)
|
||||||
|
.foregroundColor(.compound.iconSecondary)
|
||||||
|
.padding(10)
|
||||||
|
}
|
||||||
|
.accessibilityLabel(L10n.actionReact)
|
||||||
}
|
}
|
||||||
.scrollIndicators(.hidden)
|
|
||||||
.scrollBounceBehavior(.basedOnSize, axes: .horizontal)
|
|
||||||
.readFrame($reactionsFrame)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func reactionButton(for emoji: String) -> some View {
|
private func reactionButton(for emoji: String) -> some View {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
// Please see LICENSE in the repository root for full details.
|
// Please see LICENSE in the repository root for full details.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import OrderedCollections
|
||||||
import SFSafeSymbols
|
import SFSafeSymbols
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@ -25,30 +26,32 @@ struct TimelineItemMenuActions {
|
|||||||
self.actions = actions
|
self.actions = actions
|
||||||
self.debugActions = debugActions
|
self.debugActions = debugActions
|
||||||
|
|
||||||
// Only process 5 of the most frequently used emojis instead of all of them
|
var frequentlyUsed: OrderedSet<TimelineItemMenuReaction> = [
|
||||||
var frequentlyUsed = emojiProvider.frequentlyUsedSystemEmojis().prefix(5).map { TimelineItemMenuReaction(key: $0, symbol: .heart) }
|
|
||||||
|
|
||||||
frequentlyUsed += [
|
|
||||||
.init(key: "👍️", symbol: .handThumbsup),
|
.init(key: "👍️", symbol: .handThumbsup),
|
||||||
.init(key: "👎️", symbol: .handThumbsdown),
|
.init(key: "👎️", symbol: .handThumbsdown),
|
||||||
.init(key: "🔥", symbol: .flame),
|
.init(key: "🎉", symbol: .partyPopper),
|
||||||
.init(key: "❤️", symbol: .heart),
|
.init(key: "❤️", symbol: .heart)
|
||||||
.init(key: "👏", symbol: .handsClap)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
frequentlyUsed = Array(frequentlyUsed.prefix(5))
|
frequentlyUsed.append(contentsOf: emojiProvider.frequentlyUsedSystemEmojis().map { TimelineItemMenuReaction(key: $0, symbol: .heart) })
|
||||||
|
|
||||||
reactions = if isReactable {
|
reactions = if isReactable {
|
||||||
frequentlyUsed
|
Array(frequentlyUsed.elements.prefix(10))
|
||||||
} else {
|
} else {
|
||||||
[]
|
[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TimelineItemMenuReaction {
|
struct TimelineItemMenuReaction: Hashable {
|
||||||
let key: String
|
let key: String
|
||||||
let symbol: SFSymbol
|
let symbol: SFSymbol
|
||||||
|
|
||||||
|
// Frequently used emojis on the all use the same .heart SFSymbol.
|
||||||
|
// Override equatable so we can remove duplicates.
|
||||||
|
static func == (lhs: TimelineItemMenuReaction, rhs: TimelineItemMenuReaction) -> Bool {
|
||||||
|
lhs.key == rhs.key
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TimelineItemMenuAction: Identifiable, Hashable {
|
enum TimelineItemMenuAction: Identifiable, Hashable {
|
||||||
|
@ -57,7 +57,7 @@ class EmojiProvider: EmojiProviderProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func frequentlyUsedSystemEmojis() -> [String] {
|
func frequentlyUsedSystemEmojis() -> [String] {
|
||||||
guard appSettings.frequentEmojisEnabled, !ProcessInfo.processInfo.isiOSAppOnMac else {
|
guard !ProcessInfo.processInfo.isiOSAppOnMac else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ class EmojiProvider: EmojiProviderProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func markEmojiAsFrequentlyUsed(_ emoji: String) {
|
func markEmojiAsFrequentlyUsed(_ emoji: String) {
|
||||||
guard appSettings.frequentEmojisEnabled else {
|
guard !ProcessInfo.processInfo.isiOSAppOnMac else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Authenticity.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Authenticity.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Button-shapes.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Button-shapes.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Identity-Changed.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Identity-Changed.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Normal.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Normal.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unencrypted.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unencrypted.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unknown-failure.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unknown-failure.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned-Devices.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned-Devices.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-en-GB.Unsigned.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Authenticity.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Authenticity.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Button-shapes.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Button-shapes.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Identity-Changed.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Identity-Changed.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Normal.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Normal.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unencrypted.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unencrypted.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unknown-failure.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unknown-failure.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned-Devices.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned-Devices.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPad-pseudo.Unsigned.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Authenticity.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Authenticity.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Button-shapes.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Button-shapes.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Normal.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Normal.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unencrypted.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unencrypted.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-en-GB.Unsigned.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Authenticity.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Authenticity.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Button-shapes.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Button-shapes.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Normal.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Normal.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unencrypted.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unencrypted.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned.png
(Stored with Git LFS)
BIN
PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineItemMenu-iPhone-16-pseudo.Unsigned.png
(Stored with Git LFS)
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user