Files
letro-ios/ElementX/Sources/Screens/Timeline/View/ItemMenu/TimelineItemMacContextMenu.swift
manuroe c29f4cc9b4 Dual licensing: AGPL + Element Commercial (#3657)
* New LICENSE-COMMERCIAL file

* Apply dual licenses: AGPL + Element Commercial to file headers

* Update README with dual licensing
2025-01-06 11:27:37 +01:00

84 lines
3.0 KiB
Swift

//
// Copyright 2023, 2024 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SFSafeSymbols
import SwiftUI
/// The contents of the context menu shown when right clicking an item in the timeline on a Mac
struct TimelineItemMacContextMenu: View {
let item: RoomTimelineItemProtocol
let actionProvider: TimelineItemMenuActionProvider
let send: (TimelineItemMenuAction) -> Void
var body: some View {
if ProcessInfo.processInfo.isiOSAppOnMac {
if let menuActions = actionProvider.makeActions() {
Section {
if !menuActions.reactions.isEmpty {
if #available(iOS 17.0, *) {
let reactions = (item as? EventBasedTimelineItemProtocol)?.properties.reactions ?? []
ControlGroup {
ForEach(menuActions.reactions, id: \.key) {
ReactionToggle(reaction: $0, reactions: reactions) {
send(.toggleReaction(key: $0))
}
}
Button { send(.react) } label: {
CompoundIcon(\.reactionAdd)
}
}
.controlGroupStyle(.palette)
} else {
Button { send(.react) } label: {
TimelineItemMenuAction.react.label
}
}
}
ForEach(menuActions.actions) { action in
Button(role: action.isDestructive ? .destructive : nil) {
send(action)
} label: {
action.label
}
}
}
Section {
ForEach(menuActions.secondaryActions) { action in
Button(role: action.isDestructive ? .destructive : nil) {
send(action)
} label: {
action.label
}
}
}
}
}
}
}
/// A button that acts as a toggle for reacting to a message.
private struct ReactionToggle: View {
let reaction: TimelineItemMenuReaction
let reactions: [AggregatedReaction]
let action: (String) -> Void
var isOn: Bool {
reactions.contains { $0.key == reaction.key && $0.isHighlighted }
}
var body: some View {
Button { action(reaction.key) } label: {
Image(systemSymbol: reaction.symbol)
.symbolVariant(isOn ? .fill : .none)
}
}
}