mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit '6c0d9ee7b698e281ce68b91f0fdc9d96e0325800'
This commit is contained in:
commit
536df22d0f
@ -5097,3 +5097,10 @@ Any member of this group will be able to see messages in the channel.";
|
|||||||
"Wallet.AccessDenied.Title" = "Please Allow Access";
|
"Wallet.AccessDenied.Title" = "Please Allow Access";
|
||||||
"Wallet.AccessDenied.Camera" = "TON Wallet needs access to your camera to take photos and videos.\n\nPlease go to Settings > Privacy > Camera and set TON Wallet to ON.";
|
"Wallet.AccessDenied.Camera" = "TON Wallet needs access to your camera to take photos and videos.\n\nPlease go to Settings > Privacy > Camera and set TON Wallet to ON.";
|
||||||
"Wallet.AccessDenied.Settings" = "Settings";
|
"Wallet.AccessDenied.Settings" = "Settings";
|
||||||
|
|
||||||
|
"GroupInfo.ShowMoreMembers_0" = "%@ more";
|
||||||
|
"GroupInfo.ShowMoreMembers_1" = "%@ more";
|
||||||
|
"GroupInfo.ShowMoreMembers_2" = "%@ more";
|
||||||
|
"GroupInfo.ShowMoreMembers_3_10" = "%@ more";
|
||||||
|
"GroupInfo.ShowMoreMembers_many" = "%@ more";
|
||||||
|
"GroupInfo.ShowMoreMembers_any" = "%@ more";
|
||||||
|
@ -40,6 +40,8 @@ import AppBundle
|
|||||||
import Markdown
|
import Markdown
|
||||||
import LocalizedPeerData
|
import LocalizedPeerData
|
||||||
|
|
||||||
|
private let maxParticipantsDisplayedCount: Int32 = 50
|
||||||
|
|
||||||
private final class GroupInfoArguments {
|
private final class GroupInfoArguments {
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
|
|
||||||
@ -71,8 +73,9 @@ private final class GroupInfoArguments {
|
|||||||
let openLocation: (PeerGeoLocation) -> Void
|
let openLocation: (PeerGeoLocation) -> Void
|
||||||
let changeLocation: () -> Void
|
let changeLocation: () -> Void
|
||||||
let displayLocationContextMenu: (String) -> Void
|
let displayLocationContextMenu: (String) -> Void
|
||||||
|
let expandParticipants: () -> Void
|
||||||
|
|
||||||
init(context: AccountContext, avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext, tapAvatarAction: @escaping () -> Void, changeProfilePhoto: @escaping () -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, changeNotificationMuteSettings: @escaping () -> Void, openPreHistory: @escaping () -> Void, openSharedMedia: @escaping () -> Void, openAdministrators: @escaping () -> Void, openPermissions: @escaping () -> Void, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updateEditingDescriptionText: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addMember: @escaping () -> Void, promotePeer: @escaping (RenderedChannelParticipant) -> Void, restrictPeer: @escaping (RenderedChannelParticipant) -> Void, removePeer: @escaping (PeerId) -> Void, leave: @escaping () -> Void, displayUsernameShareMenu: @escaping (String) -> Void, displayUsernameContextMenu: @escaping (String) -> Void, displayAboutContextMenu: @escaping (String) -> Void, aboutLinkAction: @escaping (TextLinkItemActionType, TextLinkItem) -> Void, openStickerPackSetup: @escaping () -> Void, openGroupTypeSetup: @escaping () -> Void, openLinkedChannelSetup: @escaping () -> Void, openLocation: @escaping (PeerGeoLocation) -> Void, changeLocation: @escaping () -> Void, displayLocationContextMenu: @escaping (String) -> Void) {
|
init(context: AccountContext, avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext, tapAvatarAction: @escaping () -> Void, changeProfilePhoto: @escaping () -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, changeNotificationMuteSettings: @escaping () -> Void, openPreHistory: @escaping () -> Void, openSharedMedia: @escaping () -> Void, openAdministrators: @escaping () -> Void, openPermissions: @escaping () -> Void, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updateEditingDescriptionText: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addMember: @escaping () -> Void, promotePeer: @escaping (RenderedChannelParticipant) -> Void, restrictPeer: @escaping (RenderedChannelParticipant) -> Void, removePeer: @escaping (PeerId) -> Void, leave: @escaping () -> Void, displayUsernameShareMenu: @escaping (String) -> Void, displayUsernameContextMenu: @escaping (String) -> Void, displayAboutContextMenu: @escaping (String) -> Void, aboutLinkAction: @escaping (TextLinkItemActionType, TextLinkItem) -> Void, openStickerPackSetup: @escaping () -> Void, openGroupTypeSetup: @escaping () -> Void, openLinkedChannelSetup: @escaping () -> Void, openLocation: @escaping (PeerGeoLocation) -> Void, changeLocation: @escaping () -> Void, displayLocationContextMenu: @escaping (String) -> Void, expandParticipants: @escaping () -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.avatarAndNameInfoContext = avatarAndNameInfoContext
|
self.avatarAndNameInfoContext = avatarAndNameInfoContext
|
||||||
self.tapAvatarAction = tapAvatarAction
|
self.tapAvatarAction = tapAvatarAction
|
||||||
@ -102,6 +105,7 @@ private final class GroupInfoArguments {
|
|||||||
self.openLocation = openLocation
|
self.openLocation = openLocation
|
||||||
self.changeLocation = changeLocation
|
self.changeLocation = changeLocation
|
||||||
self.displayLocationContextMenu = displayLocationContextMenu
|
self.displayLocationContextMenu = displayLocationContextMenu
|
||||||
|
self.expandParticipants = expandParticipants
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +193,7 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
case permissions(PresentationTheme, String, String)
|
case permissions(PresentationTheme, String, String)
|
||||||
case addMember(PresentationTheme, String, editing: Bool)
|
case addMember(PresentationTheme, String, editing: Bool)
|
||||||
case member(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, index: Int, peerId: PeerId, peer: Peer, participant: RenderedChannelParticipant?, presence: PeerPresence?, memberStatus: GroupInfoMemberStatus, editing: ItemListPeerItemEditing, revealActions: [ParticipantRevealAction], enabled: Bool, selectable: Bool)
|
case member(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, index: Int, peerId: PeerId, peer: Peer, participant: RenderedChannelParticipant?, presence: PeerPresence?, memberStatus: GroupInfoMemberStatus, editing: ItemListPeerItemEditing, revealActions: [ParticipantRevealAction], enabled: Bool, selectable: Bool)
|
||||||
|
case expand(PresentationTheme, String)
|
||||||
case leave(PresentationTheme, String)
|
case leave(PresentationTheme, String)
|
||||||
|
|
||||||
var section: ItemListSectionId {
|
var section: ItemListSectionId {
|
||||||
@ -203,7 +208,7 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
return GroupInfoSection.sharedMediaAndNotifications.rawValue
|
return GroupInfoSection.sharedMediaAndNotifications.rawValue
|
||||||
case .permissions, .administrators:
|
case .permissions, .administrators:
|
||||||
return GroupInfoSection.memberManagement.rawValue
|
return GroupInfoSection.memberManagement.rawValue
|
||||||
case .addMember, .member:
|
case .addMember, .member, .expand:
|
||||||
return GroupInfoSection.members.rawValue
|
return GroupInfoSection.members.rawValue
|
||||||
case .leave:
|
case .leave:
|
||||||
return GroupInfoSection.leave.rawValue
|
return GroupInfoSection.leave.rawValue
|
||||||
@ -213,40 +218,40 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
static func ==(lhs: GroupInfoEntry, rhs: GroupInfoEntry) -> Bool {
|
static func ==(lhs: GroupInfoEntry, rhs: GroupInfoEntry) -> Bool {
|
||||||
switch lhs {
|
switch lhs {
|
||||||
case let .info(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsCachedData, lhsState, lhsUpdatingAvatar):
|
case let .info(lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsCachedData, lhsState, lhsUpdatingAvatar):
|
||||||
if case let .info(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsCachedData, rhsState, rhsUpdatingAvatar) = rhs {
|
if case let .info(rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsCachedData, rhsState, rhsUpdatingAvatar) = rhs {
|
||||||
if lhsTheme !== rhsTheme {
|
if lhsTheme !== rhsTheme {
|
||||||
return false
|
|
||||||
}
|
|
||||||
if lhsStrings !== rhsStrings {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if lhsDateTimeFormat != rhsDateTimeFormat {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if let lhsPeer = lhsPeer, let rhsPeer = rhsPeer {
|
|
||||||
if !lhsPeer.isEqual(rhsPeer) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else if (lhsPeer == nil) != (rhsPeer != nil) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if let lhsCachedData = lhsCachedData, let rhsCachedData = rhsCachedData {
|
|
||||||
if !lhsCachedData.isEqual(to: rhsCachedData) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else if (lhsCachedData != nil) != (rhsCachedData != nil) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if lhsState != rhsState {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if lhsUpdatingAvatar != rhsUpdatingAvatar {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhsStrings !== rhsStrings {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhsDateTimeFormat != rhsDateTimeFormat {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if let lhsPeer = lhsPeer, let rhsPeer = rhsPeer {
|
||||||
|
if !lhsPeer.isEqual(rhsPeer) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else if (lhsPeer == nil) != (rhsPeer != nil) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if let lhsCachedData = lhsCachedData, let rhsCachedData = rhsCachedData {
|
||||||
|
if !lhsCachedData.isEqual(to: rhsCachedData) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else if (lhsCachedData != nil) != (rhsCachedData != nil) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhsState != rhsState {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhsUpdatingAvatar != rhsUpdatingAvatar {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
case let .setGroupPhoto(lhsTheme, lhsText):
|
case let .setGroupPhoto(lhsTheme, lhsText):
|
||||||
if case let .setGroupPhoto(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
if case let .setGroupPhoto(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||||
return true
|
return true
|
||||||
@ -419,6 +424,12 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
case let .expand(lhsTheme, lhsText):
|
||||||
|
if case let .expand(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,8 +480,10 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
return 16
|
return 16
|
||||||
case let .member(_, _, _, _, index, _, _, _, _, _, _, _, _, _):
|
case let .member(_, _, _, _, index, _, _, _, _, _, _, _, _, _):
|
||||||
return 20 + index
|
return 20 + index
|
||||||
case .leave:
|
case .expand:
|
||||||
return 200000 + 1
|
return 200000 + 1
|
||||||
|
case .leave:
|
||||||
|
return 200000 + 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,6 +605,10 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
}, removePeer: { peerId in
|
}, removePeer: { peerId in
|
||||||
arguments.removePeer(peerId)
|
arguments.removePeer(peerId)
|
||||||
})
|
})
|
||||||
|
case let .expand(theme, title):
|
||||||
|
return ItemListPeerActionItem(theme: theme, icon: PresentationResourcesItemList.downArrowImage(theme), title: title, sectionId: self.section, editing: false, action: {
|
||||||
|
arguments.expandParticipants()
|
||||||
|
})
|
||||||
case let .leave(theme, title):
|
case let .leave(theme, title):
|
||||||
return ItemListActionItem(theme: theme, title: title, kind: .destructive, alignment: .center, sectionId: self.section, style: .blocks, action: {
|
return ItemListActionItem(theme: theme, title: title, kind: .destructive, alignment: .center, sectionId: self.section, style: .blocks, action: {
|
||||||
arguments.leave()
|
arguments.leave()
|
||||||
@ -627,6 +644,7 @@ private struct GroupInfoState: Equatable {
|
|||||||
let editingState: GroupInfoEditingState?
|
let editingState: GroupInfoEditingState?
|
||||||
let updatingName: ItemListAvatarAndNameInfoItemName?
|
let updatingName: ItemListAvatarAndNameInfoItemName?
|
||||||
let peerIdWithRevealedOptions: PeerId?
|
let peerIdWithRevealedOptions: PeerId?
|
||||||
|
let expandedParticipants: Bool
|
||||||
|
|
||||||
let temporaryParticipants: [TemporaryParticipant]
|
let temporaryParticipants: [TemporaryParticipant]
|
||||||
let successfullyAddedParticipantIds: Set<PeerId>
|
let successfullyAddedParticipantIds: Set<PeerId>
|
||||||
@ -649,6 +667,9 @@ private struct GroupInfoState: Equatable {
|
|||||||
if lhs.peerIdWithRevealedOptions != rhs.peerIdWithRevealedOptions {
|
if lhs.peerIdWithRevealedOptions != rhs.peerIdWithRevealedOptions {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.expandedParticipants != rhs.expandedParticipants {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if lhs.temporaryParticipants != rhs.temporaryParticipants {
|
if lhs.temporaryParticipants != rhs.temporaryParticipants {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -668,39 +689,43 @@ private struct GroupInfoState: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func withUpdatedUpdatingAvatar(_ updatingAvatar: ItemListAvatarAndNameInfoItemUpdatingAvatar?) -> GroupInfoState {
|
func withUpdatedUpdatingAvatar(_ updatingAvatar: ItemListAvatarAndNameInfoItemUpdatingAvatar?) -> GroupInfoState {
|
||||||
return GroupInfoState(updatingAvatar: updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
return GroupInfoState(updatingAvatar: updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, expandedParticipants: self.expandedParticipants, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withUpdatedEditingState(_ editingState: GroupInfoEditingState?) -> GroupInfoState {
|
func withUpdatedEditingState(_ editingState: GroupInfoEditingState?) -> GroupInfoState {
|
||||||
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, expandedParticipants: self.expandedParticipants, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withUpdatedUpdatingName(_ updatingName: ItemListAvatarAndNameInfoItemName?) -> GroupInfoState {
|
func withUpdatedUpdatingName(_ updatingName: ItemListAvatarAndNameInfoItemName?) -> GroupInfoState {
|
||||||
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, expandedParticipants: self.expandedParticipants, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withUpdatedPeerIdWithRevealedOptions(_ peerIdWithRevealedOptions: PeerId?) -> GroupInfoState {
|
func withUpdatedPeerIdWithRevealedOptions(_ peerIdWithRevealedOptions: PeerId?) -> GroupInfoState {
|
||||||
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: peerIdWithRevealedOptions, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: peerIdWithRevealedOptions, expandedParticipants: self.expandedParticipants, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withUpdatedExpandedParticipants(_ expandedParticipants: Bool) -> GroupInfoState {
|
||||||
|
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, expandedParticipants: expandedParticipants, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
||||||
|
}
|
||||||
|
|
||||||
func withUpdatedTemporaryParticipants(_ temporaryParticipants: [TemporaryParticipant]) -> GroupInfoState {
|
func withUpdatedTemporaryParticipants(_ temporaryParticipants: [TemporaryParticipant]) -> GroupInfoState {
|
||||||
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, temporaryParticipants: temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, expandedParticipants: self.expandedParticipants, temporaryParticipants: temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withUpdatedSuccessfullyAddedParticipantIds(_ successfullyAddedParticipantIds: Set<PeerId>) -> GroupInfoState {
|
func withUpdatedSuccessfullyAddedParticipantIds(_ successfullyAddedParticipantIds: Set<PeerId>) -> GroupInfoState {
|
||||||
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, expandedParticipants: self.expandedParticipants, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withUpdatedRemovingParticipantIds(_ removingParticipantIds: Set<PeerId>) -> GroupInfoState {
|
func withUpdatedRemovingParticipantIds(_ removingParticipantIds: Set<PeerId>) -> GroupInfoState {
|
||||||
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, expandedParticipants: self.expandedParticipants, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: removingParticipantIds, savingData: self.savingData, searchingMembers: self.searchingMembers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withUpdatedSavingData(_ savingData: Bool) -> GroupInfoState {
|
func withUpdatedSavingData(_ savingData: Bool) -> GroupInfoState {
|
||||||
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: savingData, searchingMembers: self.searchingMembers)
|
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, expandedParticipants: self.expandedParticipants, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: savingData, searchingMembers: self.searchingMembers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func withUpdatedSearchingMembers(_ searchingMembers: Bool) -> GroupInfoState {
|
func withUpdatedSearchingMembers(_ searchingMembers: Bool) -> GroupInfoState {
|
||||||
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: searchingMembers)
|
return GroupInfoState(updatingAvatar: self.updatingAvatar, editingState: self.editingState, updatingName: self.updatingName, peerIdWithRevealedOptions: self.peerIdWithRevealedOptions, expandedParticipants: self.expandedParticipants, temporaryParticipants: self.temporaryParticipants, successfullyAddedParticipantIds: self.successfullyAddedParticipantIds, removingParticipantIds: self.removingParticipantIds, savingData: self.savingData, searchingMembers: searchingMembers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1157,8 +1182,11 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa
|
|||||||
sortedParticipants = updatedParticipants
|
sortedParticipants = updatedParticipants
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0 ..< sortedParticipants.count {
|
var expand = state.expandedParticipants
|
||||||
let participant = sortedParticipants[i]
|
let participants = expand ? sortedParticipants : Array(sortedParticipants.prefix(Int(maxParticipantsDisplayedCount)))
|
||||||
|
|
||||||
|
for i in 0 ..< participants.count {
|
||||||
|
let participant = participants[i]
|
||||||
let memberStatus: GroupInfoMemberStatus
|
let memberStatus: GroupInfoMemberStatus
|
||||||
switch participant.participant {
|
switch participant.participant {
|
||||||
case let .creator(_, rank):
|
case let .creator(_, rank):
|
||||||
@ -1220,6 +1248,10 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa
|
|||||||
|
|
||||||
entries.append(GroupInfoEntry.member(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, index: i, peerId: participant.peer.id, peer: participant.peer, participant: participant, presence: participant.presences[participant.peer.id], memberStatus: memberStatus, editing: ItemListPeerItemEditing(editable: !peerActions.isEmpty, editing: state.editingState != nil && canRemoveAnyMember, revealed: state.peerIdWithRevealedOptions == participant.peer.id), revealActions: peerActions, enabled: true, selectable: participant.peer.id != account.peerId))
|
entries.append(GroupInfoEntry.member(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, index: i, peerId: participant.peer.id, peer: participant.peer, participant: participant, presence: participant.presences[participant.peer.id], memberStatus: memberStatus, editing: ItemListPeerItemEditing(editable: !peerActions.isEmpty, editing: state.editingState != nil && canRemoveAnyMember, revealed: state.peerIdWithRevealedOptions == participant.peer.id), revealActions: peerActions, enabled: true, selectable: participant.peer.id != account.peerId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !expand && memberCount > maxParticipantsDisplayedCount {
|
||||||
|
entries.append(GroupInfoEntry.expand(presentationData.theme, presentationData.strings.GroupInfo_ShowMoreMembers(Int32(memberCount - maxParticipantsDisplayedCount))))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let group = view.peers[view.peerId] as? TelegramGroup {
|
if let group = view.peers[view.peerId] as? TelegramGroup {
|
||||||
@ -1288,8 +1320,8 @@ private func valuesRequiringUpdate(state: GroupInfoState, view: PeerView) -> (ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func groupInfoController(context: AccountContext, peerId originalPeerId: PeerId, membersLoaded: @escaping () -> Void = {}) -> ViewController {
|
public func groupInfoController(context: AccountContext, peerId originalPeerId: PeerId, membersLoaded: @escaping () -> Void = {}) -> ViewController {
|
||||||
let statePromise = ValuePromise(GroupInfoState(updatingAvatar: nil, editingState: nil, updatingName: nil, peerIdWithRevealedOptions: nil, temporaryParticipants: [], successfullyAddedParticipantIds: Set(), removingParticipantIds: Set(), savingData: false, searchingMembers: false), ignoreRepeated: true)
|
let statePromise = ValuePromise(GroupInfoState(updatingAvatar: nil, editingState: nil, updatingName: nil, peerIdWithRevealedOptions: nil, expandedParticipants: false, temporaryParticipants: [], successfullyAddedParticipantIds: Set(), removingParticipantIds: Set(), savingData: false, searchingMembers: false), ignoreRepeated: true)
|
||||||
let stateValue = Atomic(value: GroupInfoState(updatingAvatar: nil, editingState: nil, updatingName: nil, peerIdWithRevealedOptions: nil, temporaryParticipants: [], successfullyAddedParticipantIds: Set(), removingParticipantIds: Set(), savingData: false, searchingMembers: false))
|
let stateValue = Atomic(value: GroupInfoState(updatingAvatar: nil, editingState: nil, updatingName: nil, peerIdWithRevealedOptions: nil, expandedParticipants: false, temporaryParticipants: [], successfullyAddedParticipantIds: Set(), removingParticipantIds: Set(), savingData: false, searchingMembers: false))
|
||||||
let updateState: ((GroupInfoState) -> GroupInfoState) -> Void = { f in
|
let updateState: ((GroupInfoState) -> GroupInfoState) -> Void = { f in
|
||||||
statePromise.set(stateValue.modify { f($0) })
|
statePromise.set(stateValue.modify { f($0) })
|
||||||
}
|
}
|
||||||
@ -2077,6 +2109,10 @@ public func groupInfoController(context: AccountContext, peerId originalPeerId:
|
|||||||
})
|
})
|
||||||
}, displayLocationContextMenu: { text in
|
}, displayLocationContextMenu: { text in
|
||||||
displayCopyContextMenuImpl?(text, .location)
|
displayCopyContextMenuImpl?(text, .location)
|
||||||
|
}, expandParticipants: {
|
||||||
|
updateState {
|
||||||
|
$0.withUpdatedExpandedParticipants(true)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let loadMoreControl = Atomic<(PeerId, PeerChannelMemberCategoryControl)?>(value: nil)
|
let loadMoreControl = Atomic<(PeerId, PeerChannelMemberCategoryControl)?>(value: nil)
|
||||||
|
@ -933,6 +933,9 @@ public func storageUsageController(context: AccountContext, cacheUsagePromise: P
|
|||||||
}
|
}
|
||||||
|
|
||||||
let controller = ItemListController(context: context, state: signal)
|
let controller = ItemListController(context: context, state: signal)
|
||||||
|
if isModal {
|
||||||
|
controller.navigationPresentation = .modal
|
||||||
|
}
|
||||||
presentControllerImpl = { [weak controller] c, contextType, a in
|
presentControllerImpl = { [weak controller] c, contextType, a in
|
||||||
controller?.present(c, in: contextType, with: a)
|
controller?.present(c, in: contextType, with: a)
|
||||||
}
|
}
|
||||||
|
@ -584,7 +584,13 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
moreImpl?()
|
moreImpl?()
|
||||||
})
|
})
|
||||||
|
|
||||||
let defaultThemes: [PresentationThemeReference] = [.builtin(.dayClassic), .builtin(.day), .builtin(.night), .builtin(.nightAccent)]
|
var defaultThemes: [PresentationThemeReference] = []
|
||||||
|
if presentationData.autoNightModeTriggered {
|
||||||
|
} else {
|
||||||
|
defaultThemes.append(contentsOf: [.builtin(.dayClassic), .builtin(.day)])
|
||||||
|
}
|
||||||
|
defaultThemes.append(contentsOf: [.builtin(.night), .builtin(.nightAccent)])
|
||||||
|
|
||||||
let cloudThemes: [PresentationThemeReference] = cloudThemes.map { .cloud(PresentationCloudTheme(theme: $0, resolvedWallpaper: nil)) }
|
let cloudThemes: [PresentationThemeReference] = cloudThemes.map { .cloud(PresentationCloudTheme(theme: $0, resolvedWallpaper: nil)) }
|
||||||
|
|
||||||
var availableThemes = defaultThemes
|
var availableThemes = defaultThemes
|
||||||
@ -667,7 +673,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
chatWallpaper = resolvedWallpaper ?? presentationTheme.chat.defaultWallpaper
|
chatWallpaper = resolvedWallpaper ?? presentationTheme.chat.defaultWallpaper
|
||||||
}
|
}
|
||||||
|
|
||||||
return PresentationThemeSettings(chatWallpaper: chatWallpaper, theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
return PresentationThemeSettings(chatWallpaper: chatWallpaper, theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, fontSize: current.fontSize, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}).start()
|
}).start()
|
||||||
|
@ -156,7 +156,7 @@ private func makeDarkPresentationTheme(accentColor: UIColor, baseColor: Presenta
|
|||||||
scrollIndicatorColor: UIColor(white: 1.0, alpha: 0.3),
|
scrollIndicatorColor: UIColor(white: 1.0, alpha: 0.3),
|
||||||
pageIndicatorInactiveColor: mainSecondaryTextColor.withAlphaComponent(0.4),
|
pageIndicatorInactiveColor: mainSecondaryTextColor.withAlphaComponent(0.4),
|
||||||
inputClearButtonColor: mainSecondaryColor,
|
inputClearButtonColor: mainSecondaryColor,
|
||||||
itemBarChart: PresentationThemeItemBarChart(color1: accentColor, color2: UIColor(rgb: 0x929196), color3: UIColor(rgb: 0x333333))
|
itemBarChart: PresentationThemeItemBarChart(color1: accentColor, color2: mainSecondaryTextColor.withAlphaComponent(0.5), color3: accentColor.withMultiplied(hue: 1.038, saturation: 0.329, brightness: 0.33))
|
||||||
)
|
)
|
||||||
|
|
||||||
let chatList = PresentationThemeChatList(
|
let chatList = PresentationThemeChatList(
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -31,6 +31,7 @@ public enum PresentationResourceKey: Int32 {
|
|||||||
case navigationPlayerMaximizedRateActiveIcon
|
case navigationPlayerMaximizedRateActiveIcon
|
||||||
case navigationPlayerMaximizedRateInactiveIcon
|
case navigationPlayerMaximizedRateInactiveIcon
|
||||||
|
|
||||||
|
case itemListDownArrow
|
||||||
case itemListDisclosureArrow
|
case itemListDisclosureArrow
|
||||||
case itemListCheckIcon
|
case itemListCheckIcon
|
||||||
case itemListSecondaryCheckIcon
|
case itemListSecondaryCheckIcon
|
||||||
|
@ -21,6 +21,12 @@ public func generateItemListPlusIcon(_ color: UIColor) -> UIImage? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public struct PresentationResourcesItemList {
|
public struct PresentationResourcesItemList {
|
||||||
|
public static func downArrowImage(_ theme: PresentationTheme) -> UIImage? {
|
||||||
|
return theme.image(PresentationResourceKey.itemListDownArrow.rawValue, { theme in
|
||||||
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Search/DownButton"), color: theme.list.itemAccentColor)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public static func disclosureArrowImage(_ theme: PresentationTheme) -> UIImage? {
|
public static func disclosureArrowImage(_ theme: PresentationTheme) -> UIImage? {
|
||||||
return theme.image(PresentationResourceKey.itemListDisclosureArrow.rawValue, { theme in
|
return theme.image(PresentationResourceKey.itemListDisclosureArrow.rawValue, { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Item List/DisclosureArrow"), color: theme.list.disclosureArrowColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Item List/DisclosureArrow"), color: theme.list.disclosureArrowColor)
|
||||||
|
@ -1983,6 +1983,10 @@ final class SharedApplicationContext {
|
|||||||
var carPlayOptions = options
|
var carPlayOptions = options
|
||||||
carPlayOptions.insert(.allowInCarPlay)
|
carPlayOptions.insert(.allowInCarPlay)
|
||||||
|
|
||||||
|
if #available(iOS 13.2, *) {
|
||||||
|
carPlayOptions.insert(.allowAnnouncement)
|
||||||
|
}
|
||||||
|
|
||||||
unknownMessageCategory = UNNotificationCategory(identifier: "unknown", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
|
unknownMessageCategory = UNNotificationCategory(identifier: "unknown", actions: [], intentIdentifiers: [], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: options)
|
||||||
replyMessageCategory = UNNotificationCategory(identifier: "withReply", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
|
replyMessageCategory = UNNotificationCategory(identifier: "withReply", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
|
||||||
replyLegacyMessageCategory = UNNotificationCategory(identifier: "r", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
|
replyLegacyMessageCategory = UNNotificationCategory(identifier: "r", actions: [reply], intentIdentifiers: [INSearchForMessagesIntentIdentifier], hiddenPreviewsBodyPlaceholder: hiddenContentString, options: carPlayOptions)
|
||||||
|
@ -7805,23 +7805,22 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
items.append(DeleteChatPeerActionSheetItem(context: self.context, peer: peer, chatPeer: peer, action: .clearCacheSuggestion, strings: self.presentationData.strings, nameDisplayOrder: self.presentationData.nameDisplayOrder))
|
items.append(DeleteChatPeerActionSheetItem(context: self.context, peer: peer, chatPeer: peer, action: .clearCacheSuggestion, strings: self.presentationData.strings, nameDisplayOrder: self.presentationData.nameDisplayOrder))
|
||||||
|
|
||||||
|
var presented = false
|
||||||
items.append(ActionSheetButtonItem(title: self.presentationData.strings.ClearCache_FreeSpace, color: .accent, action: { [weak self, weak actionSheet] in
|
items.append(ActionSheetButtonItem(title: self.presentationData.strings.ClearCache_FreeSpace, color: .accent, action: { [weak self, weak actionSheet] in
|
||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
if let strongSelf = self {
|
if let strongSelf = self, !presented {
|
||||||
let controller = storageUsageController(context: strongSelf.context, isModal: true)
|
presented = true
|
||||||
strongSelf.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet), blockInteraction: true)
|
strongSelf.push(storageUsageController(context: strongSelf.context, isModal: true))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||||
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
|
|
||||||
})
|
})
|
||||||
])])
|
])])
|
||||||
self.chatDisplayNode.dismissInput()
|
self.chatDisplayNode.dismissInput()
|
||||||
self.presentInGlobalOverlay(actionSheet)
|
self.presentInGlobalOverlay(actionSheet)
|
||||||
//self.present(actionSheet, in: .window(.root))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(iOSApplicationExtension 11.0, iOS 11.0, *)
|
@available(iOSApplicationExtension 11.0, iOS 11.0, *)
|
||||||
|
@ -11,13 +11,17 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView,
|
|||||||
}
|
}
|
||||||
var entries: [ChatHistoryEntry] = []
|
var entries: [ChatHistoryEntry] = []
|
||||||
var adminRanks: [PeerId: CachedChannelAdminRank] = [:]
|
var adminRanks: [PeerId: CachedChannelAdminRank] = [:]
|
||||||
|
var stickersEnabled = true
|
||||||
if case let .peer(peerId) = location, peerId.namespace == Namespaces.Peer.CloudChannel {
|
if case let .peer(peerId) = location, peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
for additionalEntry in view.additionalData {
|
for additionalEntry in view.additionalData {
|
||||||
if case let .cacheEntry(id, data) = additionalEntry {
|
if case let .cacheEntry(id, data) = additionalEntry {
|
||||||
if id == cachedChannelAdminRanksEntryId(peerId: peerId), let data = data as? CachedChannelAdminRanks {
|
if id == cachedChannelAdminRanksEntryId(peerId: peerId), let data = data as? CachedChannelAdminRanks {
|
||||||
adminRanks = data.ranks
|
adminRanks = data.ranks
|
||||||
}
|
}
|
||||||
break
|
} else if case let .peer(_, peer) = additionalEntry, let channel = peer as? TelegramChannel {
|
||||||
|
if let defaultBannedRights = channel.defaultBannedRights, defaultBannedRights.flags.contains(.banSendStickers) {
|
||||||
|
stickersEnabled = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,7 +46,7 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView,
|
|||||||
|
|
||||||
var contentTypeHint: ChatMessageEntryContentType = .generic
|
var contentTypeHint: ChatMessageEntryContentType = .generic
|
||||||
if presentationData.largeEmoji, entry.message.media.isEmpty {
|
if presentationData.largeEmoji, entry.message.media.isEmpty {
|
||||||
if entry.message.text.count == 1, let _ = associatedData.animatedEmojiStickers[entry.message.text.basicEmoji.0] {
|
if stickersEnabled && entry.message.text.count == 1, let _ = associatedData.animatedEmojiStickers[entry.message.text.basicEmoji.0] {
|
||||||
contentTypeHint = .animatedEmoji
|
contentTypeHint = .animatedEmoji
|
||||||
} else if messageIsElligibleForLargeEmoji(entry.message) {
|
} else if messageIsElligibleForLargeEmoji(entry.message) {
|
||||||
contentTypeHint = .largeEmoji
|
contentTypeHint = .largeEmoji
|
||||||
|
@ -405,10 +405,15 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if viewClassName == ChatMessageBubbleItemNode.self && self.presentationData.largeEmoji && self.message.media.isEmpty {
|
if viewClassName == ChatMessageBubbleItemNode.self && self.presentationData.largeEmoji && self.message.media.isEmpty {
|
||||||
if self.message.text.count == 1, let _ = self.associatedData.animatedEmojiStickers[self.message.text.basicEmoji.0] {
|
if case let .message(_, _, _, attributes) = self.content {
|
||||||
viewClassName = ChatMessageAnimatedStickerItemNode.self
|
switch attributes.contentTypeHint {
|
||||||
} else if messageIsElligibleForLargeEmoji(self.message) {
|
case .largeEmoji:
|
||||||
viewClassName = ChatMessageStickerItemNode.self
|
viewClassName = ChatMessageStickerItemNode.self
|
||||||
|
case .animatedEmoji:
|
||||||
|
viewClassName = ChatMessageAnimatedStickerItemNode.self
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
@ -31,7 +31,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
private let effectView: UIView
|
private let effectView: UIView
|
||||||
|
|
||||||
private let animationBackgroundColor: UIColor
|
private let animationBackgroundColor: UIColor
|
||||||
|
|
||||||
private var originalRemainingSeconds: Int
|
private var originalRemainingSeconds: Int
|
||||||
private var remainingSeconds: Int
|
private var remainingSeconds: Int
|
||||||
private var timer: SwiftSignalKit.Timer?
|
private var timer: SwiftSignalKit.Timer?
|
||||||
@ -261,7 +261,12 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
let firstLayout = self.validLayout == nil
|
let firstLayout = self.validLayout == nil
|
||||||
self.validLayout = layout
|
self.validLayout = layout
|
||||||
|
|
||||||
let leftInset: CGFloat = 50.0
|
var leftInset: CGFloat = 50.0
|
||||||
|
if let animationNode = self.animationNode, let iconSize = animationNode.preferredSize() {
|
||||||
|
if iconSize.width > leftInset {
|
||||||
|
leftInset = iconSize.width - 8.0
|
||||||
|
}
|
||||||
|
}
|
||||||
let rightInset: CGFloat = 16.0
|
let rightInset: CGFloat = 16.0
|
||||||
var contentHeight: CGFloat = 20.0
|
var contentHeight: CGFloat = 20.0
|
||||||
|
|
||||||
|
Binary file not shown.
@ -61,7 +61,7 @@ private enum WalletSendScreenEntry: ItemListNodeEntry {
|
|||||||
case address(WalletTheme, String, String)
|
case address(WalletTheme, String, String)
|
||||||
case addressInfo(WalletTheme, String)
|
case addressInfo(WalletTheme, String)
|
||||||
case commentHeader(WalletTheme, String)
|
case commentHeader(WalletTheme, String)
|
||||||
case comment(WalletTheme, String, String)
|
case comment(WalletTheme, String, String, Bool)
|
||||||
|
|
||||||
var section: ItemListSectionId {
|
var section: ItemListSectionId {
|
||||||
switch self {
|
switch self {
|
||||||
@ -131,8 +131,8 @@ private enum WalletSendScreenEntry: ItemListNodeEntry {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case let .comment(lhsTheme, lhsPlaceholder, lhsText):
|
case let .comment(lhsTheme, lhsPlaceholder, lhsText, lhsSendEnabled):
|
||||||
if case let .comment(rhsTheme, rhsPlaceholder, rhsText) = rhs, lhsTheme === rhsTheme, lhsPlaceholder == rhsPlaceholder, lhsText == rhsText {
|
if case let .comment(rhsTheme, rhsPlaceholder, rhsText, rhsSendEnabled) = rhs, lhsTheme === rhsTheme, lhsPlaceholder == rhsPlaceholder, lhsText == rhsText, lhsSendEnabled == rhsSendEnabled {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -245,7 +245,7 @@ private enum WalletSendScreenEntry: ItemListNodeEntry {
|
|||||||
return ItemListTextItem(theme: theme, text: .markdown(text), sectionId: self.section)
|
return ItemListTextItem(theme: theme, text: .markdown(text), sectionId: self.section)
|
||||||
case let .commentHeader(theme, text):
|
case let .commentHeader(theme, text):
|
||||||
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
||||||
case let .comment(theme, placeholder, value):
|
case let .comment(theme, placeholder, value, sendEnabled):
|
||||||
return ItemListMultilineInputItem(theme: theme, text: value, placeholder: placeholder, maxLength: ItemListMultilineInputItemTextLimit(value: walletTextLimit, display: true, mode: .bytes), sectionId: self.section, style: .blocks, returnKeyType: .send, textUpdated: { text in
|
return ItemListMultilineInputItem(theme: theme, text: value, placeholder: placeholder, maxLength: ItemListMultilineInputItemTextLimit(value: walletTextLimit, display: true, mode: .bytes), sectionId: self.section, style: .blocks, returnKeyType: .send, textUpdated: { text in
|
||||||
arguments.updateText(WalletSendScreenEntryTag.comment, text)
|
arguments.updateText(WalletSendScreenEntryTag.comment, text)
|
||||||
}, updatedFocus: { focus in
|
}, updatedFocus: { focus in
|
||||||
@ -253,7 +253,9 @@ private enum WalletSendScreenEntry: ItemListNodeEntry {
|
|||||||
arguments.scrollToBottom()
|
arguments.scrollToBottom()
|
||||||
}
|
}
|
||||||
}, tag: WalletSendScreenEntryTag.comment, action: {
|
}, tag: WalletSendScreenEntryTag.comment, action: {
|
||||||
arguments.proceed()
|
if sendEnabled {
|
||||||
|
arguments.proceed()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,7 +267,7 @@ private struct WalletSendScreenState: Equatable {
|
|||||||
var comment: String
|
var comment: String
|
||||||
}
|
}
|
||||||
|
|
||||||
private func walletSendScreenEntries(presentationData: WalletPresentationData, balance: Int64?, state: WalletSendScreenState) -> [WalletSendScreenEntry] {
|
private func walletSendScreenEntries(presentationData: WalletPresentationData, balance: Int64?, state: WalletSendScreenState, sendEnabled: Bool) -> [WalletSendScreenEntry] {
|
||||||
if balance == nil {
|
if balance == nil {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@ -281,7 +283,7 @@ private func walletSendScreenEntries(presentationData: WalletPresentationData, b
|
|||||||
entries.append(.addressInfo(presentationData.theme, presentationData.strings.Wallet_Send_AddressInfo))
|
entries.append(.addressInfo(presentationData.theme, presentationData.strings.Wallet_Send_AddressInfo))
|
||||||
|
|
||||||
entries.append(.commentHeader(presentationData.theme, presentationData.strings.Wallet_Receive_CommentHeader))
|
entries.append(.commentHeader(presentationData.theme, presentationData.strings.Wallet_Receive_CommentHeader))
|
||||||
entries.append(.comment(presentationData.theme, presentationData.strings.Wallet_Receive_CommentInfo, state.comment))
|
entries.append(.comment(presentationData.theme, presentationData.strings.Wallet_Receive_CommentInfo, state.comment, sendEnabled))
|
||||||
return entries
|
return entries
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,6 +376,10 @@ public func walletSendScreen(context: WalletContext, randomId: Int64, walletInfo
|
|||||||
let presentationData = context.presentationData
|
let presentationData = context.presentationData
|
||||||
let state = stateValue.with { $0 }
|
let state = stateValue.with { $0 }
|
||||||
let amount = amountValue(state.amount)
|
let amount = amountValue(state.amount)
|
||||||
|
guard amount > 0 else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let commentData = state.comment.data(using: .utf8)
|
let commentData = state.comment.data(using: .utf8)
|
||||||
let formattedAddress = String(state.address[state.address.startIndex..<state.address.index(state.address.startIndex, offsetBy: walletAddressLength / 2)] + " \n " + state.address[state.address.index(state.address.startIndex, offsetBy: walletAddressLength / 2)..<state.address.endIndex])
|
let formattedAddress = String(state.address[state.address.startIndex..<state.address.index(state.address.startIndex, offsetBy: walletAddressLength / 2)] + " \n " + state.address[state.address.index(state.address.startIndex, offsetBy: walletAddressLength / 2)..<state.address.endIndex])
|
||||||
let destinationAddress = state.address
|
let destinationAddress = state.address
|
||||||
@ -571,7 +577,7 @@ public func walletSendScreen(context: WalletContext, randomId: Int64, walletInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Wallet_Send_Title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Wallet_Navigation_Back), animateChanges: false)
|
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Wallet_Send_Title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Wallet_Navigation_Back), animateChanges: false)
|
||||||
let listState = ItemListNodeState(entries: walletSendScreenEntries(presentationData: presentationData, balance: walletState?.balance, state: state), style: .blocks, focusItemTag: focusItemTag, emptyStateItem: emptyItem, animateChanges: false)
|
let listState = ItemListNodeState(entries: walletSendScreenEntries(presentationData: presentationData, balance: walletState?.balance, state: state, sendEnabled: sendEnabled), style: .blocks, focusItemTag: focusItemTag, emptyStateItem: emptyItem, animateChanges: false)
|
||||||
|
|
||||||
return (controllerState, (listState, arguments))
|
return (controllerState, (listState, arguments))
|
||||||
}
|
}
|
||||||
|
@ -448,12 +448,12 @@ public final class WalletStrings: Equatable {
|
|||||||
public var Wallet_SecureStorageReset_Title: String { return self._s[218]! }
|
public var Wallet_SecureStorageReset_Title: String { return self._s[218]! }
|
||||||
public var Wallet_Receive_CommentHeader: String { return self._s[219]! }
|
public var Wallet_Receive_CommentHeader: String { return self._s[219]! }
|
||||||
public var Wallet_Info_ReceiveGrams: String { return self._s[220]! }
|
public var Wallet_Info_ReceiveGrams: String { return self._s[220]! }
|
||||||
public func Wallet_Updated_HoursAgo(_ value: Int32) -> String {
|
public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String {
|
||||||
let form = getPluralizationForm(self.lc, value)
|
let form = getPluralizationForm(self.lc, value)
|
||||||
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
||||||
return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue)
|
return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue)
|
||||||
}
|
}
|
||||||
public func Wallet_Updated_MinutesAgo(_ value: Int32) -> String {
|
public func Wallet_Updated_HoursAgo(_ value: Int32) -> String {
|
||||||
let form = getPluralizationForm(self.lc, value)
|
let form = getPluralizationForm(self.lc, value)
|
||||||
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
let stringValue = walletStringsFormattedNumber(value, self.groupingSeparator)
|
||||||
return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue)
|
return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user