mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 10:33:45 +00:00
Timeline Reactions: Emoji picker (#350)
* Screens template * Loading and parsing * Gridview * New json * Search method * Unit tests * Added emoji provider state * Removed containsIgnoringCase * Added plus icon, added double tap gesture, dismiss sheet after selecting emoji * Renamed EmojisProvider to EmojiProvider * Renamed EmojiPickerScreenScreen * Extra padding * Renamed EmojisLoaderProtocol * Category names * Moved method into public section of the class * Return all categories when search string is empty * Added cancel button and tittle * Removed empty lines * Removed swiftlint warning
This commit is contained in:
committed by
GitHub
parent
dcedb3fb98
commit
7f91852291
@@ -19,6 +19,7 @@ import SwiftUI
|
||||
struct RoomScreen: View {
|
||||
@ObservedObject private var settings = ElementSettings.shared
|
||||
@ObservedObject var context: RoomScreenViewModel.Context
|
||||
@State private var showReactionsMenuForItemId = ""
|
||||
|
||||
var body: some View {
|
||||
timeline
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Copyright 2022 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
|
||||
|
||||
struct TimelineItemReactionsMenuView: View {
|
||||
private let emojis = ["👍🏼", "👎🏼", "😄", "🙏🏼", "😇"]
|
||||
|
||||
var onDisplayEmojiPicker: (() -> Void)?
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
HStack(spacing: 10) {
|
||||
ForEach(emojis, id: \.self) { emoji in
|
||||
Text(emoji)
|
||||
}
|
||||
}
|
||||
.padding(10)
|
||||
.background(.gray)
|
||||
.cornerRadius(15)
|
||||
HStack(spacing: 10) {
|
||||
Text("➕")
|
||||
}
|
||||
.padding(10)
|
||||
.background(.gray)
|
||||
.cornerRadius(15)
|
||||
.onTapGesture {
|
||||
onDisplayEmojiPicker?()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TimelineItemReactionsMenuView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
TimelineItemReactionsMenuView(onDisplayEmojiPicker: nil)
|
||||
}
|
||||
}
|
||||
@@ -102,6 +102,12 @@ struct TimelineTableView: UIViewRepresentable {
|
||||
}
|
||||
}
|
||||
|
||||
var displayReactionsMenuForItemId = "" {
|
||||
didSet {
|
||||
tableView?.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
/// The table's diffable data source.
|
||||
private var dataSource: UITableViewDiffableDataSource<TimelineSection, RoomTimelineViewProvider>?
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
@@ -175,25 +181,35 @@ struct TimelineTableView: UIViewRepresentable {
|
||||
|
||||
cell.item = timelineItem
|
||||
cell.contentConfiguration = UIHostingConfiguration {
|
||||
timelineItem
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.opacity(viewModelContext.viewState.opacity(for: timelineItem))
|
||||
.contextMenu {
|
||||
viewModelContext.viewState.contextMenuBuilder?(timelineItem.id)
|
||||
}
|
||||
.onAppear {
|
||||
viewModelContext.send(viewAction: .itemAppeared(id: timelineItem.id))
|
||||
}
|
||||
.onDisappear {
|
||||
viewModelContext.send(viewAction: .itemDisappeared(id: timelineItem.id))
|
||||
}
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
viewModelContext.send(viewAction: .linkClicked(url: url))
|
||||
return .systemAction
|
||||
})
|
||||
.onTapGesture {
|
||||
viewModelContext.send(viewAction: .itemTapped(id: timelineItem.id))
|
||||
VStack {
|
||||
if viewModelContext.viewState.displayReactionsMenuForItemId == timelineItem.id {
|
||||
TimelineItemReactionsMenuView {
|
||||
viewModelContext.send(viewAction: .displayEmojiPicker(itemId: timelineItem.id))
|
||||
}
|
||||
}
|
||||
timelineItem
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.opacity(viewModelContext.viewState.opacity(for: timelineItem))
|
||||
.contextMenu {
|
||||
viewModelContext.viewState.contextMenuBuilder?(timelineItem.id)
|
||||
}
|
||||
.onAppear {
|
||||
viewModelContext.send(viewAction: .itemAppeared(id: timelineItem.id))
|
||||
}
|
||||
.onDisappear {
|
||||
viewModelContext.send(viewAction: .itemDisappeared(id: timelineItem.id))
|
||||
}
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
viewModelContext.send(viewAction: .linkClicked(url: url))
|
||||
return .systemAction
|
||||
})
|
||||
.onTapGesture(count: 2) {
|
||||
viewModelContext.send(viewAction: .displayReactionsMenuForItemId(itemId: timelineItem.id))
|
||||
}
|
||||
.onTapGesture {
|
||||
viewModelContext.send(viewAction: .itemTapped(id: timelineItem.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
.margins(.all, self.timelineStyle.rowInsets)
|
||||
.minSize(height: 1)
|
||||
@@ -240,6 +256,9 @@ struct TimelineTableView: UIViewRepresentable {
|
||||
if composerMode != viewModelContext.viewState.composerMode {
|
||||
composerMode = viewModelContext.viewState.composerMode
|
||||
}
|
||||
if displayReactionsMenuForItemId != viewModelContext.viewState.displayReactionsMenuForItemId {
|
||||
displayReactionsMenuForItemId = viewModelContext.viewState.displayReactionsMenuForItemId
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the table view with the latest items from the ``timelineItems`` array. After
|
||||
|
||||
Reference in New Issue
Block a user