635 lines
18 KiB
Swift
635 lines
18 KiB
Swift
//
|
|
// Copyright 2019 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import SignalServiceKit
|
|
|
|
public enum ThemeIcon: UInt {
|
|
case settingsAccount
|
|
case settingsLinkedDevices
|
|
case settingsDonate
|
|
case settingsAppearance
|
|
case settingsChats
|
|
case settingsStories
|
|
case settingsNotifications
|
|
case settingsPrivacy
|
|
case settingsDataUsage
|
|
case settingsPayments
|
|
case settingsHelp
|
|
case settingsInvite
|
|
case settingsAdvanced
|
|
|
|
case donateManageSubscription
|
|
case donateBadges
|
|
case donateGift
|
|
case donateReceipts
|
|
|
|
case profileName
|
|
case profileUsername
|
|
case profileAbout
|
|
case profileBadges
|
|
|
|
case chatListClearFilter
|
|
case chatListFilterByUnread
|
|
case chatSettingsTimerOn
|
|
case chatSettingsTimerOff
|
|
case chatSettingsWallpaper
|
|
case chatSettingsMessageSound
|
|
case chatSettingsBlock
|
|
case chatSettingsMute
|
|
case chatSettingsMentions
|
|
case contactInfoSafetyNumber
|
|
case contactInfoUserInContacts
|
|
case contactInfoAddToContacts
|
|
case contactInfoSignalConnection
|
|
case contactInfoNoDirectChat
|
|
case contactInfoPendingRequest
|
|
case contactInfoPhone
|
|
case contactInfoGroups
|
|
case contactInfoNote
|
|
case groupInfoLeaveGroup
|
|
case groupInfoAddMembers
|
|
case groupInfoShowAllMembers
|
|
case groupInfoGroupLink
|
|
case groupInfoRequestAndInvites
|
|
case groupInfoPermissions
|
|
case groupInfoEditName
|
|
case groupInfoEditDescription
|
|
case groupMemberRemoveFromGroup
|
|
case groupMemberMakeGroupAdmin
|
|
case groupMemberRevokeGroupAdmin
|
|
case groupMemberAddToGroup
|
|
|
|
case genericGroup
|
|
case genericStories
|
|
case phoneNumber
|
|
case checkCircle
|
|
case checkCircleFill
|
|
case xCircle
|
|
case xBold
|
|
case checkmark
|
|
case checkmarkBold
|
|
case circle
|
|
case arrowDown
|
|
case arrowUp
|
|
case arrowRight
|
|
case chevronUp
|
|
case chevronDown
|
|
case maximize
|
|
case minimize
|
|
case refresh
|
|
case spam
|
|
case official
|
|
case qrCode
|
|
case qrCodeLight
|
|
case threadCompact
|
|
|
|
case buttonCamera
|
|
case buttonMicrophone
|
|
case buttonVoiceCall
|
|
case buttonVideoCall
|
|
case buttonNewCall
|
|
case buttonMessage
|
|
case buttonPhotoLibrary
|
|
case buttonCompose
|
|
case buttonEdit
|
|
case buttonMute
|
|
case buttonDelete
|
|
case buttonSearch
|
|
case buttonForward
|
|
case buttonShare
|
|
case buttonSave
|
|
case buttonCopy
|
|
case buttonMore
|
|
case buttonText
|
|
case buttonX
|
|
case buttonRetry
|
|
case buttonLink
|
|
|
|
case contextMenuSave
|
|
case contextMenuDelete
|
|
case contextMenuReply
|
|
case contextMenuInfo
|
|
case contextMenuCopy
|
|
case contextMenuShare
|
|
case contextMenuForward
|
|
case contextMenuSelect
|
|
case contextMenuSpeak
|
|
case contextMenuStopSpeaking
|
|
case contextMenuSettings
|
|
case contextMenuArchive
|
|
case contextMenuEdit
|
|
case contextMenuPrivacy
|
|
case contextMenuXCircle
|
|
case contextMenuOpenInChat
|
|
case contextMenuVoiceCall
|
|
case contextMenuVideoCall
|
|
case contextMenuMessage
|
|
|
|
case composeNewGroupLarge
|
|
case composeFindByUsernameLarge
|
|
case composeFindByPhoneNumberLarge
|
|
case composeInviteLarge
|
|
|
|
case check16
|
|
case compose16
|
|
case error16
|
|
case group16
|
|
case heart16
|
|
case info16
|
|
case leave16
|
|
case megaphone16
|
|
case memberAdded16
|
|
case memberDeclined16
|
|
case memberRemove16
|
|
case photo16
|
|
case phone16
|
|
case phoneFill16
|
|
case video16
|
|
case videoFill16
|
|
case profile16
|
|
case safetyNumber16
|
|
case timerDisabled16
|
|
case timer16
|
|
case refresh16
|
|
case merge16
|
|
case link16
|
|
|
|
case transfer
|
|
case register
|
|
case backup
|
|
|
|
case emojiActivity
|
|
case emojiAnimal
|
|
case emojiFlag
|
|
case emojiFood
|
|
case emojiObject
|
|
case emojiSmiley
|
|
case emojiSymbol
|
|
case emojiTravel
|
|
case emojiRecent
|
|
case emojiSettings
|
|
|
|
case sealedSenderIndicator
|
|
case empty
|
|
|
|
case profilePlaceholder
|
|
|
|
case raiseHand
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public extension Theme {
|
|
|
|
class func iconImage(_ icon: ThemeIcon) -> UIImage {
|
|
iconImage(icon, isDarkThemeEnabled: isDarkThemeEnabled)
|
|
}
|
|
|
|
class func iconImage(_ icon: ThemeIcon, isDarkThemeEnabled: Bool) -> UIImage {
|
|
let name = iconName(icon, isDarkThemeEnabled: isDarkThemeEnabled)
|
|
guard let image = UIImage(named: name) else {
|
|
owsFailDebug("image was unexpectedly nil: \(name)")
|
|
return UIImage()
|
|
}
|
|
|
|
return image
|
|
}
|
|
|
|
class func iconName(_ icon: ThemeIcon) -> String {
|
|
iconName(icon, isDarkThemeEnabled: isDarkThemeEnabled)
|
|
}
|
|
|
|
class func iconName(_ icon: ThemeIcon, isDarkThemeEnabled: Bool) -> String {
|
|
switch icon {
|
|
// App Settings
|
|
case .settingsAccount:
|
|
return "person-circle"
|
|
case .settingsLinkedDevices:
|
|
return "devices"
|
|
case .settingsDonate:
|
|
return "heart"
|
|
case .settingsAppearance:
|
|
return "appearance"
|
|
case .settingsChats:
|
|
return "chat"
|
|
case .settingsStories:
|
|
return "stories"
|
|
case .settingsNotifications:
|
|
return "bell"
|
|
case .settingsPrivacy:
|
|
return "lock"
|
|
case .settingsDataUsage:
|
|
return "data"
|
|
case .settingsPayments:
|
|
return "payment"
|
|
case .settingsHelp:
|
|
return "help"
|
|
case .settingsInvite:
|
|
return "invite"
|
|
case .settingsAdvanced:
|
|
return "internal"
|
|
|
|
// Donate
|
|
case .donateManageSubscription:
|
|
return "person"
|
|
case .donateBadges:
|
|
return "badge-multi"
|
|
case .donateGift:
|
|
return "gift"
|
|
case .donateReceipts:
|
|
return "receipt"
|
|
|
|
// Profile
|
|
case .profileName:
|
|
return "person"
|
|
case .profileUsername:
|
|
return "at"
|
|
case .profileAbout:
|
|
return "edit"
|
|
case .profileBadges:
|
|
return "badge-multi"
|
|
|
|
// Group & Contact Info
|
|
case .chatSettingsTimerOn:
|
|
return "timer"
|
|
case .chatSettingsTimerOff:
|
|
return "timer-slash"
|
|
case .chatSettingsWallpaper:
|
|
return "color"
|
|
case .chatSettingsMessageSound:
|
|
return "speaker"
|
|
case .chatSettingsBlock:
|
|
return "block"
|
|
case .chatSettingsMute:
|
|
return "bell-slash"
|
|
case .chatSettingsMentions:
|
|
return "at"
|
|
case .contactInfoSafetyNumber:
|
|
return "safety-number"
|
|
case .contactInfoUserInContacts:
|
|
return "person-circle"
|
|
case .contactInfoAddToContacts:
|
|
return "person-circle-plus"
|
|
case .contactInfoSignalConnection:
|
|
return "connections"
|
|
case .contactInfoNoDirectChat:
|
|
return "chat-x"
|
|
case .contactInfoPendingRequest:
|
|
return "chat-badge"
|
|
case .chatListFilterByUnread:
|
|
return "chat-badge-light"
|
|
case .chatListClearFilter:
|
|
return "chat-x-light"
|
|
case .contactInfoPhone:
|
|
return "phone"
|
|
case .contactInfoGroups:
|
|
return "group-resizable"
|
|
case .contactInfoNote:
|
|
return "note-resizable"
|
|
case .groupInfoLeaveGroup:
|
|
return "leave"
|
|
case .groupInfoAddMembers:
|
|
return "plus-bold"
|
|
case .groupInfoShowAllMembers:
|
|
return "chevron-down-bold"
|
|
case .groupInfoGroupLink:
|
|
return "link"
|
|
case .groupInfoRequestAndInvites:
|
|
return "group"
|
|
case .groupInfoPermissions:
|
|
return "key"
|
|
case .groupInfoEditName:
|
|
return "group"
|
|
case .groupInfoEditDescription:
|
|
return "edit"
|
|
case .groupMemberRemoveFromGroup:
|
|
return "minus-circle"
|
|
case .groupMemberMakeGroupAdmin:
|
|
return "key"
|
|
case .groupMemberRevokeGroupAdmin:
|
|
return "key-slash"
|
|
case .groupMemberAddToGroup:
|
|
return "plus-circle"
|
|
|
|
// Generic
|
|
case .genericGroup:
|
|
return "group"
|
|
case .genericStories:
|
|
return "stories"
|
|
case .phoneNumber:
|
|
return "number"
|
|
case .checkCircle:
|
|
return "check-circle"
|
|
case .checkCircleFill:
|
|
return "check-circle-fill"
|
|
case .xCircle:
|
|
return "x-circle"
|
|
case .xBold:
|
|
return "x-bold"
|
|
case .checkmark:
|
|
return "check"
|
|
case .checkmarkBold:
|
|
return "check-bold"
|
|
case .circle:
|
|
return "circle"
|
|
case .arrowDown:
|
|
return "arrow-down"
|
|
case .arrowUp:
|
|
return "arrow-up"
|
|
case .arrowRight:
|
|
return "arrow-right"
|
|
case .chevronUp:
|
|
return "chevron-up"
|
|
case .chevronDown:
|
|
return "chevron-down"
|
|
case .maximize:
|
|
return "maximize"
|
|
case .minimize:
|
|
return "minimize"
|
|
case .refresh:
|
|
return "refresh"
|
|
case .spam:
|
|
return "spam"
|
|
case .official:
|
|
return isDarkThemeEnabled ? "official-dark" : "official"
|
|
case .qrCode:
|
|
return "qr_code"
|
|
case .qrCodeLight:
|
|
return "qr_code-light"
|
|
case .threadCompact:
|
|
return isDarkThemeEnabled ? "thread-compact-fill" : "thread-compact"
|
|
|
|
// Buttons (24 dp)
|
|
case .buttonCamera:
|
|
return "camera"
|
|
case .buttonMicrophone:
|
|
return "mic"
|
|
case .buttonVoiceCall:
|
|
return "phone"
|
|
case .buttonVideoCall:
|
|
return "video"
|
|
case .buttonNewCall:
|
|
return "phone-plus"
|
|
case .buttonMessage:
|
|
return "chat"
|
|
case .buttonPhotoLibrary:
|
|
return "album-tilt"
|
|
case .buttonCompose:
|
|
return "compose"
|
|
case .buttonEdit:
|
|
return "edit"
|
|
case .buttonMute:
|
|
return "bell-slash"
|
|
case .buttonDelete:
|
|
return "trash"
|
|
case .buttonSearch:
|
|
return "search"
|
|
case .buttonForward:
|
|
return "forward"
|
|
case .buttonShare:
|
|
return "share"
|
|
case .buttonSave:
|
|
return "save"
|
|
case .buttonCopy:
|
|
return "copy"
|
|
case .buttonMore:
|
|
return "more"
|
|
case .buttonText:
|
|
return "text"
|
|
case .buttonX:
|
|
return "x"
|
|
case .buttonRetry:
|
|
return "refresh"
|
|
case .buttonLink:
|
|
return "link"
|
|
|
|
// Context Menus (light version of icons)
|
|
case .contextMenuSave:
|
|
return "save-light"
|
|
case .contextMenuDelete:
|
|
return "trash-light"
|
|
case .contextMenuReply:
|
|
return "reply-light"
|
|
case .contextMenuInfo:
|
|
return "info-light"
|
|
case .contextMenuCopy:
|
|
return "copy-light"
|
|
case .contextMenuShare:
|
|
return "share-light"
|
|
case .contextMenuForward:
|
|
return "forward-light"
|
|
case .contextMenuSelect:
|
|
return "check-circle-light"
|
|
case .contextMenuSpeak:
|
|
return "speaker-light"
|
|
case .contextMenuStopSpeaking:
|
|
return "pause-circle-light"
|
|
case .contextMenuSettings:
|
|
return "settings-light"
|
|
case .contextMenuArchive:
|
|
return "archive-light"
|
|
case .contextMenuEdit:
|
|
return "edit-light"
|
|
case .contextMenuPrivacy:
|
|
return "lock-light"
|
|
case .contextMenuXCircle:
|
|
return "x-circle-light"
|
|
case .contextMenuOpenInChat:
|
|
return "arrow-square-upright-light"
|
|
case .contextMenuVoiceCall:
|
|
return "phone-light"
|
|
case .contextMenuVideoCall:
|
|
return "video-light"
|
|
case .contextMenuMessage:
|
|
return "chat-light"
|
|
|
|
// Empty chat list
|
|
case .composeNewGroupLarge:
|
|
return "group-resizable"
|
|
case .composeFindByUsernameLarge:
|
|
return "at-display-bold"
|
|
case .composeFindByPhoneNumberLarge:
|
|
return "number-resizable"
|
|
case .composeInviteLarge:
|
|
return "invite-resizable"
|
|
|
|
// Compact 16 dp icons
|
|
case .check16:
|
|
return "check-compact"
|
|
case .compose16:
|
|
return "edit-compact"
|
|
case .error16:
|
|
return "error-circle-compact"
|
|
case .group16:
|
|
return "group-compact"
|
|
case .heart16:
|
|
return "heart-compact"
|
|
case .info16:
|
|
return "info-compact"
|
|
case .leave16:
|
|
return "leave-compact"
|
|
case .megaphone16:
|
|
return "megaphone-compact"
|
|
case .memberAdded16:
|
|
return "person-plus-compact"
|
|
case .memberDeclined16:
|
|
return "person-x-compact"
|
|
case .memberRemove16:
|
|
return "person-minus-compact"
|
|
case .photo16:
|
|
return "photo-compact"
|
|
case .phone16:
|
|
return "phone-compact"
|
|
case .phoneFill16:
|
|
return "phone-fill-compact"
|
|
case .video16:
|
|
return "video-compact"
|
|
case .videoFill16:
|
|
return "video-fill-compact"
|
|
case .profile16:
|
|
return "person-compact"
|
|
case .safetyNumber16:
|
|
return "safety-number-compact"
|
|
case .timerDisabled16:
|
|
return "timer-slash-compact"
|
|
case .timer16:
|
|
return "timer-compact"
|
|
case .refresh16:
|
|
return "refresh-compact"
|
|
case .merge16:
|
|
return "merge-compact"
|
|
case .link16:
|
|
return "link-compact"
|
|
|
|
case .transfer:
|
|
return "transfer-\(UIDevice.current.isIPad ? "ipad" : "phone")-outline-60-\(isDarkThemeEnabled ? "dark" : "light")"
|
|
case .register:
|
|
return "register-\(UIDevice.current.isIPad ? "ipad" : "phone")-outline-60-\(isDarkThemeEnabled ? "dark" : "light")"
|
|
case .backup:
|
|
return "backup-display"
|
|
|
|
case .emojiActivity:
|
|
return "emoji-activity"
|
|
case .emojiAnimal:
|
|
return "emoji-animal"
|
|
case .emojiFlag:
|
|
return "emoji-flag"
|
|
case .emojiFood:
|
|
return "emoji-food"
|
|
case .emojiObject:
|
|
return "emoji-object"
|
|
case .emojiSmiley:
|
|
return "emoji-smiley"
|
|
case .emojiSymbol:
|
|
return "emoji-symbol"
|
|
case .emojiTravel:
|
|
return "emoji-travel"
|
|
case .emojiRecent:
|
|
return "recent-20"
|
|
case .emojiSettings:
|
|
return "settings"
|
|
|
|
case .sealedSenderIndicator:
|
|
return "unidentified-delivery-outline-20"
|
|
case .empty:
|
|
return "empty-24"
|
|
|
|
case .profilePlaceholder:
|
|
return isDarkThemeEnabled ? "profile-placeholder-dark-56" : "profile-placeholder-56"
|
|
|
|
case .raiseHand:
|
|
return "raise_hand"
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
extension Theme {
|
|
|
|
// Bridging the old name to new name for our ObjC friends
|
|
public static var actionSheetBackgroundColor: UIColor {
|
|
return ActionSheet.default.backgroundColor
|
|
}
|
|
|
|
public enum ActionSheet {
|
|
case `default`
|
|
case grouped
|
|
case translucentDark
|
|
|
|
public var hairlineColor: UIColor {
|
|
switch self {
|
|
case .default, .grouped: return isDarkThemeEnabled ? .ows_gray65 : .ows_gray05
|
|
case .translucentDark: return .ows_whiteAlpha20
|
|
}
|
|
}
|
|
|
|
public var headerTitleColor: UIColor {
|
|
switch self {
|
|
case .default, .grouped: return Theme.primaryTextColor
|
|
case .translucentDark: return Theme.darkThemePrimaryColor
|
|
}
|
|
}
|
|
|
|
public var headerMessageColor: UIColor {
|
|
switch self {
|
|
case .default, .grouped: return Theme.primaryTextColor
|
|
case .translucentDark: return Theme.darkThemeSecondaryTextAndIconColor
|
|
}
|
|
}
|
|
|
|
public var buttonTextColor: UIColor {
|
|
switch self {
|
|
case .default, .grouped: return Theme.primaryTextColor
|
|
case .translucentDark: return Theme.darkThemePrimaryColor
|
|
}
|
|
}
|
|
|
|
public var safetyNumberChangeButtonBackgroundColor: UIColor {
|
|
switch self {
|
|
case .default, .grouped: return Theme.conversationButtonBackgroundColor
|
|
case .translucentDark: return .ows_gray75
|
|
}
|
|
}
|
|
|
|
public var safetyNumberChangeButtonTextColor: UIColor {
|
|
switch self {
|
|
case .default, .grouped: return Theme.conversationButtonTextColor
|
|
case .translucentDark: return .ows_accentBlueDark
|
|
}
|
|
}
|
|
|
|
public var destructiveButtonTextColor: UIColor {
|
|
return .ows_accentRed
|
|
}
|
|
|
|
public var buttonHighlightColor: UIColor {
|
|
switch self {
|
|
case .default, .grouped: return Theme.cellSelectedColor
|
|
case .translucentDark: return .ows_whiteAlpha20
|
|
}
|
|
}
|
|
|
|
public var backgroundColor: UIColor {
|
|
switch self {
|
|
case .default: return isDarkThemeEnabled ? .ows_gray75 : .ows_white
|
|
case .grouped: return Theme.tableView2BackgroundColor
|
|
case .translucentDark: return .clear
|
|
}
|
|
}
|
|
|
|
public func createBackgroundView() -> UIView {
|
|
switch self {
|
|
case .default, .grouped:
|
|
let background = UIView()
|
|
background.backgroundColor = backgroundColor
|
|
return background
|
|
case .translucentDark:
|
|
let background = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
|
|
return background
|
|
}
|
|
}
|
|
}
|
|
}
|