Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a feature flag for Message Pinning. #3063

Merged
merged 3 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ line_length:
error: 1000

file_length:
warning: 1000
error: 1000
warning: 2000

type_name:
min_length: 3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"action_view_source" = "View source";
"action_yes" = "Yes";
"action.load_more" = "Load more";
"action.pin" = "Pin";
"common_about" = "About";
"common_acceptable_use_policy" = "Acceptable use policy";
"common_advanced_settings" = "Advanced settings";
Expand Down Expand Up @@ -252,6 +253,10 @@
"error_no_compatible_app_found" = "No compatible app was found to handle this action.";
"error_some_messages_have_not_been_sent" = "Some messages have not been sent";
"error_unknown" = "Sorry, an error occurred";
"event_shield_reason_authenticity_not_guaranteed" = "The authenticity of this encrypted message can't be guaranteed on this device.";
"event_shield_reason_unknown_device" = "Encrypted by an unknown or deleted device.";
"event_shield_reason_unsigned_device" = "Encrypted by a device not verified by its owner.";
"event_shield_reason_unverified_identity" = "Encrypted by an unverified user.";
"full_screen_intent_banner_message" = "To ensure you never miss an important call, please change your settings to allow full-screen notifications when your phone is locked.";
"full_screen_intent_banner_title" = "Enhance your call experience";
"invite_friends_rich_title" = "🔐️ Join me on %1$@";
Expand Down
4 changes: 4 additions & 0 deletions ElementX/Sources/Application/AppSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ final class AppSettings {
case simplifiedSlidingSyncEnabled
case publicSearchEnabled
case fuzzyRoomListSearchEnabled
case pinningEnabled
}

private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
Expand Down Expand Up @@ -281,6 +282,9 @@ final class AppSettings {

@UserPreference(key: UserDefaultsKeys.fuzzyRoomListSearchEnabled, defaultValue: false, storageType: .userDefaults(store))
var fuzzyRoomListSearchEnabled

@UserPreference(key: UserDefaultsKeys.pinningEnabled, defaultValue: false, storageType: .userDefaults(store))
var pinningEnabled

#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import SwiftState
import SwiftUI
import UserNotifications

// swiftlint:disable file_length
enum RoomFlowCoordinatorAction: Equatable {
case presentCallScreen(roomProxy: RoomProxyProtocol)
case finished
Expand Down
10 changes: 10 additions & 0 deletions ElementX/Sources/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,14 @@ internal enum L10n {
internal static var errorSomeMessagesHaveNotBeenSent: String { return L10n.tr("Localizable", "error_some_messages_have_not_been_sent") }
/// Sorry, an error occurred
internal static var errorUnknown: String { return L10n.tr("Localizable", "error_unknown") }
/// The authenticity of this encrypted message can't be guaranteed on this device.
internal static var eventShieldReasonAuthenticityNotGuaranteed: String { return L10n.tr("Localizable", "event_shield_reason_authenticity_not_guaranteed") }
/// Encrypted by an unknown or deleted device.
internal static var eventShieldReasonUnknownDevice: String { return L10n.tr("Localizable", "event_shield_reason_unknown_device") }
/// Encrypted by a device not verified by its owner.
internal static var eventShieldReasonUnsignedDevice: String { return L10n.tr("Localizable", "event_shield_reason_unsigned_device") }
/// Encrypted by an unverified user.
internal static var eventShieldReasonUnverifiedIdentity: String { return L10n.tr("Localizable", "event_shield_reason_unverified_identity") }
/// To ensure you never miss an important call, please change your settings to allow full-screen notifications when your phone is locked.
internal static var fullScreenIntentBannerMessage: String { return L10n.tr("Localizable", "full_screen_intent_banner_message") }
/// Enhance your call experience
Expand Down Expand Up @@ -2221,6 +2229,8 @@ internal enum L10n {
internal enum Action {
/// Load more
internal static var loadMore: String { return L10n.tr("Localizable", "action.load_more") }
/// Pin
internal static var pin: String { return L10n.tr("Localizable", "action.pin") }
}

internal enum Common {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ class RoomScreenInteractionHandler {
Task { await roomProxy.timeline.toggleReaction(key, to: eventID) }
case .endPoll(let pollStartID):
endPoll(pollStartID: pollStartID)
case .pin:
// TODO: Implement the pin action
break
}

if action.switchToDefaultComposer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ struct RoomScreenViewState: BindableState {
var ownUserID: String
var canCurrentUserRedactOthers = false
var canCurrentUserRedactSelf = false
var canCurrentUserPin = false
var isViewSourceEnabled: Bool

var canJoinCall = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,13 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
} else {
state.canCurrentUserRedactSelf = false
}

if appSettings.pinningEnabled,
case let .success(value) = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomPinnedEvents) {
state.canCurrentUserPin = value
} else {
state.canCurrentUserPin = false
}
}

private func setupSubscriptions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ struct TimelineItemMenu_Previews: PreviewProvider, TestablePreview {
@ViewBuilder
static var testView: some View {
if let item = RoomTimelineItemFixtures.singleMessageChunk.first as? EventBasedTimelineItemProtocol,
let actions = TimelineItemMenuActions(isReactable: true, actions: [.copy, .edit, .reply(isThread: false), .redact], debugActions: [.viewSource]) {
let actions = TimelineItemMenuActions(isReactable: true, actions: [.copy, .edit, .reply(isThread: false), .pin, .redact], debugActions: [.viewSource]) {
TimelineItemMenu(item: item, actions: actions)
.environmentObject(viewModel.context)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
case react
case toggleReaction(key: String)
case endPoll(pollStartID: String)
case pin

var id: Self { self }

Expand Down Expand Up @@ -133,6 +134,8 @@ enum TimelineItemMenuAction: Identifiable, Hashable {
Label(L10n.actionReact, icon: \.reactionAdd)
case .endPoll:
Label(L10n.actionEndPoll, icon: \.pollsEnd)
case .pin:
Label(L10n.Action.pin, icon: \.pin)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct TimelineItemMenuActionProvider {
let timelineItem: RoomTimelineItemProtocol
let canCurrentUserRedactSelf: Bool
let canCurrentUserRedactOthers: Bool
let canCurrentUserPin: Bool
let isDM: Bool
let isViewSourceEnabled: Bool

Expand Down Expand Up @@ -64,6 +65,11 @@ struct TimelineItemMenuActionProvider {
if item.isForwardable {
actions.append(.forward(itemID: item.id))
}

if canCurrentUserPin {
// TODO: If the event is already pinned use the unpinned action
actions.append(.pin)
}

if item.isEditable {
actions.append(.edit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct RoomScreen: View {
let actions = TimelineItemMenuActionProvider(timelineItem: info.item,
canCurrentUserRedactSelf: context.viewState.canCurrentUserRedactSelf,
canCurrentUserRedactOthers: context.viewState.canCurrentUserRedactOthers,
canCurrentUserPin: context.viewState.canCurrentUserPin,
isDM: context.viewState.isEncryptedOneToOneRoom,
isViewSourceEnabled: context.viewState.isViewSourceEnabled).makeActions()
if let actions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
let provider = TimelineItemMenuActionProvider(timelineItem: timelineItem,
canCurrentUserRedactSelf: context.viewState.canCurrentUserRedactSelf,
canCurrentUserRedactOthers: context.viewState.canCurrentUserRedactOthers,
canCurrentUserPin: context.viewState.canCurrentUserPin,
isDM: context.viewState.isEncryptedOneToOneRoom,
isViewSourceEnabled: context.viewState.isViewSourceEnabled)
TimelineItemMacContextMenu(item: timelineItem, actionProvider: provider) { action in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ protocol DeveloperOptionsProtocol: AnyObject {
var hideUnreadMessagesBadge: Bool { get set }
var elementCallBaseURLOverride: URL? { get set }
var fuzzyRoomListSearchEnabled: Bool { get set }
var pinningEnabled: Bool { get set }
}

extension AppSettings: DeveloperOptionsProtocol { }
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ struct DeveloperOptionsScreen: View {
}
}

Section("Message Pinning") {
Toggle(isOn: $context.pinningEnabled) {
Text("Enable message pinning")
}
}

Section("Room List") {
Toggle(isOn: $context.hideUnreadMessagesBadge) {
Text("Hide grey dots")
Expand Down
1 change: 0 additions & 1 deletion ElementX/Sources/Services/Client/ClientProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import OrderedCollections

import MatrixRustSDK

// swiftlint:disable file_length
class ClientProxy: ClientProxyProtocol {
private let client: ClientProtocol
private let networkMonitor: NetworkMonitorProtocol
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading