mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-19 16:13:42 +02:00
Reactions: Add primary reactions as message actions
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2019 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 Foundation
|
||||
|
||||
/// TemplateScreenViewController view actions exposed to view model
|
||||
enum ReactionsMenuAction {
|
||||
case react(String)
|
||||
case unreact(String)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright 2019 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 Foundation
|
||||
|
||||
enum ReactionsMenuReactions: String {
|
||||
case agree = "👍"
|
||||
case disagree = "👎"
|
||||
case like = "🙂"
|
||||
case dislike = "😔"
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright 2019 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 UIKit
|
||||
import Reusable
|
||||
|
||||
final class ReactionsMenuView: UIView, NibOwnerLoadable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Outlets
|
||||
|
||||
// MARK: Private
|
||||
|
||||
//private var strengthViews: [UIView] = []
|
||||
|
||||
// MARK: Public
|
||||
|
||||
var viewModel: ReactionsMenuViewModelType? {
|
||||
didSet {
|
||||
self.updateView()
|
||||
self.viewModel?.viewDelegate = self
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
self.loadNibContent()
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
self.loadNibContent()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func updateView() {
|
||||
guard let viewModel = self.viewModel else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ReactionsMenuView: ReactionsMenuViewModelDelegate {
|
||||
func reactionsMenuViewModelDidUpdate(_ viewModel: ReactionsMenuViewModelType) {
|
||||
self.updateView()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ReactionsMenuView" customModule="Riot" customModuleProvider="target"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="100"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="30O-28-rwy">
|
||||
<rect key="frame" x="104" y="13" width="100" height="38"/>
|
||||
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="38" id="TII-Yn-bza"/>
|
||||
<constraint firstAttribute="width" constant="100" id="cjU-F5-DjB"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<state key="normal" title="Agree 👍">
|
||||
<color key="titleColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
</state>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ebe-PT-0R2">
|
||||
<rect key="frame" x="104" y="59" width="100" height="38"/>
|
||||
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="807-lM-sNX"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="bIY-hX-5PC"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="j4m-Qi-NS5"/>
|
||||
<constraint firstAttribute="height" constant="38" id="tNZ-Kv-LxS"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<state key="normal" title="Disagree 👎">
|
||||
<color key="titleColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
</state>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kao-MQ-QFq">
|
||||
<rect key="frame" x="210" y="13" width="100" height="38"/>
|
||||
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="8hf-4f-egV"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="Gvk-Ap-Wtc"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="lZK-go-x5A"/>
|
||||
<constraint firstAttribute="height" constant="38" id="o0a-8j-0et"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<state key="normal" title="Like 🙂">
|
||||
<color key="titleColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
</state>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AgH-2U-HpP">
|
||||
<rect key="frame" x="210" y="59" width="100" height="38"/>
|
||||
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="100" id="75c-dq-L2I"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="GgC-VF-je2"/>
|
||||
<constraint firstAttribute="width" constant="100" id="RCe-5D-dg5"/>
|
||||
<constraint firstAttribute="height" constant="38" id="cvn-yC-3VY"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="hVj-hk-Vob"/>
|
||||
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="38" id="wNs-Eg-frx"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<state key="normal" title="Dislike 😔">
|
||||
<color key="titleColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
</state>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="Ebe-PT-0R2" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="centerX" constant="-3" id="3kX-GA-4mf"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="centerX" secondItem="kao-MQ-QFq" secondAttribute="leading" constant="-3" id="FV3-zi-y6i"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="centerY" secondItem="Ebe-PT-0R2" secondAttribute="top" constant="-4" id="Hfb-BB-kgH"/>
|
||||
<constraint firstItem="AgH-2U-HpP" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="centerX" constant="3" id="LBW-Lg-fZv"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="centerY" secondItem="AgH-2U-HpP" secondAttribute="top" constant="-4" id="MAE-KT-eAQ"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="centerY" secondItem="30O-28-rwy" secondAttribute="bottom" constant="4" id="jTW-iy-hDv"/>
|
||||
<constraint firstItem="vUN-kp-3ea" firstAttribute="centerY" secondItem="kao-MQ-QFq" secondAttribute="bottom" constant="4" id="sRb-2V-clB"/>
|
||||
<constraint firstItem="30O-28-rwy" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="centerX" constant="-3" id="xUt-vJ-1I1" userLabel="Agree 👍.trailing = Safe Area.centerX + 7"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
|
||||
<point key="canvasLocation" x="128.98550724637681" y="35.491071428571423"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright 2019 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 UIKit
|
||||
|
||||
final class ReactionsMenuViewModel: ReactionsMenuViewModelType {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
private let aggregations: MXAggregations
|
||||
private let roomId: String
|
||||
private let eventId: String
|
||||
|
||||
// MARK: Public
|
||||
|
||||
var isAgreeButtonSelected: Bool = false
|
||||
var isDisagreeButtonSelected: Bool = false
|
||||
var isLikeButtonSelected: Bool = false
|
||||
var isDislikeButtonSelected: Bool = false
|
||||
|
||||
weak var viewDelegate: ReactionsMenuViewModelDelegate?
|
||||
weak var coordinatorDelegate: ReactionsMenuViewModelCoordinatorDelegate?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(aggregations: MXAggregations, roomId: String, eventId: String) {
|
||||
|
||||
self.aggregations = aggregations
|
||||
self.roomId = roomId
|
||||
self.eventId = eventId
|
||||
|
||||
self.loadData()
|
||||
self.listenToDataUpdate()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
|
||||
private func resetData() {
|
||||
self.isAgreeButtonSelected = false
|
||||
self.isDisagreeButtonSelected = false
|
||||
self.isLikeButtonSelected = false
|
||||
self.isDislikeButtonSelected = false
|
||||
}
|
||||
|
||||
private func loadData() {
|
||||
guard let reactionCounts = self.aggregations.reactions(onEvent: self.eventId, inRoom: self.roomId) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.resetData()
|
||||
reactionCounts.forEach { (reaction) in
|
||||
if let reaction = ReactionsMenuReactions(rawValue: reaction.reaction) {
|
||||
switch reaction {
|
||||
case .agree:
|
||||
self.isAgreeButtonSelected = true
|
||||
case .disagree:
|
||||
self.isDisagreeButtonSelected = true
|
||||
case .like:
|
||||
self.isLikeButtonSelected = true
|
||||
case .dislike:
|
||||
self.isDislikeButtonSelected = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let viewDelegate = self.viewDelegate {
|
||||
viewDelegate.reactionsMenuViewModelDidUpdate(self)
|
||||
}
|
||||
}
|
||||
|
||||
private func listenToDataUpdate() {
|
||||
self.aggregations.listenToReactionCountUpdate(inRoom: self.roomId) { [weak self] (changes) in
|
||||
|
||||
guard let sself = self else {
|
||||
return
|
||||
}
|
||||
|
||||
if changes[sself.eventId] != nil {
|
||||
sself.loadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Copyright 2019 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 Foundation
|
||||
|
||||
protocol ReactionsMenuViewModelDelegate: class {
|
||||
func reactionsMenuViewModelDidUpdate(_ viewModel: ReactionsMenuViewModelType)
|
||||
}
|
||||
|
||||
protocol ReactionsMenuViewModelCoordinatorDelegate: class {
|
||||
func reactionsMenuViewModel(_ viewModel: ReactionsMenuViewModelType, doAction action: ReactionsMenuAction)
|
||||
}
|
||||
|
||||
|
||||
protocol ReactionsMenuViewModelType {
|
||||
|
||||
var isAgreeButtonSelected: Bool { get }
|
||||
var isDisagreeButtonSelected: Bool { get }
|
||||
var isLikeButtonSelected: Bool { get }
|
||||
var isDislikeButtonSelected: Bool { get }
|
||||
|
||||
|
||||
var viewDelegate: ReactionsMenuViewModelDelegate? { get set }
|
||||
var coordinatorDelegate: ReactionsMenuViewModelCoordinatorDelegate? { get set }
|
||||
}
|
||||
Reference in New Issue
Block a user