Update localization

This commit is contained in:
Isaac 2025-04-09 18:21:11 +04:00
parent 5134cc2ff2
commit 700a71f393
28 changed files with 173 additions and 121 deletions

View File

@ -14115,3 +14115,68 @@ Sorry for the inconvenience.";
"WebApp.ImportData.AccountHeader" = "ACCOUNT TO IMPORT DATA FROM";
"WebApp.ImportData.CreatedOn" = "created on %@";
"WebApp.ImportData.Import" = "Import";
"CallList.ToastCallLinkCopied.Text" = "Call link copied";
"CallList.ToastCallLinkCopied.Action" = "View Call";
"CallList.NewCall" = "New Call";
"CallList.NewCallLink" = "New Call Link";
"Chat.SendStarsToBecomeTopInfo" = "Send %@ or more to highlight your profile";
"VideoChat.RevokeLink" = "Revoke Link";
"InviteLink.GroupCallLinkHelp" = "Anyone on Telegram can join your call by following the link below.";
"InviteLink.CallLinkTitle" = "Call Link";
"InviteLink.CreatedGroupCallFooter" = "Be the first to join the call and add people from there. [Open Call >](open_call)";
"InviteLink.QRCode.InfoGroupCall" = "Everyone on Telegram can scan this code to join your group call.";
"Call.GenericGroupCallTitle" = "Group Call";
"VideoChat.EncryptionKeyLabel" = "End-to-end encrypted";
"VideoChat.EncryptionKeyText" = "These four emojis represent the call's encryption key. They must match for all participants and change when someone joins or leaves.";
"VideoChat.EncryptionKeyDone" = "Close";
"VideoChat.InviteMember" = "Add Member";
"VideoChat.GroupCallTitle" = "Group Call";
"Chat.ViewGroupCall" = "JOIN GROUP CALL";
"NewCall.SearchPlaceholder" = "Search for contacts or usernames";
"NewCall.VideoOption" = "Call with video enabled";
"NewCall.ActionCallSingle" = "Call %@";
"NewCall.ActionCallMultiple" = "Call";
"Chat.ToastCallLinkExpired.Text" = "This link is no longer active";
"Chat.CallMessage.GroupCallParticipantCount_1" = "1 person";
"Chat.CallMessage.GroupCallParticipantCount_any" = "%d people";
"Chat.CallMessage.DeclinedGroupCall" = "Declined Group Call";
"Chat.CallMessage.MissedGroupCall" = "Missed Group Call";
"Chat.CallMessage.CancelledGroupCall" = "Cancelled Group Call";
"Chat.CallMessage.IncomingGroupCall" = "Incoming Group Call";
"Chat.CallMessage.OutgoingGroupCall" = "Outgoing Group Call";
"Invitation.GroupCall" = "Group Call";
"Invitation.JoinGroupCall" = "Join Group Call";
"Invitation.PublicGroup" = "public group";
"Invitation.PrivateGroup" = "private group";
"Invitation.GroupCall.Text" = "You are invited to join a group call.";
"Invitation.Group.AlreadyJoinedSingle" = "**%@** already joined this group.";
"Invitation.Group.AlreadyJoinedMultiple" = "%@ already joined this group.";
"Invitation.Group.AlreadyJoinedMultipleWithCount_1" = "{} and **%d** other person already joined this group.";
"Invitation.Group.AlreadyJoinedMultipleWithCount_any" = "{} and **%d** other people already joined this group.";
"Invitation.GroupCall.AlreadyJoinedSingle" = "**%@** already joined this call.";
"Invitation.GroupCall.AlreadyJoinedMultiple" = "%@ already joined this call.";
"Invitation.GroupCall.AlreadyJoinedMultipleWithCount_1" = "{} and **%d** other person already joined this call.";
"Invitation.GroupCall.AlreadyJoinedMultipleWithCount_any" = "{} and **%d** other people already joined this call.";
"Call.ShareLink" = "Share Call Link";
"Call.AddMemberTitle" = "Add Member";
"Call.IncomingGroupCallTitle.Single" = "%@";
"Call.IncomingGroupCallTitle.Multiple_1" = "{} and 1 other";
"Call.IncomingGroupCallTitle.Multiple_any" = "{} and %d others";

View File

@ -425,9 +425,8 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode {
isVideo = conferenceCall.flags.contains(.isVideo)
if message.flags.contains(.Incoming) {
hasIncoming = true
//TODO:localize
let missedTimeout: Int32
#if DEBUG
#if DEBUG && false
missedTimeout = 5
#else
missedTimeout = 30
@ -463,8 +462,7 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode {
peersString.append(", ")
}
if peer.id == item.context.account.peerId {
//TODO:localize
peersString += "You"
peersString += item.presentationData.strings.DialogList_You
} else {
peersString += peer.compactDisplayTitle
}

View File

@ -297,9 +297,8 @@ public final class CallListController: TelegramBaseController {
if let result {
switch result {
case .linkCopied:
//TODO:localize
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
self.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: "Call link copied.", customUndoText: "View Call", timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
self.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: presentationData.strings.CallList_ToastCallLinkCopied_Text, customUndoText: presentationData.strings.CallList_ToastCallLinkCopied_Action, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
if case .undo = action {
openCall()
}
@ -517,8 +516,7 @@ public final class CallListController: TelegramBaseController {
return
}
//TODO:localize
let options = [ContactListAdditionalOption(title: "New Call Link", icon: .generic(PresentationResourcesItemList.linkIcon(presentationData.theme)!), action: { [weak self] in
let options = [ContactListAdditionalOption(title: self.presentationData.strings.CallList_NewCallLink, icon: .generic(PresentationResourcesItemList.linkIcon(presentationData.theme)!), action: { [weak self] in
guard let self else {
return
}
@ -741,8 +739,7 @@ public final class CallListController: TelegramBaseController {
self.context.sharedContext.openCreateGroupCallUI(context: self.context, peerIds: conferenceCall.otherParticipants, parentController: self)
default:
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
self.present(textAlertController(context: self.context, title: nil, text: "An error occurred", actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(textAlertController(context: self.context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}
})
}

View File

@ -126,8 +126,7 @@ private func mappedInsertEntries(context: AccountContext, presentationData: Item
case let .displayTabInfo(_, text):
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint)
case .openNewCall:
//TODO:localize
let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: .none, title: "New Call", hasSeparator: false, sectionId: 1, height: .generic, noInsets: true, editing: false, action: {
let item = ItemListPeerActionItem(presentationData: presentationData, style: showSettings ? .blocks : .plain, icon: .none, title: presentationData.strings.CallList_NewCall, hasSeparator: false, sectionId: 1, height: .generic, noInsets: true, editing: false, action: {
nodeInteraction.openNewCall()
})
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint)
@ -151,8 +150,7 @@ private func mappedUpdateEntries(context: AccountContext, presentationData: Item
case let .displayTabInfo(_, text):
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint)
case .openNewCall:
//TODO:localize
let item = ItemListPeerActionItem(presentationData: presentationData, icon: .none, title: "New Call", sectionId: 1, height: .generic, noInsets: true, editing: false, action: {
let item = ItemListPeerActionItem(presentationData: presentationData, icon: .none, title: presentationData.strings.CallList_NewCall, sectionId: 1, height: .generic, noInsets: true, editing: false, action: {
nodeInteraction.openNewCall()
})
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: item, directionHint: entry.directionHint)

View File

@ -298,9 +298,25 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder:
messageText = invoice.title
case let action as TelegramMediaAction:
switch action.action {
case .conferenceCall:
//TODO:localize
messageText = "Group call"
case let .conferenceCall(conferenceCall):
let incoming = message.flags.contains(.Incoming)
let missedTimeout: Int32 = 30
let currentTime = Int32(Date().timeIntervalSince1970)
if conferenceCall.flags.contains(.isMissed) {
messageText = strings.Chat_CallMessage_DeclinedGroupCall
} else if message.timestamp < currentTime - missedTimeout {
messageText = strings.Chat_CallMessage_MissedGroupCall
} else if conferenceCall.duration != nil {
messageText = strings.Chat_CallMessage_CancelledGroupCall
} else {
if incoming {
messageText = strings.Chat_CallMessage_IncomingGroupCall
} else {
messageText = strings.Chat_CallMessage_OutgoingGroupCall
}
}
case let .phoneCall(_, discardReason, _, isVideo):
hideAuthor = !isPeerGroup
let incoming = message.flags.contains(.Incoming)

View File

@ -438,9 +438,8 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
icon = nil
isUserInteractionEnabled = action != nil
case let .starsReactions(topCount):
//TODO:localize
self.action = nil
self.text = "Send \(topCount) or more to highlight your profile"
self.text = self.presentationData.strings.Chat_SendStarsToBecomeTopInfo("\(topCount)").string
self.targetSelectionIndex = nil
icon = nil
isUserInteractionEnabled = action != nil

View File

@ -492,10 +492,9 @@ public final class InviteLinkInviteController: ViewController {
let dismissAction: () -> Void = { [weak controller] in
controller?.dismissAnimated()
}
//TODO:localize
controller.setItemGroups([
ActionSheetItemGroup(items: [
ActionSheetTextItem(title: "Revoke Link"),
ActionSheetTextItem(title: presentationData.strings.VideoChat_RevokeLink),
ActionSheetButtonItem(title: presentationData.strings.GroupInfo_InviteLink_RevokeLink, color: .destructive, action: { [weak self] in
dismissAction()
@ -674,9 +673,8 @@ public final class InviteLinkInviteController: ViewController {
}
var entries: [InviteLinkInviteEntry] = []
//TODO:localize
let helpText: String = "Anyone on Telegram can join your call by following the link below."
entries.append(.header(title: "Call Link", text: helpText))
let helpText: String = presentationData.strings.InviteLink_GroupCallLinkHelp
entries.append(.header(title: presentationData.strings.InviteLink_CallLinkTitle, text: helpText))
let mainInvite: ExportedInvitation = .link(link: mainInvite?.link ?? "", title: nil, isPermanent: true, requestApproval: false, isRevoked: false, adminId: self.context.account.peerId, date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil, requestedCount: nil, pricing: nil)

View File

@ -369,8 +369,7 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem
return (TelegramTextAttributes.URL, contents)
}
)
//TODO:localize
let justCreatedCallTextAttributedString = parseMarkdownIntoAttributedString("Be the first to join the call and add people from there. [Open Call >](open_call)", attributes: markdownAttributes).mutableCopy() as! NSMutableAttributedString
let justCreatedCallTextAttributedString = parseMarkdownIntoAttributedString(item.presentationData.strings.InviteLink_CreatedGroupCallFooter, attributes: markdownAttributes).mutableCopy() as! NSMutableAttributedString
if let range = justCreatedCallTextAttributedString.string.range(of: ">"), let chevronImage {
justCreatedCallTextAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: justCreatedCallTextAttributedString.string))
}

View File

@ -193,9 +193,7 @@ public func JoinLinkPreviewController(
) -> ViewController {
if let data = context.currentAppConfiguration.with({ $0 }).data, data["ios_killswitch_legacy_join_link"] != nil {
return LegacyJoinLinkPreviewController(context: context, link: link, navigateToPeer: navigateToPeer, parentNavigationController: parentNavigationController, resolvedState: resolvedState)
} else if case let .invite(invite) = resolvedState, !invite.flags.requestNeeded, !invite.flags.isBroadcast, !invite.flags.canRefulfillSubscription {
//TODO:release
} else if case let .invite(invite) = resolvedState, !invite.flags.requestNeeded, !invite.flags.isBroadcast, !invite.flags.canRefulfillSubscription {
var verificationStatus: JoinSubjectScreenMode.Group.VerificationStatus?
if invite.flags.isFake {
verificationStatus = .fake

View File

@ -253,8 +253,7 @@ public final class QrCodeScreen: ViewController {
case .channel:
text = self.presentationData.strings.InviteLink_QRCode_InfoChannel
case .groupCall:
//TODO:localize
text = "Everyone on Telegram can scan this code to join your group call."
text = self.presentationData.strings.InviteLink_QRCode_InfoGroupCall
}
case .chatFolder:
title = self.presentationData.strings.InviteLink_QRCodeFolder_Title

View File

@ -498,14 +498,12 @@ public final class CallController: ViewController {
}
static func openConferenceAddParticipant(context: AccountContext, disablePeerIds: [EnginePeer.Id], shareLink: (() -> Void)?, completion: @escaping ([(id: EnginePeer.Id, isVideo: Bool)]) -> Void) -> ViewController {
//TODO:localize
let presentationData = context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme)
var options: [ContactListAdditionalOption] = []
var openShareLinkImpl: (() -> Void)?
if shareLink != nil {
//TODO:localize
options.append(ContactListAdditionalOption(title: "Share Call Link", icon: .generic(UIImage(bundleImageName: "Contact List/LinkActionIcon")!), action: {
options.append(ContactListAdditionalOption(title: presentationData.strings.Call_ShareLink, icon: .generic(UIImage(bundleImageName: "Contact List/LinkActionIcon")!), action: {
openShareLinkImpl?()
}, clearHighlightAutomatically: false))
}
@ -515,8 +513,7 @@ public final class CallController: ViewController {
updatedPresentationData: (initial: presentationData, signal: .single(presentationData)),
mode: .generic,
title: { strings in
//TODO:localize
return "Add Member"
return strings.Call_AddMemberTitle
},
options: .single(options),
displayCallIcons: true,

View File

@ -765,8 +765,8 @@ public final class PresentationCallImpl: PresentationCall {
self.localVideoEndpointId = nil
self.remoteVideoEndpointId = nil
//TODO:localize
self.callKitIntegration?.updateCallIsConference(uuid: self.internalId, title: self.conferenceTitle ?? "Group Call")
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
self.callKitIntegration?.updateCallIsConference(uuid: self.internalId, title: self.conferenceTitle ?? presentationData.strings.Call_GenericGroupCallTitle)
}
func internal_markAsCanBeRemoved() {

View File

@ -3568,8 +3568,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
let presentationData = self.accountContext.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: defaultDarkColorPresentationTheme)
//TODO:localize
var errorText = "An error occurred"
var errorText = presentationData.strings.Login_UnknownError
switch error {
case let .privacy(peer):
if let peer {

View File

@ -614,11 +614,10 @@ final class VideoChatEncryptionKeyComponent: Component {
)
}
//TODO:localize
let collapsedTextSize = self.collapsedText.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: "End-to-end encrypted", font: Font.semibold(12.0), textColor: component.theme.list.itemPrimaryTextColor))
text: .plain(NSAttributedString(string: component.strings.VideoChat_EncryptionKeyLabel, font: Font.semibold(12.0), textColor: component.theme.list.itemPrimaryTextColor))
)),
environment: {},
containerSize: CGSize(width: 1000.0, height: 1000.0)
@ -627,7 +626,7 @@ final class VideoChatEncryptionKeyComponent: Component {
let expandedTextSize = self.expandedText.update(
transition: .immediate,
component: AnyComponent(BalancedTextComponent(
text: .plain(NSAttributedString(string: "These four emojis represent the call's encryption key. They must match for all participants and change when someone joins or leaves.", font: Font.regular(12.0), textColor: component.theme.list.itemPrimaryTextColor)),
text: .plain(NSAttributedString(string: component.strings.VideoChat_EncryptionKeyText, font: Font.regular(12.0), textColor: component.theme.list.itemPrimaryTextColor)),
maximumNumberOfLines: 0,
lineSpacing: 0.3
)),
@ -638,7 +637,7 @@ final class VideoChatEncryptionKeyComponent: Component {
let expandedButtonTextSize = self.expandedButtonText.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: "Close", font: Font.regular(17.0), textColor: component.theme.list.itemPrimaryTextColor))
text: .plain(NSAttributedString(string: component.strings.VideoChat_EncryptionKeyDone, font: Font.regular(17.0), textColor: component.theme.list.itemPrimaryTextColor))
)),
environment: {},
containerSize: CGSize(width: availableSize.width - expandedSideInset * 2.0, height: 1000.0)

View File

@ -1282,18 +1282,7 @@ final class VideoChatParticipantsComponent: Component {
let invitedPeer = component.invitedPeers[i - self.listParticipants.count]
participantPeerId = invitedPeer.peer.id
let subtitle: PeerListItemComponent.Subtitle
//TODO:localize
switch invitedPeer.state {
case .none:
subtitle = PeerListItemComponent.Subtitle(text: component.strings.VoiceChat_StatusInvited, color: .neutral)
case .connecting:
subtitle = PeerListItemComponent.Subtitle(text: "connecting...", color: .neutral)
case .requesting:
subtitle = PeerListItemComponent.Subtitle(text: "requesting...", color: .neutral)
case .ringing:
subtitle = PeerListItemComponent.Subtitle(text: "invited", color: .neutral)
}
let subtitle: PeerListItemComponent.Subtitle = PeerListItemComponent.Subtitle(text: component.strings.VoiceChat_StatusInvited, color: .neutral)
let rightAccessoryComponent: AnyComponent<Empty> = AnyComponent(VideoChatParticipantInvitedStatusComponent(
theme: component.theme
@ -1861,11 +1850,10 @@ final class VideoChatParticipantsComponent: Component {
let iconType: VideoChatListInviteComponent.Icon
switch inviteOption.type {
case let .invite(isMultiple):
//TODO:localize
if isMultiple {
inviteText = component.strings.VoiceChat_InviteMember
} else {
inviteText = "Add Member"
inviteText = component.strings.VideoChat_InviteMember
}
iconType = .addUser
case .shareLink:

View File

@ -685,9 +685,8 @@ final class VideoChatScreenComponent: Component {
if let result {
switch result {
case .linkCopied:
//TODO:localize
let presentationData = groupCall.accountContext.sharedContext.currentPresentationData.with { $0 }
self.environment?.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: "Call link copied.", customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
self.environment?.controller()?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: presentationData.strings.CallList_ToastCallLinkCopied_Text, customUndoText: presentationData.strings.CallList_ToastCallLinkCopied_Action, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
return false
}), in: .current)
case .openCall:
@ -2038,11 +2037,10 @@ final class VideoChatScreenComponent: Component {
maxTitleWidth -= 110.0
}
//TODO:localize
let titleSize = self.title.update(
transition: transition,
component: AnyComponent(VideoChatTitleComponent(
title: self.callState?.title ?? self.peer?.debugDisplayTitle ?? "Group Call",
title: self.callState?.title ?? self.peer?.debugDisplayTitle ?? environment.strings.VideoChat_GroupCallTitle,
status: idleTitleStatusText,
isRecording: self.callState?.recordingStartTimestamp != nil,
strings: environment.strings,

View File

@ -129,7 +129,6 @@ extension VideoChatScreenComponent.View {
if let participant {
dismissController?()
//TODO:release
if groupCall.invitePeer(participant.peer.id, isVideo: false) {
let text: String
if case let .channel(channel) = self.peer, case .broadcast = channel.info {
@ -242,7 +241,6 @@ extension VideoChatScreenComponent.View {
}
dismissController?()
//TODO:release
if groupCall.invitePeer(peer.id, isVideo: false) {
let text: String
if case let .channel(channel) = self.peer, case .broadcast = channel.info {
@ -315,7 +313,6 @@ extension VideoChatScreenComponent.View {
}
dismissController?()
//TODO:release
if groupCall.invitePeer(peer.id, isVideo: false) {
let text: String
if case let .channel(channel) = self.peer, case .broadcast = channel.info {

View File

@ -1256,7 +1256,6 @@ final class VoiceChatControllerImpl: ViewController, VoiceChatController {
if let participant = participant {
dismissController?()
//TODO:release
if strongSelf.call.invitePeer(participant.peer.id, isVideo: false) {
let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
@ -1365,7 +1364,6 @@ final class VoiceChatControllerImpl: ViewController, VoiceChatController {
}
dismissController?()
//TODO:release
if strongSelf.call.invitePeer(peer.id, isVideo: false) {
let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
@ -1434,7 +1432,6 @@ final class VoiceChatControllerImpl: ViewController, VoiceChatController {
}
dismissController?()
//TODO:release
if strongSelf.call.invitePeer(peer.id, isVideo: false) {
let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {

View File

@ -182,7 +182,6 @@ public final class ConferenceCallE2EContext {
self.e2eEncryptionKeyHashValue.set(outEmoji.isEmpty ? nil : outEmoji)
for outBlock in outBlocks {
//TODO:release queue
let _ = self.engine.calls.sendConferenceCallBroadcast(callId: self.callId, accessHash: self.accessHash, block: outBlock).startStandalone()
}
}
@ -400,7 +399,6 @@ public final class ConferenceCallE2EContext {
}
func kickPeer(id: EnginePeer.Id) {
//TODO:release
if !self.pendingKickPeers.contains(id) {
self.pendingKickPeers.append(id)

View File

@ -616,9 +616,27 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
}
}
attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor)
case .conferenceCall:
//TODO:localize
let titleString = "Group call"
case let .conferenceCall(conferenceCall):
var titleString: String
let incoming = message.flags.contains(.Incoming)
let missedTimeout: Int32 = 30
let currentTime = Int32(Date().timeIntervalSince1970)
if conferenceCall.flags.contains(.isMissed) {
titleString = strings.Chat_CallMessage_DeclinedGroupCall
} else if message.timestamp < currentTime - missedTimeout {
titleString = strings.Chat_CallMessage_MissedGroupCall
} else if conferenceCall.duration != nil {
titleString = strings.Chat_CallMessage_CancelledGroupCall
} else {
if incoming {
titleString = strings.Chat_CallMessage_IncomingGroupCall
} else {
titleString = strings.Chat_CallMessage_OutgoingGroupCall
}
}
attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor)
case let .groupPhoneCall(_, _, scheduleDate, duration):
if let scheduleDate = scheduleDate {

View File

@ -153,8 +153,7 @@ public class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode {
callDuration = conferenceCall.duration
if conferenceCall.otherParticipants.count > 0 {
//TODO:localize
peopleTextString = "\(conferenceCall.otherParticipants.count + 1) people"
peopleTextString = item.presentationData.strings.Chat_CallMessage_GroupCallParticipantCount(Int32(conferenceCall.otherParticipants.count + 1))
if let peer = item.message.author {
peopleAvatars.append(peer)
}
@ -165,9 +164,8 @@ public class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode {
}
}
//TODO:localize
let missedTimeout: Int32
#if DEBUG
#if DEBUG && false
missedTimeout = 5
#else
missedTimeout = 30
@ -175,16 +173,16 @@ public class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode {
let currentTime = Int32(Date().timeIntervalSince1970)
if conferenceCall.flags.contains(.isMissed) {
titleString = "Declined Group Call"
titleString = item.presentationData.strings.Chat_CallMessage_DeclinedGroupCall
} else if item.message.timestamp < currentTime - missedTimeout {
titleString = "Missed Group Call"
titleString = item.presentationData.strings.Chat_CallMessage_MissedGroupCall
} else if conferenceCall.duration != nil {
titleString = "Cancelled Group Call"
titleString = item.presentationData.strings.Chat_CallMessage_CancelledGroupCall
} else {
if incoming {
titleString = "Incoming Group Call"
titleString = item.presentationData.strings.Chat_CallMessage_IncomingGroupCall
} else {
titleString = "Outgoing Group Call"
titleString = item.presentationData.strings.Chat_CallMessage_OutgoingGroupCall
}
updateConferenceTimerEndTimeout = (item.message.timestamp + missedTimeout) - currentTime
}

View File

@ -475,8 +475,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
text = nil
entities = nil
case "telegram_call":
//TODO:localize
actionTitle = "JOIN GROUP CALL"
actionTitle = item.presentationData.strings.Chat_ViewGroupCall
default:
break
}

View File

@ -490,7 +490,7 @@ private final class JoinSubjectScreenComponent: Component {
contentHeight += 31.0
titleString = group.title
subtitleString = group.isPublic ? "public group" : "private group"
subtitleString = group.isPublic ? environment.strings.Invitation_PublicGroup : environment.strings.Invitation_PrivateGroup
descriptionTextString = group.about
previewPeers = group.members
@ -528,10 +528,9 @@ private final class JoinSubjectScreenComponent: Component {
}
contentHeight += peerAvatarSize.height + 21.0
case let .groupCall(groupCall):
//TODO:localize
titleString = "Group Call"
titleString = environment.strings.Invitation_GroupCall
subtitleString = nil
descriptionTextString = "You are invited to join a group call."
descriptionTextString = environment.strings.Invitation_GroupCall_Text
previewPeers = groupCall.members
totalMemberCount = groupCall.totalMemberCount
@ -691,12 +690,11 @@ private final class JoinSubjectScreenComponent: Component {
if !previewPeers.isEmpty {
contentHeight += 11.0
//TODO:localize
let previewPeersString: String
switch component.mode {
case .group:
if previewPeers.count == 1 {
previewPeersString = "**\(previewPeers[0].compactDisplayTitle)** already joined this group."
previewPeersString = environment.strings.Invitation_Group_AlreadyJoinedSingle(previewPeers[0].compactDisplayTitle).string
} else {
let firstPeers = previewPeers.prefix(upTo: 2)
let peersTextArray = firstPeers.map { "**\($0.compactDisplayTitle)**" }
@ -717,14 +715,14 @@ private final class JoinSubjectScreenComponent: Component {
}
}
if totalMemberCount > firstPeers.count {
previewPeersString = "\(peersText) and **\(totalMemberCount - firstPeers.count)** other people already joined this group."
previewPeersString = environment.strings.Invitation_Group_AlreadyJoinedMultipleWithCount(Int32(totalMemberCount - firstPeers.count)).replacingOccurrences(of: "{}", with: peersText)
} else {
previewPeersString = "\(peersText) already joined this group."
previewPeersString = environment.strings.Invitation_Group_AlreadyJoinedMultiple(peersText).string
}
}
case .groupCall:
if previewPeers.count == 1 {
previewPeersString = "**\(previewPeers[0].compactDisplayTitle)** already joined this call."
previewPeersString = environment.strings.Invitation_GroupCall_AlreadyJoinedSingle(previewPeers[0].compactDisplayTitle).string
} else {
let firstPeers = previewPeers.prefix(upTo: 2)
let peersTextArray = firstPeers.map { "**\($0.compactDisplayTitle)**" }
@ -745,9 +743,9 @@ private final class JoinSubjectScreenComponent: Component {
}
}
if totalMemberCount > firstPeers.count {
previewPeersString = "\(peersText) and **\(totalMemberCount - firstPeers.count)** other people already joined this call."
previewPeersString = environment.strings.Invitation_GroupCall_AlreadyJoinedMultipleWithCount(Int32(totalMemberCount - firstPeers.count)).replacingOccurrences(of: "{}", with: peersText)
} else {
previewPeersString = "\(peersText) already joined this call."
previewPeersString = environment.strings.Invitation_GroupCall_AlreadyJoinedMultiple(peersText).string
}
}
}
@ -854,8 +852,7 @@ private final class JoinSubjectScreenComponent: Component {
case .group:
actionButtonTitle = environment.strings.Invitation_JoinGroup
case .groupCall:
//TODO:localize
actionButtonTitle = "Join Group Call"
actionButtonTitle = environment.strings.Invitation_JoinGroupCall
}
let actionButtonSize = self.actionButton.update(
transition: transition,

View File

@ -2164,14 +2164,18 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
let internalId = CallSessionManager.getStableIncomingUUID(peerId: fromPeerId.id._internalGetInt64Value(), messageId: messageId.id)
//TODO:localize
var displayTitle = "\(fromTitle)"
var strings: PresentationStrings = defaultPresentationStrings
let _ = (self.sharedContextPromise.get()
|> take(1)
|> deliverOnMainQueue).start(next: { sharedApplicationContext in
strings = sharedApplicationContext.sharedContext.currentPresentationData.with { $0.strings }
})
let displayTitle: String
if let memberCountString = payloadJson["member_count"] as? String, let memberCount = Int(memberCountString) {
if memberCount == 1 {
displayTitle.append(" and 1 other")
} else {
displayTitle.append(" and \(memberCount) others")
}
displayTitle = strings.Call_IncomingGroupCallTitle_Multiple(Int32(memberCount)).replacingOccurrences(of: "{}", with: fromTitle)
} else {
displayTitle = strings.Call_IncomingGroupCallTitle_Single(fromTitle).string
}
callKitIntegration.reportIncomingCall(

View File

@ -2932,8 +2932,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.context.sharedContext.openCreateGroupCallUI(context: self.context, peerIds: conferenceCall.otherParticipants, parentController: self)
default:
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
//TODO:localize
self.present(textAlertController(context: self.context, title: nil, text: "An error occurred", actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
self.present(textAlertController(context: self.context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}
})
}, longTap: { [weak self] action, params in

View File

@ -131,11 +131,10 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
}, checkOptionTitle: nil)
case let .groupCreation(isCall):
if isCall {
//TODO:localize
placeholder = "Search for contacts or usernames"
placeholder = self.presentationData.strings.NewCall_SearchPlaceholder
self.footerPanelNode = FooterPanelNode(theme: self.presentationData.theme, strings: self.presentationData.strings, action: {
proceedImpl?()
}, checkOptionTitle: isCall ? "Call with video enabled" : nil)
}, checkOptionTitle: self.presentationData.strings.NewCall_VideoOption)
} else {
placeholder = self.presentationData.strings.Compose_TokenListPlaceholder
self.footerPanelNode = nil
@ -483,15 +482,14 @@ final class ContactMultiselectionControllerNode: ASDisplayNode {
count = contactListNode.selectionState?.selectedPeerIndices.count ?? 0
}
if case let .groupCreation(isCall) = self.mode, isCall {
//TODO:localize
if count == 0 {
// Don't set anything to prevent state update
} else if count <= 1 {
let callTitle: String
if case let .contacts(contactListNode) = self.contentNode, let peer = contactListNode.selectedPeers.first, case let .peer(peer, _, _) = peer {
callTitle = "Call \(EnginePeer(peer).compactDisplayTitle)"
callTitle = self.presentationData.strings.NewCall_ActionCallSingle(EnginePeer(peer).compactDisplayTitle).string
} else {
callTitle = "Call"
callTitle = self.presentationData.strings.NewCall_ActionCallMultiple
}
footerPanelNode.content = FooterPanelNode.Content(title: callTitle, badge: "")
} else {

View File

@ -407,8 +407,7 @@ func openResolvedUrlImpl(
if case .chat = urlContext {
elevatedLayout = false
}
//TODO:localize
present(UndoOverlayController(presentationData: presentationData, content: .linkRevoked(text: "This link is no longer active"), elevatedLayout: elevatedLayout, animateInAsReplacement: false, action: { _ in
present(UndoOverlayController(presentationData: presentationData, content: .linkRevoked(text: presentationData.strings.Chat_ToastCallLinkExpired_Text), elevatedLayout: elevatedLayout, animateInAsReplacement: false, action: { _ in
return true
}), nil)
})

View File

@ -1962,10 +1962,11 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return
}
let isVideo = controller?.isCallVideoOptionSelected ?? false
if peerIds.count == 1 {
//TODO:release isVideo
controller?.dismiss()
self.performCall(context: context, parentController: parentController, peerId: peerIds[0], isVideo: false, began: {
self.performCall(context: context, parentController: parentController, peerId: peerIds[0], isVideo: isVideo, began: {
let _ = (context.sharedContext.hasOngoingCall.get()
|> filter { $0 }
|> timeout(1.0, queue: Queue.mainQueue(), alternate: .single(true))
@ -1980,7 +1981,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
})
})
} else {
self.createGroupCall(context: context, parentController: parentController, peerIds: peerIds, completion: {
self.createGroupCall(context: context, parentController: parentController, peerIds: peerIds, isVideo: isVideo, completion: {
controller?.dismiss()
})
}
@ -2011,7 +2012,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
})
}
private func createGroupCall(context: AccountContext, parentController: ViewController, peerIds: [EnginePeer.Id], completion: (() -> Void)? = nil) {
private func createGroupCall(context: AccountContext, parentController: ViewController, peerIds: [EnginePeer.Id], isVideo: Bool, completion: (() -> Void)? = nil) {
parentController.view.endEditing(true)
var cancelImpl: (() -> Void)?
@ -2057,7 +2058,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
isStream: false
),
reference: .id(id: call.callInfo.id, accessHash: call.callInfo.accessHash),
beginWithVideo: false,
beginWithVideo: isVideo,
invitePeerIds: peerIds
)
completion?()
@ -2079,9 +2080,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
if let result {
switch result {
case .linkCopied:
//TODO:localize
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
parentController.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: "Call link copied.", customUndoText: "View Call", timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
parentController.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_linkcopied", scale: 0.08, colors: ["info1.info1.stroke": UIColor.clear, "info2.info2.Fill": UIColor.clear], title: nil, text: presentationData.strings.CallList_ToastCallLinkCopied_Text, customUndoText: presentationData.strings.CallList_ToastCallLinkCopied_Action, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
if case .undo = action {
openCall()
}