Merge branch 'feature/5216_federation_us03' into 'develop'

MESSENGER-5216 Added federation indicator to room info screen

See merge request bwmessenger/bundesmessenger/bundesmessenger-ios!249
This commit is contained in:
Arnfried Griesert
2023-11-15 07:42:32 +00:00
13 changed files with 200 additions and 15 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "App=BUM, platform=iOS, Theme=dark, Outline=background, Language=german.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "App=BUM, platform=iOS, Theme=light, Outline=background, Language=german.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "App=BUM, platform=iOS, Theme=dark, Outline=background, Language=english.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "App=BUM, platform=iOS, Theme=light, Outline=background, Language=english.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -46,10 +46,23 @@ internal class Asset: NSObject {
internal static let authenticationTermsIcon = ImageAsset(name: "authentication_terms_icon")
internal static let binoculars = ImageAsset(name: "binoculars")
internal static let birthdayCake = ImageAsset(name: "birthday_cake")
internal static let buttonNewDark = ImageAsset(name: "button_new_dark")
internal static let buttonNewLight = ImageAsset(name: "button_new_light")
internal static let bwiSettingsFilled = ImageAsset(name: "bwi_settings_filled")
internal static let federationPillDeBumDark = ImageAsset(name: "federation_pill_de_bum_dark")
internal static let federationPillDeBumLight = ImageAsset(name: "federation_pill_de_bum_light")
internal static let federationPillEnBumDark = ImageAsset(name: "federation_pill_en_bum_dark")
internal static let federationPillEnBumLight = ImageAsset(name: "federation_pill_en_bum_light")
internal static let fileAttachmentIcon = ImageAsset(name: "file_attachment_icon")
internal static let fileScanInfected = ImageAsset(name: "file_scan_infected")
internal static let newFeatures = ImageAsset(name: "new_features")
internal static let qrcodeViewfinder = ImageAsset(name: "qrcode_viewfinder")
internal static let roomFederatedBumIconDark = ImageAsset(name: "room_federated_bum_icon_dark")
internal static let roomFederatedBumIconLight = ImageAsset(name: "room_federated_bum_icon_light")
internal static let roomFilterToggleDarkOff = ImageAsset(name: "room_filter_toggle_dark_off")
internal static let roomFilterToggleDarkOn = ImageAsset(name: "room_filter_toggle_dark_on")
internal static let roomFilterToggleLightOff = ImageAsset(name: "room_filter_toggle_light_off")
internal static let roomFilterToggleLightOn = ImageAsset(name: "room_filter_toggle_light_on")
internal static let welcomeExperience1 = ImageAsset(name: "welcome_experience_1")
internal static let welcomeExperience2 = ImageAsset(name: "welcome_experience_2")
internal static let welcomeExperience3 = ImageAsset(name: "welcome_experience_3")

View File

@@ -43,6 +43,9 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType {
}
let directUserPresence = session.user(withUserId: room.directUserId)?.presence ?? .unknown
// bwi: 5216 - federation
let isFederated = isFederationEnabled(room: room)
let basicInfoViewData = RoomInfoBasicViewData(avatarUrl: room.summary.avatar,
mediaManager: session.mediaManager,
roomId: room.roomId,
@@ -53,7 +56,8 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType {
isEncrypted: room.summary.isEncrypted,
isDirect: room.isDirect,
directUserId: room.directUserId,
directUserPresence: directUserPresence)
directUserPresence: directUserPresence,
isFederated: isFederated)
return RoomInfoListViewData(numberOfMembers: Int(room.summary.membersCount.joined),
isEncrypted: room.summary.isEncrypted,
@@ -61,6 +65,23 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType {
basicInfoViewData: basicInfoViewData)
}
// bwi: 5216 - federation
private func isFederationEnabled(room: MXRoom) -> Bool {
guard BWIBuildSettings.shared.isFederationEnabled else {
return false
}
if room.isPersonalNotesRoom() {
return false
} else {
if room.isDirect {
return room.isDMFederated()
} else {
return room.isRoomFederated()
}
}
}
// MARK: - Setup
init(session: MXSession, room: MXRoom) {

View File

@@ -63,6 +63,8 @@ class RoomInfoBasicView: UIView {
@IBOutlet private weak var securityTitleLabel: UILabel!
@IBOutlet private weak var securityInformationLabel: UILabel!
private var pillImageView: UIImageView?
/// Block to be invoked when topic text view changes its content size.
var onTopicSizeChange: ((RoomInfoBasicView) -> Void)?
@@ -96,7 +98,7 @@ class RoomInfoBasicView: UIView {
} else {
avatarImageView.image = avatarImage
}
if BWIBuildSettings.shared.bwiUseCustomPersonalNotesAvatar {
if let session = AppDelegate.theDelegate().mxSessions.first as? MXSession {
let service = PersonalNotesDefaultService(mxSession: session)
@@ -105,9 +107,38 @@ class RoomInfoBasicView: UIView {
}
}
}
// bwi: 5216 - federation
if BWIBuildSettings.shared.isFederationEnabled && viewData.isFederated {
// add imageview for the pill if it doesn't exist
if pillImageView == nil {
// because of svg we use fixed values here for the raw image size
let pillImageWidth: CGFloat = 23.0
let pillImageHeight: CGFloat = 18.0
let pillBorderSize: CGFloat = 3.0
// compensation for the bottom gap in the asset
let verticalShift: CGFloat = 2.5
badgeImageView.image = viewData.encryptionImage
roomNameLabel.text = viewData.roomDisplayName
let avatarSize = avatarImageView.frame.size.height
let pillHeight: CGFloat = avatarSize * 0.34 // 34% relative size by design rule
let pillWidth: CGFloat = pillHeight / pillImageHeight * pillImageWidth
let scaledBorderSize: CGFloat = pillBorderSize * pillHeight / pillImageHeight
let frame = CGRect(x: avatarImageView.frame.origin.x + avatarSize - pillWidth + scaledBorderSize, y: verticalShift + avatarImageView.frame.origin.y + avatarSize - pillHeight, width: pillWidth, height: pillHeight)
let imageView = UIImageView(frame: frame)
pillImageView = imageView
pillImageView?.contentMode = .scaleAspectFit
avatarContainerView.addSubview(imageView)
}
pillImageView?.image = federationBadgeImage()
roomNameLabel.numberOfLines = 2
roomNameLabel.attributedText = roomNameWithFederationPill(roomDisplayName: viewData.roomDisplayName, font: roomNameLabel.font)
} else {
roomNameLabel.text = viewData.roomDisplayName
}
badgeImageView.image = nil
roomAddressLabel.text = viewData.mainRoomAlias
roomAddressLabel.isHidden = roomAddressLabel.text?.isEmpty ?? true
roomTopicTextView.text = viewData.roomTopic
@@ -125,6 +156,46 @@ class RoomInfoBasicView: UIView {
updateBadgeImageViewPosition(isPresenceDisplayed: viewData.directUserPresence != .unknown)
}
// bwi: 5216 - federation
private func federationBadgeImage() -> UIImage {
if ThemeService.shared().isCurrentThemeDark() {
return Asset.Images.roomFederatedBumIconDark.image
} else {
return Asset.Images.roomFederatedBumIconLight.image
}
}
// bwi: 5216 - federation
private func roomNameWithFederationPill(roomDisplayName: String?, font: UIFont) -> NSAttributedString? {
guard let roomDisplayName = roomDisplayName else {
return nil
}
let attributedString = NSMutableAttributedString(string: roomDisplayName + " ")
// get the correct asset for the current theme and language
let image: UIImage
if Locale.current.languageCode == "de" {
image = ThemeService.shared().isCurrentThemeDark() ? Asset.Images.federationPillDeBumDark.image : Asset.Images.federationPillDeBumLight.image
} else {
image = ThemeService.shared().isCurrentThemeDark() ? Asset.Images.federationPillEnBumDark.image : Asset.Images.federationPillEnBumLight.image
}
// append the pill to the room name
if image.size.width > 0.0 && image.size.height > 0.0 {
let aspectRatio = image.size.width / image.size.height
let pillHeight: CGFloat = 20.0
let offset = 0.5 * (font.capHeight - pillHeight)
let attachment = NSTextAttachment()
attachment.image = image
attachment.bounds = CGRect(x: 0, y: offset, width: pillHeight * aspectRatio, height: pillHeight)
attributedString.append(NSAttributedString(attachment: attachment))
}
return attributedString
}
private func updateBadgeImageViewPosition(isPresenceDisplayed: Bool) {
guard badgeImageView.image != nil else {
badgeImageView.isHidden = true

View File

@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RoomInfoBasicView" customModule="Riot" customModuleProvider="target">
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RoomInfoBasicView" customModule="Element" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="414" height="307"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
@@ -40,12 +40,12 @@
<rect key="frame" x="0.0" y="0.0" width="80" height="80"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1Ub-5S-5cA" customClass="PresenceIndicatorView" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="56" y="56" width="20" height="20"/>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1Ub-5S-5cA" customClass="PresenceIndicatorView" customModule="Element" customModuleProvider="target">
<rect key="frame" x="50" y="46" width="30" height="30"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="0na-3G-Eyj"/>
<constraint firstAttribute="height" constant="20" id="vJh-9j-14t"/>
<constraint firstAttribute="width" constant="30" id="0na-3G-Eyj"/>
<constraint firstAttribute="height" constant="30" id="vJh-9j-14t"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
@@ -58,7 +58,7 @@
<constraints>
<constraint firstItem="6tV-Ha-dWM" firstAttribute="top" secondItem="uhx-GK-2je" secondAttribute="top" id="BoZ-qJ-yLh"/>
<constraint firstItem="6tV-Ha-dWM" firstAttribute="leading" secondItem="uhx-GK-2je" secondAttribute="leading" id="Cct-TF-2Cj"/>
<constraint firstAttribute="trailing" secondItem="1Ub-5S-5cA" secondAttribute="trailing" constant="4" id="D7F-jG-Ann"/>
<constraint firstAttribute="trailing" secondItem="1Ub-5S-5cA" secondAttribute="trailing" id="D7F-jG-Ann"/>
<constraint firstItem="szu-r5-TIX" firstAttribute="leading" secondItem="uhx-GK-2je" secondAttribute="leading" id="D8c-8Q-pof"/>
<constraint firstItem="szu-r5-TIX" firstAttribute="top" secondItem="uhx-GK-2je" secondAttribute="top" id="GI9-rA-rhp"/>
<constraint firstAttribute="bottom" secondItem="6tV-Ha-dWM" secondAttribute="bottom" id="ISw-Ft-Kvj"/>
@@ -88,10 +88,10 @@
</label>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="24" id="Bus-PH-DBv"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="24" id="Bus-PH-DBv"/>
</constraints>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Yjw-ez-u4W">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Yjw-ez-u4W">
<rect key="frame" x="161.5" y="129" width="39.5" height="22"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<nil key="textColor"/>
@@ -196,7 +196,7 @@
</objects>
<designables>
<designable name="DCx-MH-TSC">
<size key="intrinsicContentSize" width="98.5" height="34"/>
<size key="intrinsicContentSize" width="-1" height="34"/>
</designable>
</designables>
<resources>

View File

@@ -29,4 +29,5 @@ struct RoomInfoBasicViewData {
let isDirect: Bool
let directUserId: String?
let directUserPresence: MXPresence
let isFederated: Bool
}