Update localization

This commit is contained in:
Ali 2021-08-30 17:40:04 +04:00
parent 9a848cf51c
commit 66fe378a07
14 changed files with 327 additions and 58 deletions

View File

@ -2480,11 +2480,15 @@ Unused sets are archived when you add more.";
"Call.CallInProgressTitle" = "Call in Progress"; "Call.CallInProgressTitle" = "Call in Progress";
"Call.CallInProgressMessage" = "Finish call with %1$@ and start a new one with %2$@?"; "Call.CallInProgressMessage" = "Finish call with %1$@ and start a new one with %2$@?";
"Call.CallInProgressVoiceChatMessage" = "Finish call with %1$@ and start a voice chat with %2$@?"; "Call.CallInProgressVoiceChatMessage" = "Finish call with %1$@ and start a voice chat with %2$@?";
"Call.CallInProgressLiveStreamMessage" = "Finish call with %1$@ and start a live stream with %2$@?";
"Call.ExternalCallInProgressMessage" = "Please finish the current call first."; "Call.ExternalCallInProgressMessage" = "Please finish the current call first.";
"Call.VoiceChatInProgressTitle" = "Voice Chat in Progress"; "Call.VoiceChatInProgressTitle" = "Voice Chat in Progress";
"Call.LiveStreamInProgressTitle" = "Live Stream in Progress";
"Call.VoiceChatInProgressMessage" = "Leave voice chat in %1$@ and start a new one with %2$@?"; "Call.VoiceChatInProgressMessage" = "Leave voice chat in %1$@ and start a new one with %2$@?";
"Call.LiveStreamInProgressMessage" = "Leave live stream in %1$@ and start a new one with %2$@?";
"Call.VoiceChatInProgressCallMessage" = "Leave voice chat in %1$@ and start a call with %2$@?"; "Call.VoiceChatInProgressCallMessage" = "Leave voice chat in %1$@ and start a call with %2$@?";
"Call.LiveStreamInProgressCallMessage" = "Leave live stream in %1$@ and start a call with %2$@?";
"Call.Message" = "Message"; "Call.Message" = "Message";
@ -2618,6 +2622,7 @@ Unused sets are archived when you add more.";
"Channel.AdminLog.CanBeAnonymous" = "Remain Anonymous"; "Channel.AdminLog.CanBeAnonymous" = "Remain Anonymous";
"Channel.AdminLog.CanEditMessages" = "Edit Messages"; "Channel.AdminLog.CanEditMessages" = "Edit Messages";
"Channel.AdminLog.CanManageCalls" = "Manage Voice Chats"; "Channel.AdminLog.CanManageCalls" = "Manage Voice Chats";
"Channel.AdminLog.CanManageLiveStreams" = "Manage Live Streams";
"Channel.AdminLog.MessageToggleInvitesOn" = "%@ enabled group invites"; "Channel.AdminLog.MessageToggleInvitesOn" = "%@ enabled group invites";
"Channel.AdminLog.MessageToggleInvitesOff" = "%@ disabled group invites"; "Channel.AdminLog.MessageToggleInvitesOff" = "%@ disabled group invites";
@ -2676,6 +2681,7 @@ Unused sets are archived when you add more.";
"Channel.AdminLogFilter.EventsPinned" = "Pinned Messages"; "Channel.AdminLogFilter.EventsPinned" = "Pinned Messages";
"Channel.AdminLogFilter.EventsLeaving" = "Members Removed"; "Channel.AdminLogFilter.EventsLeaving" = "Members Removed";
"Channel.AdminLogFilter.EventsCalls" = "Voice Chats"; "Channel.AdminLogFilter.EventsCalls" = "Voice Chats";
"Channel.AdminLogFilter.EventsLiveStreams" = "Live Streams";
"Channel.AdminLogFilter.EventsInviteLinks" = "Invite Links"; "Channel.AdminLogFilter.EventsInviteLinks" = "Invite Links";
"Channel.AdminLogFilter.AdminsTitle" = "ADMINS"; "Channel.AdminLogFilter.AdminsTitle" = "ADMINS";
"Channel.AdminLogFilter.AdminsAll" = "All Admins"; "Channel.AdminLogFilter.AdminsAll" = "All Admins";
@ -5708,6 +5714,7 @@ Sorry for the inconvenience.";
"VoiceChat.SpeakPermissionAdmin" = "New paricipants are muted"; "VoiceChat.SpeakPermissionAdmin" = "New paricipants are muted";
"VoiceChat.Share" = "Share Invite Link"; "VoiceChat.Share" = "Share Invite Link";
"VoiceChat.EndVoiceChat" = "End Voice Chat"; "VoiceChat.EndVoiceChat" = "End Voice Chat";
"VoiceChat.EndLiveStream" = "End Live Stream";
"VoiceChat.CopyInviteLink" = "Copy Invite Link"; "VoiceChat.CopyInviteLink" = "Copy Invite Link";
"VoiceChat.InviteLinkCopiedText" = "Invite link copied to clipboard"; "VoiceChat.InviteLinkCopiedText" = "Invite link copied to clipboard";
@ -5723,16 +5730,17 @@ Sorry for the inconvenience.";
"VoiceChatChannel.Title" = "Live Stream"; "VoiceChatChannel.Title" = "Live Stream";
"VoiceChat.InviteMember" = "Invite Member"; "VoiceChat.InviteMember" = "Invite Member";
"VoiceChat.UserInvited" = "You invited **%@** to the voice chat";
"Notification.VoiceChatInvitation" = "%1$@ invited %2$@ to the voice chat"; "Notification.VoiceChatInvitation" = "%1$@ invited %2$@ to the voice chat";
"Notification.VoiceChatInvitationForYou" = "%1$@ invited you to the voice chat"; "Notification.VoiceChatInvitationForYou" = "%1$@ invited you to the voice chat";
"VoiceChat.InvitedPeerText" = "You invited %@ to the voice chat"; "VoiceChat.InvitedPeerText" = "You invited %@ to the voice chat";
"LiveStream.InvitedPeerText" = "You invited %@ to the live stream";
"VoiceChat.RemovedPeerText" = "You removed %@ from this group"; "VoiceChat.RemovedPeerText" = "You removed %@ from this group";
"Notification.VoiceChatStarted" = "%1$@ started a voice chat"; "Notification.VoiceChatStarted" = "%1$@ started a voice chat";
"Notification.VoiceChatEnded" = "Voice chat ended (%@)"; "Notification.VoiceChatEnded" = "Voice chat ended (%@)";
"Notification.LiveStreamEnded" = "Live stream ended (%@)";
"Notification.VoiceChatEndedGroup" = "%1$@ ended the voice chat (%2$@)"; "Notification.VoiceChatEndedGroup" = "%1$@ ended the voice chat (%2$@)";
"VoiceChat.Panel.TapToJoin" = "Tap to join"; "VoiceChat.Panel.TapToJoin" = "Tap to join";
@ -5752,12 +5760,17 @@ Sorry for the inconvenience.";
"VoiceChat.Status.MembersFormat" = "%1$@ %2$@"; "VoiceChat.Status.MembersFormat" = "%1$@ %2$@";
"ChannelInfo.CreateVoiceChat" = "Start Voice Chat"; "ChannelInfo.CreateVoiceChat" = "Start Voice Chat";
"ChannelInfo.CreateLiveStream" = "Start Live Stream";
"VoiceChat.AnonymousDisabledAlertText" = "Sorry, you can't join voice chat as an anonymous admin."; "VoiceChat.AnonymousDisabledAlertText" = "Sorry, you can't join voice chat as an anonymous admin.";
"LiveStream.AnonymousDisabledAlertText" = "Sorry, you can't join live stream as an anonymous admin.";
"VoiceChat.ChatFullAlertText" = "Sorry, this voice chat has too many participants at the moment."; "VoiceChat.ChatFullAlertText" = "Sorry, this voice chat has too many participants at the moment.";
"LiveStream.ChatFullAlertText" = "Sorry, this live stream has too many participants at the moment.";
"VoiceChat.EndConfirmationTitle" = "End voice chat"; "VoiceChat.EndConfirmationTitle" = "End voice chat";
"LiveStream.EndConfirmationTitle" = "End live stream";
"VoiceChat.EndConfirmationText" = "Are you sure you want to end this voice chat?"; "VoiceChat.EndConfirmationText" = "Are you sure you want to end this voice chat?";
"LiveStream.EndConfirmationText" = "Are you sure you want to end this live stream?";
"VoiceChat.EndConfirmationEnd" = "End"; "VoiceChat.EndConfirmationEnd" = "End";
"VoiceChat.InviteMemberToGroupFirstText" = "%1$@ isn't a member of \"%2$@\" yet. Add them to the group?"; "VoiceChat.InviteMemberToGroupFirstText" = "%1$@ isn't a member of \"%2$@\" yet. Add them to the group?";
@ -5765,6 +5778,7 @@ Sorry for the inconvenience.";
"VoiceChat.InviteMemberToGroupFirstAdd" = "Add"; "VoiceChat.InviteMemberToGroupFirstAdd" = "Add";
"VoiceChat.CreateNewVoiceChatText" = "Voice chat ended. Start a new one?"; "VoiceChat.CreateNewVoiceChatText" = "Voice chat ended. Start a new one?";
"LiveStream.CreateNewVoiceChatText" = "Live stream ended. Start a new one?";
"VoiceChat.CreateNewVoiceChatStart" = "Start"; "VoiceChat.CreateNewVoiceChatStart" = "Start";
"VoiceChat.CreateNewVoiceChatStartNow" = "Start Now"; "VoiceChat.CreateNewVoiceChatStartNow" = "Start Now";
"VoiceChat.CreateNewVoiceChatSchedule" = "Schedule"; "VoiceChat.CreateNewVoiceChatSchedule" = "Schedule";
@ -5774,8 +5788,10 @@ Sorry for the inconvenience.";
"PUSH_CHAT_VOICECHAT_INVITE_YOU" = "%2$@|%1$@ invited you to the voice chat"; "PUSH_CHAT_VOICECHAT_INVITE_YOU" = "%2$@|%1$@ invited you to the voice chat";
"PUSH_CHAT_VOICECHAT_END" = "%2$@|%1$@ has ended the voice chat"; "PUSH_CHAT_VOICECHAT_END" = "%2$@|%1$@ has ended the voice chat";
"Call.VoiceChatInProgressTitle" = "Voice Chat in Progress"; "PUSH_CHAT_LIVESTREAM_START" = "%2$@|%1$@ started a live stream";
"Call.VoiceChatInProgressMessageCall" = "Leave voice chat in %1$@ and start a call with %2$@?"; "PUSH_CHAT_LIVESTREAM_INVITE" = "%2$@|%1$@ invited %3$@ to the live stream";
"PUSH_CHAT_LIVESTREAM_INVITE_YOU" = "%2$@|%1$@ invited you to the live stream";
"PUSH_CHAT_LIVESTREAM_END" = "%2$@|%1$@ has ended the live stream";
"Conversation.Dice.u1F3B3" = "Send a bowling emoji to try your luck."; "Conversation.Dice.u1F3B3" = "Send a bowling emoji to try your luck.";
@ -5791,7 +5807,9 @@ Sorry for the inconvenience.";
"VoiceOver.Chat.MessagesSelected_any" = "%@ messages selected"; "VoiceOver.Chat.MessagesSelected_any" = "%@ messages selected";
"Channel.AdminLog.StartedVoiceChat" = "%1$@ started voice chat"; "Channel.AdminLog.StartedVoiceChat" = "%1$@ started voice chat";
"Channel.AdminLog.StartedLiveStream" = "%1$@ started live stream";
"Channel.AdminLog.EndedVoiceChat" = "%1$@ ended voice chat"; "Channel.AdminLog.EndedVoiceChat" = "%1$@ ended voice chat";
"Channel.AdminLog.EndedLiveStream" = "%1$@ ended live stream";
"Channel.AdminLog.MutedParticipant" = "%1$@ muted %2$@"; "Channel.AdminLog.MutedParticipant" = "%1$@ muted %2$@";
"Channel.AdminLog.UnmutedMutedParticipant" = "%1$@ unmuted %2$@"; "Channel.AdminLog.UnmutedMutedParticipant" = "%1$@ unmuted %2$@";
"Channel.AdminLog.AllowedNewMembersToSpeak" = "%1$@ allowed new members to speak"; "Channel.AdminLog.AllowedNewMembersToSpeak" = "%1$@ allowed new members to speak";
@ -5800,11 +5818,13 @@ Sorry for the inconvenience.";
"Group.GroupMembersHeader" = "GROUP MEMBERS"; "Group.GroupMembersHeader" = "GROUP MEMBERS";
"Conversation.VoiceChatMediaRecordingRestricted" = "You can't record voice and video messages during a voice chat."; "Conversation.VoiceChatMediaRecordingRestricted" = "You can't record voice and video messages during a voice chat.";
"Conversation.LiveStreamMediaRecordingRestricted" = "You can't record voice and video messages during a live stream.";
"CallList.ActiveVoiceChatsHeader" = "ACTIVE VOICE CHATS"; "CallList.ActiveVoiceChatsHeader" = "ACTIVE VOICE CHATS";
"CallList.RecentCallsHeader" = "RECENT CALLS"; "CallList.RecentCallsHeader" = "RECENT CALLS";
"VoiceChat.PeerJoinedText" = "%@ joined the voice chat"; "VoiceChat.PeerJoinedText" = "%@ joined the voice chat";
"LiveStream.PeerJoinedText" = "%@ joined the live stream";
"VoiceChat.StartRecording" = "Start Recording"; "VoiceChat.StartRecording" = "Start Recording";
"VoiceChat.StopRecording" = "Stop Recording"; "VoiceChat.StopRecording" = "Stop Recording";
@ -5815,7 +5835,9 @@ Sorry for the inconvenience.";
"VoiceChat.RecordingTitlePlaceholder" = "Audio Title (Optional)"; "VoiceChat.RecordingTitlePlaceholder" = "Audio Title (Optional)";
"VoiceChat.RecordingStarted" = "Voice chat recording started"; "VoiceChat.RecordingStarted" = "Voice chat recording started";
"LiveStream.RecordingStarted" = "Live stream recording started";
"VoiceChat.RecordingInProgress" = "Voice chat is being recorded"; "VoiceChat.RecordingInProgress" = "Voice chat is being recorded";
"LiveStream.RecordingInProgress" = "Live stream is being recorded";
"VoiceChat.StopRecordingTitle" = "Stop Recording?"; "VoiceChat.StopRecordingTitle" = "Stop Recording?";
"VoiceChat.StopRecordingStop" = "Stop"; "VoiceChat.StopRecordingStop" = "Stop";
@ -5840,6 +5862,7 @@ Sorry for the inconvenience.";
"VoiceChat.MuteForMe" = "Mute for Me"; "VoiceChat.MuteForMe" = "Mute for Me";
"PeerInfo.ButtonVoiceChat" = "Voice Chat"; "PeerInfo.ButtonVoiceChat" = "Voice Chat";
"PeerInfo.ButtonLiveStream" = "Live Stream";
"VoiceChat.OpenChat" = "Open Chat"; "VoiceChat.OpenChat" = "Open Chat";
"GroupInfo.InviteLinks" = "Invite Links"; "GroupInfo.InviteLinks" = "Invite Links";
@ -6187,16 +6210,20 @@ Sorry for the inconvenience.";
"VoiceChat.DisplayAsInfo" = "Choose whether you want to be displayed as your personal account or as your channel."; "VoiceChat.DisplayAsInfo" = "Choose whether you want to be displayed as your personal account or as your channel.";
"VoiceChat.DisplayAsInfoGroup" = "Choose whether you want to be displayed as your personal account, this group, or one of your channels."; "VoiceChat.DisplayAsInfoGroup" = "Choose whether you want to be displayed as your personal account, this group, or one of your channels.";
"VoiceChat.DisplayAsSuccess" = "Members of this voice chat will now see your as **%@**."; "VoiceChat.DisplayAsSuccess" = "Members of this voice chat will now see your as **%@**.";
"LiveStream.DisplayAsSuccess" = "Members of this live stream will now see your as **%@**.";
"VoiceChat.PersonalAccount" = "personal account"; "VoiceChat.PersonalAccount" = "personal account";
"VoiceChat.EditTitle" = "Edit Voice Chat Title"; "VoiceChat.EditTitle" = "Edit Voice Chat Title";
"LiveStream.EditTitle" = "Edit Live Stream Title";
"VoiceChat.EditPermissions" = "Edit Permissions"; "VoiceChat.EditPermissions" = "Edit Permissions";
"VoiceChat.OpenChannel" = "Open Channel"; "VoiceChat.OpenChannel" = "Open Channel";
"VoiceChat.EditTitleTitle" = "Voice Chat Title";
"VoiceChat.EditTitleText" = "Edit a title of this voice chat."; "VoiceChat.EditTitleText" = "Edit a title of this voice chat.";
"LiveStream.EditTitleText" = "Edit a title of this live stream.";
"VoiceChat.EditTitleSuccess" = "Voice chat title changed to **%@**."; "VoiceChat.EditTitleSuccess" = "Voice chat title changed to **%@**.";
"LiveStream.EditTitleSuccess" = "Live stream title changed to **%@**.";
"VoiceChat.EditTitleRemoveSuccess" = "Voice chat title removed."; "VoiceChat.EditTitleRemoveSuccess" = "Voice chat title removed.";
"LiveStream.EditTitleRemoveSuccess" = "Live Stream title removed.";
"VoiceChat.InviteLink.Speaker" = "Speaker"; "VoiceChat.InviteLink.Speaker" = "Speaker";
"VoiceChat.InviteLink.Listener" = "Listener"; "VoiceChat.InviteLink.Listener" = "Listener";
@ -6217,8 +6244,6 @@ Sorry for the inconvenience.";
"VoiceChat.InviteLink.InviteListeners_many" = "[%@] Invite Listeners"; "VoiceChat.InviteLink.InviteListeners_many" = "[%@] Invite Listeners";
"VoiceChat.InviteLink.InviteListeners_any" = "[%@] Invite Listeners"; "VoiceChat.InviteLink.InviteListeners_any" = "[%@] Invite Listeners";
"Conversation.JoinVoiceChat" = "JOIN VOICE CHAT";
"Conversation.CancelForwardTitle" = "Cancel Forwarding"; "Conversation.CancelForwardTitle" = "Cancel Forwarding";
"Conversation.CancelForwardText" = "Do you want to cancel forwarding or send messages to a different chat?"; "Conversation.CancelForwardText" = "Do you want to cancel forwarding or send messages to a different chat?";
"Conversation.CancelForwardCancelForward" = "Cancel Forwarding"; "Conversation.CancelForwardCancelForward" = "Cancel Forwarding";
@ -6260,8 +6285,10 @@ Sorry for the inconvenience.";
"VoiceChat.RemovePeerConfirmationChannel" = "Are you sure you want to remove %@ from the channel?"; "VoiceChat.RemovePeerConfirmationChannel" = "Are you sure you want to remove %@ from the channel?";
"VoiceChat.RemoveAndBanPeerConfirmation" = "Do you want to remove %1$@ from the voice chat and ban them in %2$@?"; "VoiceChat.RemoveAndBanPeerConfirmation" = "Do you want to remove %1$@ from the voice chat and ban them in %2$@?";
"LiveStream.RemoveAndBanPeerConfirmation" = "Do you want to remove %1$@ from the live stream and ban them in %2$@?";
"Notification.VoiceChatStartedChannel" = "Voice chat started"; "Notification.VoiceChatStartedChannel" = "Voice chat started";
"Notification.LiveStreamStarted" = "Live stream started";
"Conversation.MessageCopied" = "Message copied to clipboard"; "Conversation.MessageCopied" = "Message copied to clipboard";
"Conversation.LinkCopied" = "Link copied to clipboard"; "Conversation.LinkCopied" = "Link copied to clipboard";
@ -6280,14 +6307,19 @@ Sorry for the inconvenience.";
"Conversation.DeletedFromContacts" = "**%@** deleted from your contacts"; "Conversation.DeletedFromContacts" = "**%@** deleted from your contacts";
"Conversation.VoiceChat" = "Voice Chat"; "Conversation.VoiceChat" = "Voice Chat";
"Conversation.LiveStream" = "Live Stream";
"Conversation.JoinVoiceChatAsSpeaker" = "JOIN AS SPEAKER"; "Conversation.JoinVoiceChatAsSpeaker" = "JOIN AS SPEAKER";
"Conversation.JoinVoiceChatAsListener" = "JOIN AS LISTENER"; "Conversation.JoinVoiceChatAsListener" = "JOIN AS LISTENER";
"VoiceChat.LeaveConfirmation" = "Are you sure you want to leave this voice chat?"; "VoiceChat.LeaveConfirmation" = "Are you sure you want to leave this voice chat?";
"LiveStream.LeaveConfirmation" = "Are you sure you want to leave this live stream?";
"VoiceChat.LeaveVoiceChat" = "Leave Voice Chat"; "VoiceChat.LeaveVoiceChat" = "Leave Voice Chat";
"LiveStream.LeaveVoiceChat" = "Leave Live Stream";
"VoiceChat.LeaveAndEndVoiceChat" = "End Voice Chat"; "VoiceChat.LeaveAndEndVoiceChat" = "End Voice Chat";
"LiveStream.LeaveAndEndVoiceChat" = "End Live Stream";
"VoiceChat.LeaveAndCancelVoiceChat" = "Abort Voice Chat"; "VoiceChat.LeaveAndCancelVoiceChat" = "Abort Voice Chat";
"LiveStream.LeaveAndCancelVoiceChat" = "Abort Live Stream";
"VoiceChat.ForwardTooltip.Chat" = "Invite link forwarded to **%@**"; "VoiceChat.ForwardTooltip.Chat" = "Invite link forwarded to **%@**";
"VoiceChat.ForwardTooltip.TwoChats" = "Invite link forwarded to **%@** and **%@**"; "VoiceChat.ForwardTooltip.TwoChats" = "Invite link forwarded to **%@** and **%@**";
@ -6341,12 +6373,15 @@ Sorry for the inconvenience.";
"VoiceChat.UnpinVideo" = "Unpin Video"; "VoiceChat.UnpinVideo" = "Unpin Video";
"Notification.VoiceChatScheduledChannel" = "Voice chat scheduled for %@"; "Notification.VoiceChatScheduledChannel" = "Voice chat scheduled for %@";
"Notification.LiveStreamScheduled" = "Live stream scheduled for %@";
"Notification.VoiceChatScheduled" = "%1$@ scheduled a voice chat for %2$@"; "Notification.VoiceChatScheduled" = "%1$@ scheduled a voice chat for %2$@";
"Notification.VoiceChatScheduledTodayChannel" = "Voice chat scheduled for today at %@"; "Notification.VoiceChatScheduledTodayChannel" = "Voice chat scheduled for today at %@";
"Notification.LiveStreamScheduledToday" = "Live stream scheduled for today at %@";
"Notification.VoiceChatScheduledToday" = "%1$@ scheduled a voice chat for today at %2$@"; "Notification.VoiceChatScheduledToday" = "%1$@ scheduled a voice chat for today at %2$@";
"Notification.VoiceChatScheduledTomorrowChannel" = "Voice chat scheduled for tomorrow at %@"; "Notification.VoiceChatScheduledTomorrowChannel" = "Voice chat scheduled for tomorrow at %@";
"Notification.LiveStreamScheduledTomorrow" = "Live stream scheduled for tomorrow at %@";
"Notification.VoiceChatScheduledTomorrow" = "%1$@ scheduled a voice chat for tomorrow at %2$@"; "Notification.VoiceChatScheduledTomorrow" = "%1$@ scheduled a voice chat for tomorrow at %2$@";
"VoiceChat.StartsIn" = "Starts in"; "VoiceChat.StartsIn" = "Starts in";
@ -6365,28 +6400,36 @@ Sorry for the inconvenience.";
"VoiceChat.TapToEditTitle" = "Tap to edit title"; "VoiceChat.TapToEditTitle" = "Tap to edit title";
"ChannelInfo.ScheduleVoiceChat" = "Schedule Voice Chat"; "ChannelInfo.ScheduleVoiceChat" = "Schedule Voice Chat";
"ChannelInfo.ScheduleLiveStream" = "Schedule Live Stream";
"ScheduleVoiceChat.Title" = "Schedule Voice Chat"; "ScheduleVoiceChat.Title" = "Schedule Voice Chat";
"ScheduleVoiceChatChannel.Title" = "Schedule Voice Chat"; "ScheduleLiveStream.Title" = "Schedule Live Stream";
"ScheduleVoiceChat.GroupText" = "The members of the group will be notified that the voice chat will start in %@."; "ScheduleVoiceChat.GroupText" = "The members of the group will be notified that the voice chat will start in %@.";
"ScheduleVoiceChat.ChannelText" = "The members of the channel will be notified that the voice chat will start in %@."; "ScheduleLiveStream.ChannelText" = "The members of the channel will be notified that the live stream will start in %@.";
"ScheduleVoiceChat.ScheduleToday" = "Start today at %@"; "ScheduleVoiceChat.ScheduleToday" = "Start today at %@";
"ScheduleVoiceChat.ScheduleTomorrow" = "Start tomorrow at %@"; "ScheduleVoiceChat.ScheduleTomorrow" = "Start tomorrow at %@";
"ScheduleVoiceChat.ScheduleOn" = "Start on %@ at %@"; "ScheduleVoiceChat.ScheduleOn" = "Start on %@ at %@";
"Conversation.ScheduledVoiceChat" = "Scheduled Voice Chat"; "Conversation.ScheduledVoiceChat" = "Scheduled Voice Chat";
"Conversation.ScheduledLiveStream" = "Scheduled Live Stream";
"Conversation.ScheduledVoiceChatStartsOn" = "Voice chat starts on %@"; "Conversation.ScheduledVoiceChatStartsOn" = "Voice chat starts on %@";
"Conversation.ScheduledLiveStreamStartsOn" = "Live stream starts on %@";
"Conversation.ScheduledVoiceChatStartsOnShort" = "Starts on %@"; "Conversation.ScheduledVoiceChatStartsOnShort" = "Starts on %@";
"Conversation.ScheduledVoiceChatStartsToday" = "Voice chat starts today at %@"; "Conversation.ScheduledVoiceChatStartsToday" = "Voice chat starts today at %@";
"Conversation.ScheduledLiveStreamStartsToday" = "Live stream starts today at %@";
"Conversation.ScheduledVoiceChatStartsTodayShort" = "Starts today at %@"; "Conversation.ScheduledVoiceChatStartsTodayShort" = "Starts today at %@";
"Conversation.ScheduledVoiceChatStartsTomorrow" = "Voice chat starts tomorrow at %@"; "Conversation.ScheduledVoiceChatStartsTomorrow" = "Voice chat starts tomorrow at %@";
"Conversation.ScheduledLiveStreamStartsTomorrow" = "Live stream starts tomorrow at %@";
"Conversation.ScheduledVoiceChatStartsTomorrowShort" = "Starts tomorrow at %@"; "Conversation.ScheduledVoiceChatStartsTomorrowShort" = "Starts tomorrow at %@";
"VoiceChat.CancelVoiceChat" = "Abort Voice Chat"; "VoiceChat.CancelVoiceChat" = "Abort Voice Chat";
"VoiceChat.CancelLiveStream" = "Abort Live Stream";
"VoiceChat.CancelConfirmationTitle" = "Abort Voice Chat"; "VoiceChat.CancelConfirmationTitle" = "Abort Voice Chat";
"LiveStream.CancelConfirmationTitle" = "Abort Live Stream";
"VoiceChat.CancelConfirmationText" = "Do you want to abort the scheduled voice chat?"; "VoiceChat.CancelConfirmationText" = "Do you want to abort the scheduled voice chat?";
"LiveStream.CancelConfirmationText" = "Do you want to abort the scheduled live stream?";
"VoiceChat.CancelConfirmationEnd" = "Abort"; "VoiceChat.CancelConfirmationEnd" = "Abort";
"ScheduledIn.Seconds_1" = "%@ second"; "ScheduledIn.Seconds_1" = "%@ second";

View File

@ -142,7 +142,11 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode {
} }
} }
case .removeFromGroup: case .removeFromGroup:
text = strings.VoiceChat_RemoveAndBanPeerConfirmation(peer.displayTitle(strings: strings, displayOrder: nameOrder), chatPeer.displayTitle(strings: strings, displayOrder: nameOrder)) if case let .channel(channel) = chatPeer, case .broadcast = channel.info {
text = strings.LiveStream_RemoveAndBanPeerConfirmation(peer.displayTitle(strings: strings, displayOrder: nameOrder), chatPeer.displayTitle(strings: strings, displayOrder: nameOrder))
} else {
text = strings.VoiceChat_RemoveAndBanPeerConfirmation(peer.displayTitle(strings: strings, displayOrder: nameOrder), chatPeer.displayTitle(strings: strings, displayOrder: nameOrder))
}
case .removeFromChannel: case .removeFromChannel:
text = strings.VoiceChat_RemovePeerConfirmationChannel(peer.displayTitle(strings: strings, displayOrder: nameOrder)) text = strings.VoiceChat_RemovePeerConfirmationChannel(peer.displayTitle(strings: strings, displayOrder: nameOrder))
default: default:

View File

@ -379,7 +379,7 @@ private struct ChannelAdminControllerState: Equatable {
} }
} }
private func stringForRight(strings: PresentationStrings, right: TelegramChatAdminRightsFlags, isGroup: Bool, defaultBannedRights: TelegramChatBannedRights?) -> String { private func stringForRight(strings: PresentationStrings, right: TelegramChatAdminRightsFlags, isGroup: Bool, isChannel: Bool, defaultBannedRights: TelegramChatBannedRights?) -> String {
if right.contains(.canChangeInfo) { if right.contains(.canChangeInfo) {
return isGroup ? strings.Group_EditAdmin_PermissionChangeInfo : strings.Channel_EditAdmin_PermissionChangeInfo return isGroup ? strings.Group_EditAdmin_PermissionChangeInfo : strings.Channel_EditAdmin_PermissionChangeInfo
} else if right.contains(.canPostMessages) { } else if right.contains(.canPostMessages) {
@ -407,7 +407,11 @@ private func stringForRight(strings: PresentationStrings, right: TelegramChatAdm
} else if right.contains(.canBeAnonymous) { } else if right.contains(.canBeAnonymous) {
return strings.Channel_AdminLog_CanBeAnonymous return strings.Channel_AdminLog_CanBeAnonymous
} else if right.contains(.canManageCalls) { } else if right.contains(.canManageCalls) {
return strings.Channel_AdminLog_CanManageCalls if isChannel {
return strings.Channel_AdminLog_CanManageLiveStreams
} else {
return strings.Channel_AdminLog_CanManageCalls
}
} else { } else {
return "" return ""
} }
@ -498,6 +502,11 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
if let channel = channelView.peers[channelView.peerId] as? TelegramChannel, let admin = adminView.peers[adminView.peerId] { if let channel = channelView.peers[channelView.peerId] as? TelegramChannel, let admin = adminView.peers[adminView.peerId] {
entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminView.peerPresences[admin.id] as? TelegramUserPresence)) entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminView.peerPresences[admin.id] as? TelegramUserPresence))
var isChannel = false
if case .broadcast = channel.info {
isChannel = true
}
var isCreator = false var isCreator = false
if let initialParticipant = initialParticipant, case .creator = initialParticipant { if let initialParticipant = initialParticipant, case .creator = initialParticipant {
@ -566,7 +575,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
var index = 0 var index = 0
for right in rightsOrder { for right in rightsOrder {
if accountUserRightsFlags.contains(right) { if accountUserRightsFlags.contains(right) {
entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, defaultBannedRights: channel.defaultBannedRights), right, currentRightsFlags, currentRightsFlags.contains(right), right == .canBeAnonymous)) entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, isChannel: isChannel, defaultBannedRights: channel.defaultBannedRights), right, currentRightsFlags, currentRightsFlags.contains(right), right == .canBeAnonymous))
index += 1 index += 1
} }
} }
@ -596,7 +605,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
var index = 0 var index = 0
for right in rightsOrder { for right in rightsOrder {
if accountUserRightsFlags.contains(right) { if accountUserRightsFlags.contains(right) {
entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, defaultBannedRights: channel.defaultBannedRights), right, currentRightsFlags, currentRightsFlags.contains(right), !state.updating && admin.id != accountPeerId && !rightEnabledByDefault(channelPeer: channel, right: right))) entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, isChannel: isChannel, defaultBannedRights: channel.defaultBannedRights), right, currentRightsFlags, currentRightsFlags.contains(right), !state.updating && admin.id != accountPeerId && !rightEnabledByDefault(channelPeer: channel, right: right)))
index += 1 index += 1
} }
} }
@ -628,7 +637,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
} else if let initialParticipant = initialParticipant, case let .member(_, _, maybeAdminInfo, _, _) = initialParticipant, let adminInfo = maybeAdminInfo { } else if let initialParticipant = initialParticipant, case let .member(_, _, maybeAdminInfo, _, _) = initialParticipant, let adminInfo = maybeAdminInfo {
var index = 0 var index = 0
for right in rightsOrder { for right in rightsOrder {
entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, defaultBannedRights: channel.defaultBannedRights), right, adminInfo.rights.rights, adminInfo.rights.rights.contains(right), false)) entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, isChannel: isChannel, defaultBannedRights: channel.defaultBannedRights), right, adminInfo.rights.rights, adminInfo.rights.rights.contains(right), false))
index += 1 index += 1
} }
} }
@ -683,6 +692,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
entries.append(.rightsTitle(presentationData.theme, presentationData.strings.Channel_EditAdmin_PermissionsHeader)) entries.append(.rightsTitle(presentationData.theme, presentationData.strings.Channel_EditAdmin_PermissionsHeader))
let isGroup = true let isGroup = true
let isChannel = false
let maskRightsFlags: TelegramChatAdminRightsFlags = .groupSpecific let maskRightsFlags: TelegramChatAdminRightsFlags = .groupSpecific
let rightsOrder: [TelegramChatAdminRightsFlags] = [ let rightsOrder: [TelegramChatAdminRightsFlags] = [
.canChangeInfo, .canChangeInfo,
@ -714,7 +724,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
var index = 0 var index = 0
for right in rightsOrder { for right in rightsOrder {
if accountUserRightsFlags.contains(right) { if accountUserRightsFlags.contains(right) {
entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, defaultBannedRights: group.defaultBannedRights), right, currentRightsFlags, currentRightsFlags.contains(right), !state.updating && accountIsCreator)) entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, isChannel: isChannel, defaultBannedRights: group.defaultBannedRights), right, currentRightsFlags, currentRightsFlags.contains(right), !state.updating && accountIsCreator))
index += 1 index += 1
} }
} }

View File

@ -526,8 +526,10 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
var joinText = self.strings.VoiceChat_PanelJoin var joinText = self.strings.VoiceChat_PanelJoin
var title = self.strings.VoiceChat_Title var title = self.strings.VoiceChat_Title
var isChannel = false
if let currentData = self.currentData, currentData.isChannel { if let currentData = self.currentData, currentData.isChannel {
title = self.strings.VoiceChatChannel_Title title = self.strings.VoiceChatChannel_Title
isChannel = true
} }
var text = self.currentText var text = self.currentText
var isScheduled = false var isScheduled = false
@ -536,9 +538,9 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode {
isScheduled = true isScheduled = true
if let voiceChatTitle = self.currentData?.info.title { if let voiceChatTitle = self.currentData?.info.title {
title = voiceChatTitle title = voiceChatTitle
text = humanReadableStringForTimestamp(strings: self.strings, dateTimeFormat: self.dateTimeFormat, timestamp: scheduleTime, alwaysShowTime: true, format: HumanReadableStringFormat(dateFormatString: { self.strings.Conversation_ScheduledVoiceChatStartsOn($0) }, tomorrowFormatString: { self.strings.Conversation_ScheduledVoiceChatStartsTomorrow($0) }, todayFormatString: { self.strings.Conversation_ScheduledVoiceChatStartsToday($0) })).string text = humanReadableStringForTimestamp(strings: self.strings, dateTimeFormat: self.dateTimeFormat, timestamp: scheduleTime, alwaysShowTime: true, format: HumanReadableStringFormat(dateFormatString: { isChannel ? self.strings.Conversation_ScheduledLiveStreamStartsOn($0) : self.strings.Conversation_ScheduledVoiceChatStartsOn($0) }, tomorrowFormatString: { isChannel ? self.strings.Conversation_ScheduledLiveStreamStartsTomorrow($0) : self.strings.Conversation_ScheduledVoiceChatStartsTomorrow($0) }, todayFormatString: { isChannel ? self.strings.Conversation_ScheduledLiveStreamStartsToday($0) : self.strings.Conversation_ScheduledVoiceChatStartsToday($0) })).string
} else { } else {
title = self.strings.Conversation_ScheduledVoiceChat title = isChannel ? self.strings.Conversation_ScheduledLiveStream : self.strings.Conversation_ScheduledVoiceChat
text = humanReadableStringForTimestamp(strings: self.strings, dateTimeFormat: self.dateTimeFormat, timestamp: scheduleTime, alwaysShowTime: true, format: HumanReadableStringFormat(dateFormatString: { self.strings.Conversation_ScheduledVoiceChatStartsOnShort($0) }, tomorrowFormatString: { self.strings.Conversation_ScheduledVoiceChatStartsTomorrowShort($0) }, todayFormatString: { self.strings.Conversation_ScheduledVoiceChatStartsTodayShort($0) })).string text = humanReadableStringForTimestamp(strings: self.strings, dateTimeFormat: self.dateTimeFormat, timestamp: scheduleTime, alwaysShowTime: true, format: HumanReadableStringFormat(dateFormatString: { self.strings.Conversation_ScheduledVoiceChatStartsOnShort($0) }, tomorrowFormatString: { self.strings.Conversation_ScheduledVoiceChatStartsTomorrowShort($0) }, todayFormatString: { self.strings.Conversation_ScheduledVoiceChatStartsTodayShort($0) })).string
} }

View File

@ -398,6 +398,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
private var initialCall: EngineGroupCallDescription? private var initialCall: EngineGroupCallDescription?
public let internalId: CallSessionInternalId public let internalId: CallSessionInternalId
public let peerId: PeerId public let peerId: PeerId
private let isChannel: Bool
private var invite: String? private var invite: String?
private var joinAsPeerId: PeerId private var joinAsPeerId: PeerId
private var ignorePreviousJoinAsPeerId: (PeerId, UInt32)? private var ignorePreviousJoinAsPeerId: (PeerId, UInt32)?
@ -650,6 +651,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
self.initialCall = initialCall self.initialCall = initialCall
self.internalId = internalId self.internalId = internalId
self.peerId = peerId self.peerId = peerId
self.isChannel = isChannel
self.invite = invite self.invite = invite
self.joinAsPeerId = joinAsPeerId ?? accountContext.account.peerId self.joinAsPeerId = joinAsPeerId ?? accountContext.account.peerId
self.schedulePending = initialCall == nil self.schedulePending = initialCall == nil
@ -1524,12 +1526,12 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} }
if case .anonymousNotAllowed = error { if case .anonymousNotAllowed = error {
let presentationData = strongSelf.accountContext.sharedContext.currentPresentationData.with { $0 } let presentationData = strongSelf.accountContext.sharedContext.currentPresentationData.with { $0 }
strongSelf.accountContext.sharedContext.mainWindow?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.VoiceChat_AnonymousDisabledAlertText, actions: [ strongSelf.accountContext.sharedContext.mainWindow?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: strongSelf.isChannel ? presentationData.strings.LiveStream_AnonymousDisabledAlertText : presentationData.strings.VoiceChat_AnonymousDisabledAlertText, actions: [
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {}) TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})
]), on: .root, blockInteraction: false, completion: {}) ]), on: .root, blockInteraction: false, completion: {})
} else if case .tooManyParticipants = error { } else if case .tooManyParticipants = error {
let presentationData = strongSelf.accountContext.sharedContext.currentPresentationData.with { $0 } let presentationData = strongSelf.accountContext.sharedContext.currentPresentationData.with { $0 }
strongSelf.accountContext.sharedContext.mainWindow?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.VoiceChat_ChatFullAlertText, actions: [ strongSelf.accountContext.sharedContext.mainWindow?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: strongSelf.isChannel ? presentationData.strings.LiveStream_ChatFullAlertText : presentationData.strings.VoiceChat_ChatFullAlertText, actions: [
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {}) TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})
]), on: .root, blockInteraction: false, completion: {}) ]), on: .root, blockInteraction: false, completion: {})
} else if case .invalidJoinAsPeer = error { } else if case .invalidJoinAsPeer = error {

View File

@ -1236,7 +1236,13 @@ public final class VoiceChatController: ViewController {
dismissController?() dismissController?()
if strongSelf.call.invitePeer(participant.peer.id) { if strongSelf.call.invitePeer(participant.peer.id) {
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: participant.peer, text: strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), action: { _ in return false }) let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
} else {
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
}
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: participant.peer, text: text), action: { _ in return false })
} }
} else { } else {
if let groupPeer = groupPeer as? TelegramChannel, let listenerLink = inviteLinks?.listenerLink, !groupPeer.hasPermission(.inviteMembers) { if let groupPeer = groupPeer as? TelegramChannel, let listenerLink = inviteLinks?.listenerLink, !groupPeer.hasPermission(.inviteMembers) {
@ -1336,7 +1342,13 @@ public final class VoiceChatController: ViewController {
dismissController?() dismissController?()
if strongSelf.call.invitePeer(peer.id) { if strongSelf.call.invitePeer(peer.id) {
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), action: { _ in return false }) let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
} else {
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
}
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: text), action: { _ in return false })
} }
})) }))
} else if let groupPeer = groupPeer as? TelegramGroup { } else if let groupPeer = groupPeer as? TelegramGroup {
@ -1398,7 +1410,13 @@ public final class VoiceChatController: ViewController {
dismissController?() dismissController?()
if strongSelf.call.invitePeer(peer.id) { if strongSelf.call.invitePeer(peer.id) {
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), action: { _ in return false }) let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
} else {
text = strongSelf.presentationData.strings.VoiceChat_InvitedPeerText(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
}
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: text), action: { _ in return false })
} }
})) }))
} }
@ -2175,7 +2193,13 @@ public final class VoiceChatController: ViewController {
return return
} }
if event.joined { if event.joined {
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: event.peer, text: strongSelf.presentationData.strings.VoiceChat_PeerJoinedText(event.peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), action: { _ in return false }) let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_PeerJoinedText(event.peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
} else {
text = strongSelf.presentationData.strings.VoiceChat_PeerJoinedText(event.peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
}
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: event.peer, text: text), action: { _ in return false })
} }
})) }))
@ -2184,7 +2208,13 @@ public final class VoiceChatController: ViewController {
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: strongSelf.presentationData.strings.VoiceChat_DisplayAsSuccess(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string), action: { _ in return false }) let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_DisplayAsSuccess(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
} else {
text = strongSelf.presentationData.strings.VoiceChat_DisplayAsSuccess(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).string
}
strongSelf.presentUndoOverlay(content: .invitedToVoiceChat(context: strongSelf.context, peer: peer, text: text), action: { _ in return false })
})) }))
self.stateVersionDisposable.set((self.call.stateVersion self.stateVersionDisposable.set((self.call.stateVersion
@ -2210,7 +2240,13 @@ public final class VoiceChatController: ViewController {
} }
if !hasTooltipAlready { if !hasTooltipAlready {
let location = strongSelf.titleNode.recordingIconNode.convert(strongSelf.titleNode.recordingIconNode.bounds, to: nil) let location = strongSelf.titleNode.recordingIconNode.convert(strongSelf.titleNode.recordingIconNode.bounds, to: nil)
strongSelf.controller?.present(TooltipScreen(text: presentationData.strings.VoiceChat_RecordingInProgress, icon: nil, location: .point(location.offsetBy(dx: 1.0, dy: 0.0), .top), displayDuration: .custom(3.0), shouldDismissOnTouch: { _ in let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = presentationData.strings.LiveStream_RecordingInProgress
} else {
text = presentationData.strings.VoiceChat_RecordingInProgress
}
strongSelf.controller?.present(TooltipScreen(text: text, icon: nil, location: .point(location.offsetBy(dx: 1.0, dy: 0.0), .top), displayDuration: .custom(3.0), shouldDismissOnTouch: { _ in
return .dismiss(consume: true) return .dismiss(consume: true)
}), in: .window(.root)) }), in: .window(.root))
} }
@ -2457,7 +2493,13 @@ public final class VoiceChatController: ViewController {
} }
if canManageCall { if canManageCall {
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.VoiceChat_EditTitle, icon: { theme -> UIImage? in let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_EditTitle
} else {
text = strongSelf.presentationData.strings.VoiceChat_EditTitle
}
items.append(.action(ContextMenuActionItem(text: text, icon: { theme -> UIImage? in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Pencil"), color: theme.actionSheet.primaryTextColor) return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Pencil"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in }, action: { _, f in
f(.default) f(.default)
@ -2585,15 +2627,29 @@ public final class VoiceChatController: ViewController {
if let strongSelf = self { if let strongSelf = self {
strongSelf.call.setShouldBeRecording(true, title: "", videoOrientation: videoOrientation) strongSelf.call.setShouldBeRecording(true, title: "", videoOrientation: videoOrientation)
strongSelf.presentUndoOverlay(content: .voiceChatRecording(text: strongSelf.presentationData.strings.VoiceChat_RecordingStarted), action: { _ in return false }) let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_RecordingStarted
} else {
text = strongSelf.presentationData.strings.VoiceChat_RecordingStarted
}
strongSelf.presentUndoOverlay(content: .voiceChatRecording(text: text), action: { _ in return false })
strongSelf.call.playTone(.recordingStarted) strongSelf.call.playTone(.recordingStarted)
} }
}) })
// let controller = voiceChatTitleEditController(sharedContext: strongSelf.context.sharedContext, account: strongSelf.context.account, forceTheme: strongSelf.darkTheme, title: presentationData.strings.VoiceChat_StartRecordingTitle, text: presentationData.strings.VoiceChat_StartRecordingText, placeholder: presentationData.strings.VoiceChat_RecordingTitlePlaceholder, value: nil, maxLength: 40, apply: { title in // let controller = voiceChatTitleEditController(sharedContext: strongSelf.context.sharedContext, account: strongSelf.context.account, forceTheme: strongSelf.darkTheme, title: presentationData.strings.VoiceChat_StartRecordingTitle, text: presentationData.strings.VoiceChat_StartRecordingText, placeholder: presentationData.strings.VoiceChat_RecordingTitlePlaceholder, value: nil, maxLength: 40, apply: { title in
// if let strongSelf = self, let title = title { // if let strongSelf = self, let title = title {
// strongSelf.call.setShouldBeRecording(true, title: title) // strongSelf.call.setShouldBeRecording(true, title: title)
// let text: String
// if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
// text = strongSelf.presentationData.strings.LiveStream_RecordingStarted
// } else {
// text = strongSelf.presentationData.strings.VoiceChat_RecordingStarted
// }
// //
// strongSelf.presentUndoOverlay(content: .voiceChatRecording(text: strongSelf.presentationData.strings.VoiceChat_RecordingStarted), action: { _ in return false }) // strongSelf.presentUndoOverlay(content: .voiceChatRecording(text: text), action: { _ in return false })
// strongSelf.call.playTone(.recordingStarted) // strongSelf.call.playTone(.recordingStarted)
// } // }
// }) // })
@ -2604,7 +2660,13 @@ public final class VoiceChatController: ViewController {
} }
if canManageCall { if canManageCall {
items.append(.action(ContextMenuActionItem(text: isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelVoiceChat : strongSelf.presentationData.strings.VoiceChat_EndVoiceChat, textColor: .destructive, icon: { theme in let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelLiveStream : strongSelf.presentationData.strings.VoiceChat_EndLiveStream
} else {
text = isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelVoiceChat : strongSelf.presentationData.strings.VoiceChat_EndVoiceChat
}
items.append(.action(ContextMenuActionItem(text: text, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.actionSheet.destructiveActionTextColor) return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.actionSheet.destructiveActionTextColor)
}, action: { _, f in }, action: { _, f in
f(.dismissWithoutContent) f(.dismissWithoutContent)
@ -2626,13 +2688,29 @@ public final class VoiceChatController: ViewController {
}) })
} }
let alertController = textAlertController(context: strongSelf.context, forceTheme: strongSelf.darkTheme, title: isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationTitle : strongSelf.presentationData.strings.VoiceChat_EndConfirmationTitle, text: isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationText : strongSelf.presentationData.strings.VoiceChat_EndConfirmationText, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationEnd : strongSelf.presentationData.strings.VoiceChat_EndConfirmationEnd, action: { let title: String
let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
title = isScheduled ? strongSelf.presentationData.strings.LiveStream_CancelConfirmationTitle : strongSelf.presentationData.strings.LiveStream_EndConfirmationTitle
text = isScheduled ? strongSelf.presentationData.strings.LiveStream_CancelConfirmationText : strongSelf.presentationData.strings.LiveStream_EndConfirmationText
} else {
title = isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationTitle : strongSelf.presentationData.strings.VoiceChat_EndConfirmationTitle
text = isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationText : strongSelf.presentationData.strings.VoiceChat_EndConfirmationText
}
let alertController = textAlertController(context: strongSelf.context, forceTheme: strongSelf.darkTheme, title: title, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationEnd : strongSelf.presentationData.strings.VoiceChat_EndConfirmationEnd, action: {
action() action()
})]) })])
strongSelf.controller?.present(alertController, in: .window(.root)) strongSelf.controller?.present(alertController, in: .window(.root))
}))) })))
} else { } else {
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.VoiceChat_LeaveVoiceChat, textColor: .destructive, icon: { theme in let leaveText: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
leaveText = strongSelf.presentationData.strings.LiveStream_LeaveVoiceChat
} else {
leaveText = strongSelf.presentationData.strings.VoiceChat_LeaveVoiceChat
}
items.append(.action(ContextMenuActionItem(text: leaveText, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.actionSheet.destructiveActionTextColor) return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.actionSheet.destructiveActionTextColor)
}, action: { _, f in }, action: { _, f in
f(.dismissWithoutContent) f(.dismissWithoutContent)
@ -2949,7 +3027,7 @@ public final class VoiceChatController: ViewController {
isGroup = false isGroup = false
} }
let intervalString = scheduledTimeIntervalString(strings: self.presentationData.strings, value: max(60, delta)) let intervalString = scheduledTimeIntervalString(strings: self.presentationData.strings, value: max(60, delta))
self.scheduleTextNode.attributedText = NSAttributedString(string: isGroup ? self.presentationData.strings.ScheduleVoiceChat_GroupText(intervalString).string : self.presentationData.strings.ScheduleVoiceChat_ChannelText(intervalString).string, font: Font.regular(14.0), textColor: UIColor(rgb: 0x8e8e93)) self.scheduleTextNode.attributedText = NSAttributedString(string: isGroup ? self.presentationData.strings.ScheduleVoiceChat_GroupText(intervalString).string : self.presentationData.strings.ScheduleLiveStream_ChannelText(intervalString).string, font: Font.regular(14.0), textColor: UIColor(rgb: 0x8e8e93))
if let (layout, navigationHeight) = self.validLayout { if let (layout, navigationHeight) = self.validLayout {
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .spring)) self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .spring))
@ -3090,14 +3168,35 @@ public final class VoiceChatController: ViewController {
let actionSheet = ActionSheetController(presentationData: self.presentationData.withUpdated(theme: self.darkTheme)) let actionSheet = ActionSheetController(presentationData: self.presentationData.withUpdated(theme: self.darkTheme))
var items: [ActionSheetItem] = [] var items: [ActionSheetItem] = []
let leaveTitle: String
let leaveAndCancelTitle: String
if let channel = self.peer as? TelegramChannel, case .broadcast = channel.info {
leaveTitle = self.presentationData.strings.LiveStream_LeaveConfirmation
leaveAndCancelTitle = self.isScheduled ? self.presentationData.strings.LiveStream_LeaveAndCancelVoiceChat : self.presentationData.strings.LiveStream_LeaveAndEndVoiceChat
} else {
leaveTitle = self.presentationData.strings.VoiceChat_LeaveConfirmation
leaveAndCancelTitle = self.isScheduled ? self.presentationData.strings.VoiceChat_LeaveAndCancelVoiceChat : self.presentationData.strings.VoiceChat_LeaveAndEndVoiceChat
}
items.append(ActionSheetTextItem(title: self.presentationData.strings.VoiceChat_LeaveConfirmation)) items.append(ActionSheetTextItem(title: leaveTitle))
items.append(ActionSheetButtonItem(title: self.isScheduled ? self.presentationData.strings.VoiceChat_LeaveAndCancelVoiceChat : self.presentationData.strings.VoiceChat_LeaveAndEndVoiceChat, color: .destructive, action: { [weak self, weak actionSheet] in items.append(ActionSheetButtonItem(title: leaveAndCancelTitle, color: .destructive, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated() actionSheet?.dismissAnimated()
if let strongSelf = self { if let strongSelf = self {
let title: String
let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
title = strongSelf.isScheduled ? strongSelf.presentationData.strings.LiveStream_CancelConfirmationTitle : strongSelf.presentationData.strings.LiveStream_EndConfirmationTitle
text = strongSelf.isScheduled ? strongSelf.presentationData.strings.LiveStream_CancelConfirmationText : strongSelf.presentationData.strings.LiveStream_EndConfirmationText
} else {
title = strongSelf.isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationTitle : strongSelf.presentationData.strings.VoiceChat_EndConfirmationTitle
text = strongSelf.isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationText : strongSelf.presentationData.strings.VoiceChat_EndConfirmationText
}
if let (members, _) = strongSelf.currentCallMembers, members.count >= 10 || true { if let (members, _) = strongSelf.currentCallMembers, members.count >= 10 || true {
let alertController = textAlertController(context: strongSelf.context, forceTheme: strongSelf.darkTheme, title: strongSelf.isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationTitle : strongSelf.presentationData.strings.VoiceChat_EndConfirmationTitle, text: strongSelf.isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationText : strongSelf.presentationData.strings.VoiceChat_EndConfirmationText, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: strongSelf.isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationEnd : strongSelf.presentationData.strings.VoiceChat_EndConfirmationEnd, action: { let alertController = textAlertController(context: strongSelf.context, forceTheme: strongSelf.darkTheme, title: title, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: strongSelf.isScheduled ? strongSelf.presentationData.strings.VoiceChat_CancelConfirmationEnd : strongSelf.presentationData.strings.VoiceChat_EndConfirmationEnd, action: {
action() action()
})]) })])
strongSelf.controller?.present(alertController, in: .window(.root)) strongSelf.controller?.present(alertController, in: .window(.root))
@ -3106,7 +3205,15 @@ public final class VoiceChatController: ViewController {
} }
} }
})) }))
items.append(ActionSheetButtonItem(title: self.presentationData.strings.VoiceChat_LeaveVoiceChat, color: .accent, action: { [weak self, weak actionSheet] in
let leaveText: String
if let channel = self.peer as? TelegramChannel, case .broadcast = channel.info {
leaveText = self.presentationData.strings.LiveStream_LeaveVoiceChat
} else {
leaveText = self.presentationData.strings.VoiceChat_LeaveVoiceChat
}
items.append(ActionSheetButtonItem(title: leaveText, color: .accent, action: { [weak self, weak actionSheet] in
actionSheet?.dismissAnimated() actionSheet?.dismissAnimated()
guard let strongSelf = self else { guard let strongSelf = self else {
@ -3921,7 +4028,7 @@ public final class VoiceChatController: ViewController {
var title = self.currentTitle var title = self.currentTitle
if self.isScheduling { if self.isScheduling {
if let peer = self.peer as? TelegramChannel, case .broadcast = peer.info { if let peer = self.peer as? TelegramChannel, case .broadcast = peer.info {
title = self.presentationData.strings.ScheduleVoiceChatChannel_Title title = self.presentationData.strings.ScheduleLiveStream_Title
} else { } else {
title = self.presentationData.strings.ScheduleVoiceChat_Title title = self.presentationData.strings.ScheduleVoiceChat_Title
} }
@ -5857,11 +5964,29 @@ public final class VoiceChatController: ViewController {
} }
let initialTitle = strongSelf.callState?.title ?? "" let initialTitle = strongSelf.callState?.title ?? ""
let controller = voiceChatTitleEditController(sharedContext: strongSelf.context.sharedContext, account: strongSelf.context.account, forceTheme: strongSelf.darkTheme, title: strongSelf.presentationData.strings.VoiceChat_EditTitleTitle, text: strongSelf.presentationData.strings.VoiceChat_EditTitleText, placeholder: chatPeer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), value: initialTitle, maxLength: 40, apply: { title in
let title: String
let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
title = strongSelf.presentationData.strings.LiveStream_EditTitle
text = strongSelf.presentationData.strings.LiveStream_EditTitleText
} else {
title = strongSelf.presentationData.strings.VoiceChat_EditTitle
text = strongSelf.presentationData.strings.VoiceChat_EditTitleText
}
let controller = voiceChatTitleEditController(sharedContext: strongSelf.context.sharedContext, account: strongSelf.context.account, forceTheme: strongSelf.darkTheme, title: title, text: text, placeholder: chatPeer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder), value: initialTitle, maxLength: 40, apply: { title in
if let strongSelf = self, let title = title, title != initialTitle { if let strongSelf = self, let title = title, title != initialTitle {
strongSelf.call.updateTitle(title) strongSelf.call.updateTitle(title)
strongSelf.presentUndoOverlay(content: .voiceChatFlag(text: title.isEmpty ? strongSelf.presentationData.strings.VoiceChat_EditTitleRemoveSuccess : strongSelf.presentationData.strings.VoiceChat_EditTitleSuccess(title).string), action: { _ in return false }) let text: String
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
text = title.isEmpty ? strongSelf.presentationData.strings.LiveStream_EditTitleRemoveSuccess : strongSelf.presentationData.strings.LiveStream_EditTitleSuccess(title).string
} else {
text = title.isEmpty ? strongSelf.presentationData.strings.VoiceChat_EditTitleRemoveSuccess : strongSelf.presentationData.strings.VoiceChat_EditTitleSuccess(title).string
}
strongSelf.presentUndoOverlay(content: .voiceChatFlag(text: text), action: { _ in return false })
} }
}) })
strongSelf.controller?.present(controller, in: .window(.root)) strongSelf.controller?.present(controller, in: .window(.root))

View File

@ -440,7 +440,12 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
case let .groupPhoneCall(_, _, scheduleDate, duration): case let .groupPhoneCall(_, _, scheduleDate, duration):
if let scheduleDate = scheduleDate { if let scheduleDate = scheduleDate {
if message.author?.id.namespace == Namespaces.Peer.CloudChannel { if message.author?.id.namespace == Namespaces.Peer.CloudChannel {
let titleString = humanReadableStringForTimestamp(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: scheduleDate, alwaysShowTime: true, allowYesterday: false, format: HumanReadableStringFormat(dateFormatString: { strings.Notification_VoiceChatScheduledChannel($0) }, tomorrowFormatString: { strings.Notification_VoiceChatScheduledTomorrowChannel($0) }, todayFormatString: { strings.Notification_VoiceChatScheduledTodayChannel($0) })) let titleString: PresentationStrings.FormattedString
if let channel = message.author as? TelegramChannel, case .broadcast = channel.info {
titleString = humanReadableStringForTimestamp(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: scheduleDate, alwaysShowTime: true, allowYesterday: false, format: HumanReadableStringFormat(dateFormatString: { strings.Notification_LiveStreamScheduled($0) }, tomorrowFormatString: { strings.Notification_LiveStreamScheduledTomorrow($0) }, todayFormatString: { strings.Notification_LiveStreamScheduledToday($0) }))
} else {
titleString = humanReadableStringForTimestamp(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: scheduleDate, alwaysShowTime: true, allowYesterday: false, format: HumanReadableStringFormat(dateFormatString: { strings.Notification_VoiceChatScheduledChannel($0) }, tomorrowFormatString: { strings.Notification_VoiceChatScheduledTomorrowChannel($0) }, todayFormatString: { strings.Notification_VoiceChatScheduledTodayChannel($0) }))
}
attributedString = NSAttributedString(string: titleString.string, font: titleFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: titleString.string, font: titleFont, textColor: primaryTextColor)
} else { } else {
let titleString = humanReadableStringForTimestamp(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: scheduleDate, alwaysShowTime: true, allowYesterday: false, format: HumanReadableStringFormat(dateFormatString: { strings.Notification_VoiceChatScheduled(authorName, $0) }, tomorrowFormatString: { strings.Notification_VoiceChatScheduledTomorrow(authorName, $0) }, todayFormatString: { strings.Notification_VoiceChatScheduledToday(authorName, $0) })) let titleString = humanReadableStringForTimestamp(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: scheduleDate, alwaysShowTime: true, allowYesterday: false, format: HumanReadableStringFormat(dateFormatString: { strings.Notification_VoiceChatScheduled(authorName, $0) }, tomorrowFormatString: { strings.Notification_VoiceChatScheduledTomorrow(authorName, $0) }, todayFormatString: { strings.Notification_VoiceChatScheduledToday(authorName, $0) }))
@ -449,7 +454,12 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
} }
} else if let duration = duration { } else if let duration = duration {
if message.author?.id.namespace == Namespaces.Peer.CloudChannel { if message.author?.id.namespace == Namespaces.Peer.CloudChannel {
let titleString = strings.Notification_VoiceChatEnded(callDurationString(strings: strings, value: duration)).string let titleString: String
if let channel = message.author as? TelegramChannel, case .broadcast = channel.info {
titleString = strings.Notification_LiveStreamEnded(callDurationString(strings: strings, value: duration)).string
} else {
titleString = strings.Notification_VoiceChatEnded(callDurationString(strings: strings, value: duration)).string
}
attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor)
} else { } else {
let attributePeerIds: [(Int, PeerId?)] = [(0, message.author?.id)] let attributePeerIds: [(Int, PeerId?)] = [(0, message.author?.id)]
@ -458,8 +468,13 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
} }
} else { } else {
if message.author?.id.namespace == Namespaces.Peer.CloudChannel { if message.author?.id.namespace == Namespaces.Peer.CloudChannel {
let titleString = strings.Notification_VoiceChatStartedChannel let titleString: String
attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor) if let channel = message.author as? TelegramChannel, case .broadcast = channel.info {
titleString = strings.Notification_LiveStreamStarted
} else {
titleString = strings.Notification_VoiceChatStartedChannel
}
attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor)
} else { } else {
let attributePeerIds: [(Int, PeerId?)] = [(0, message.author?.id)] let attributePeerIds: [(Int, PeerId?)] = [(0, message.author?.id)]
let titleString = strings.Notification_VoiceChatStarted(authorName) let titleString = strings.Notification_VoiceChatStarted(authorName)

View File

@ -346,14 +346,30 @@ public final class AccountContextImpl: AccountContext {
let presentationData = strongSelf.sharedContext.currentPresentationData.with { $0 } let presentationData = strongSelf.sharedContext.currentPresentationData.with { $0 }
if let current = current { if let current = current {
if current is TelegramChannel || current is TelegramGroup { if current is TelegramChannel || current is TelegramGroup {
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: presentationData.strings.Call_VoiceChatInProgressTitle, text: presentationData.strings.Call_VoiceChatInProgressMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: { let title: String
let text: String
if let channel = current as? TelegramChannel, case .broadcast = channel.info {
title = presentationData.strings.Call_LiveStreamInProgressTitle
text = presentationData.strings.Call_LiveStreamInProgressMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
} else {
title = presentationData.strings.Call_VoiceChatInProgressTitle
text = presentationData.strings.Call_VoiceChatInProgressMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
}
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: title, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
let _ = strongSelf.sharedContext.callManager?.joinGroupCall(context: strongSelf, peerId: peer.id, invite: invite, requestJoinAsPeerId: requestJoinAsPeerId, initialCall: activeCall, endCurrentIfAny: true) let _ = strongSelf.sharedContext.callManager?.joinGroupCall(context: strongSelf, peerId: peer.id, invite: invite, requestJoinAsPeerId: requestJoinAsPeerId, initialCall: activeCall, endCurrentIfAny: true)
})]), on: .root) })]), on: .root)
} else { } else {
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: presentationData.strings.Call_CallInProgressTitle, text: presentationData.strings.Call_CallInProgressVoiceChatMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: { let text: String
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
text = presentationData.strings.Call_CallInProgressLiveStreamMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
} else {
text = presentationData.strings.Call_CallInProgressVoiceChatMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
}
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: presentationData.strings.Call_CallInProgressTitle, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
@ -392,7 +408,13 @@ public final class AccountContextImpl: AccountContext {
let presentationData = strongSelf.sharedContext.currentPresentationData.with { $0 } let presentationData = strongSelf.sharedContext.currentPresentationData.with { $0 }
if let current = current { if let current = current {
if current is TelegramChannel || current is TelegramGroup { if current is TelegramChannel || current is TelegramGroup {
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: presentationData.strings.Call_VoiceChatInProgressTitle, text: presentationData.strings.Call_VoiceChatInProgressCallMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: { let text: String
if let channel = current as? TelegramChannel, case .broadcast = channel.info {
text = presentationData.strings.Call_LiveStreamInProgressCallMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
} else {
text = presentationData.strings.Call_VoiceChatInProgressCallMessage(current.compactDisplayTitle, peer.compactDisplayTitle).string
}
strongSelf.sharedContext.mainWindow?.present(textAlertController(context: strongSelf, title: presentationData.strings.Call_VoiceChatInProgressTitle, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }

View File

@ -637,7 +637,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
if canManageGroupCalls { if canManageGroupCalls {
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.VoiceChat_CreateNewVoiceChatText, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.VoiceChat_CreateNewVoiceChatStartNow, action: { let text: String
if let channel = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_CreateNewVoiceChatText
} else {
text = strongSelf.presentationData.strings.VoiceChat_CreateNewVoiceChatText
}
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.VoiceChat_CreateNewVoiceChatStartNow, action: {
if let strongSelf = self { if let strongSelf = self {
var dismissStatus: (() -> Void)? var dismissStatus: (() -> Void)?
let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: { let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: {
@ -666,7 +672,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
case .generic, .scheduledTooLate: case .generic, .scheduledTooLate:
text = strongSelf.presentationData.strings.Login_UnknownError text = strongSelf.presentationData.strings.Login_UnknownError
case .anonymousNotAllowed: case .anonymousNotAllowed:
text = strongSelf.presentationData.strings.VoiceChat_AnonymousDisabledAlertText if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_AnonymousDisabledAlertText
} else {
text = strongSelf.presentationData.strings.VoiceChat_AnonymousDisabledAlertText
}
} }
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
}, completed: { }, completed: {
@ -6189,7 +6199,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let rect = strongSelf.chatDisplayNode.frameForInputActionButton() let rect = strongSelf.chatDisplayNode.frameForInputActionButton()
if let rect = rect { if let rect = rect {
strongSelf.mediaRestrictedTooltipController?.dismiss() strongSelf.mediaRestrictedTooltipController?.dismiss()
let tooltipController = TooltipController(content: .text(strongSelf.presentationInterfaceState.strings.Conversation_VoiceChatMediaRecordingRestricted), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize) let text: String
if let channel = strongSelf.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationInterfaceState.strings.Conversation_LiveStreamMediaRecordingRestricted
} else {
text = strongSelf.presentationInterfaceState.strings.Conversation_VoiceChatMediaRecordingRestricted
}
let tooltipController = TooltipController(content: .text(text), baseFontSize: strongSelf.presentationData.listsFontSize.baseDisplaySize)
strongSelf.mediaRestrictedTooltipController = tooltipController strongSelf.mediaRestrictedTooltipController = tooltipController
strongSelf.mediaRestrictedTooltipControllerMode = false strongSelf.mediaRestrictedTooltipControllerMode = false
tooltipController.dismissed = { [weak tooltipController] _ in tooltipController.dismissed = { [weak tooltipController] _ in

View File

@ -290,7 +290,11 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
case "telegram_message": case "telegram_message":
actionTitle = item.presentationData.strings.Conversation_ViewMessage actionTitle = item.presentationData.strings.Conversation_ViewMessage
case "telegram_voicechat": case "telegram_voicechat":
title = item.presentationData.strings.Conversation_VoiceChat if let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, case let .broadcast = channel.info {
title = item.presentationData.strings.Conversation_LiveStream
} else {
title = item.presentationData.strings.Conversation_VoiceChat
}
if webpage.url.contains("voicechat=") { if webpage.url.contains("voicechat=") {
actionTitle = item.presentationData.strings.Conversation_JoinVoiceChatAsSpeaker actionTitle = item.presentationData.strings.Conversation_JoinVoiceChatAsSpeaker
} else { } else {

View File

@ -279,7 +279,7 @@ private func channelRecentActionsFilterControllerEntries(presentationData: Prese
([.editMessages], presentationData.strings.Channel_AdminLogFilter_EventsEditedMessages), ([.editMessages], presentationData.strings.Channel_AdminLogFilter_EventsEditedMessages),
([.pinnedMessages], presentationData.strings.Channel_AdminLogFilter_EventsPinned), ([.pinnedMessages], presentationData.strings.Channel_AdminLogFilter_EventsPinned),
([.leave], presentationData.strings.Channel_AdminLogFilter_EventsLeaving), ([.leave], presentationData.strings.Channel_AdminLogFilter_EventsLeaving),
([.calls], presentationData.strings.Channel_AdminLogFilter_EventsCalls) ([.calls], presentationData.strings.Channel_AdminLogFilter_EventsLiveStreams)
] ]
} }

View File

@ -714,7 +714,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
(.canInviteUsers, self.presentationData.strings.Channel_AdminLog_CanInviteUsersViaLink), (.canInviteUsers, self.presentationData.strings.Channel_AdminLog_CanInviteUsersViaLink),
(.canPinMessages, self.presentationData.strings.Channel_AdminLog_CanPinMessages), (.canPinMessages, self.presentationData.strings.Channel_AdminLog_CanPinMessages),
(.canAddAdmins, self.presentationData.strings.Channel_AdminLog_CanAddAdmins), (.canAddAdmins, self.presentationData.strings.Channel_AdminLog_CanAddAdmins),
(.canManageCalls, self.presentationData.strings.Channel_AdminLog_CanManageCalls) (.canManageCalls, self.presentationData.strings.Channel_AdminLog_CanManageLiveStreams)
] ]
prevFlags = prevFlags.intersection(TelegramChatAdminRightsFlags.broadcastSpecific) prevFlags = prevFlags.intersection(TelegramChatAdminRightsFlags.broadcastSpecific)
newFlags = newFlags.intersection(TelegramChatAdminRightsFlags.broadcastSpecific) newFlags = newFlags.intersection(TelegramChatAdminRightsFlags.broadcastSpecific)
@ -1122,9 +1122,17 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
let rawText: PresentationStrings.FormattedString let rawText: PresentationStrings.FormattedString
if case .startGroupCall = self.entry.event.action { if case .startGroupCall = self.entry.event.action {
rawText = self.presentationData.strings.Channel_AdminLog_StartedVoiceChat(author?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "") if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
rawText = self.presentationData.strings.Channel_AdminLog_StartedLiveStream(author?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
} else {
rawText = self.presentationData.strings.Channel_AdminLog_StartedVoiceChat(author?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
}
} else { } else {
rawText = self.presentationData.strings.Channel_AdminLog_EndedVoiceChat(author?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "") if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
rawText = self.presentationData.strings.Channel_AdminLog_EndedLiveStream(author?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
} else {
rawText = self.presentationData.strings.Channel_AdminLog_EndedVoiceChat(author?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
}
} }
appendAttributedText(text: rawText, generateEntities: { index in appendAttributedText(text: rawText, generateEntities: { index in

View File

@ -2429,7 +2429,11 @@ final class PeerInfoHeaderNode: ASDisplayNode {
buttonText = presentationData.strings.PeerInfo_ButtonVideoCall buttonText = presentationData.strings.PeerInfo_ButtonVideoCall
buttonIcon = .videoCall buttonIcon = .videoCall
case .voiceChat: case .voiceChat:
buttonText = presentationData.strings.PeerInfo_ButtonVoiceChat if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
buttonText = presentationData.strings.PeerInfo_ButtonLiveStream
} else {
buttonText = presentationData.strings.PeerInfo_ButtonVoiceChat
}
buttonIcon = .voiceChat buttonIcon = .voiceChat
case .mute: case .mute:
if let notificationSettings = notificationSettings, case .muted = notificationSettings.muteState { if let notificationSettings = notificationSettings, case .muted = notificationSettings.muteState {

View File

@ -4060,7 +4060,11 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
case .generic, .scheduledTooLate: case .generic, .scheduledTooLate:
text = strongSelf.presentationData.strings.Login_UnknownError text = strongSelf.presentationData.strings.Login_UnknownError
case .anonymousNotAllowed: case .anonymousNotAllowed:
text = strongSelf.presentationData.strings.VoiceChat_AnonymousDisabledAlertText if let channel = strongSelf.data?.peer as? TelegramChannel, case .broadcast = channel.info {
text = strongSelf.presentationData.strings.LiveStream_AnonymousDisabledAlertText
} else {
text = strongSelf.presentationData.strings.VoiceChat_AnonymousDisabledAlertText
}
} }
strongSelf.controller?.present(textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) strongSelf.controller?.present(textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
})) }))
@ -4404,14 +4408,24 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
items.append(.separator) items.append(.separator)
} }
} }
let createVoiceChatTitle: String
let scheduleVoiceChatTitle: String
if let channel = strongSelf.data?.peer as? TelegramChannel, case .broadcast = channel.info {
createVoiceChatTitle = strongSelf.presentationData.strings.ChannelInfo_CreateLiveStream
scheduleVoiceChatTitle = strongSelf.presentationData.strings.ChannelInfo_ScheduleLiveStream
} else {
createVoiceChatTitle = strongSelf.presentationData.strings.ChannelInfo_CreateVoiceChat
scheduleVoiceChatTitle = strongSelf.presentationData.strings.ChannelInfo_ScheduleVoiceChat
}
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.ChannelInfo_CreateVoiceChat, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/VoiceChat"), color: theme.contextMenu.primaryColor) }, action: { _, f in items.append(.action(ContextMenuActionItem(text: createVoiceChatTitle, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/VoiceChat"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.dismissWithoutContent) f(.dismissWithoutContent)
self?.createAndJoinGroupCall(peerId: peerId, joinAsPeerId: defaultJoinAsPeerId) self?.createAndJoinGroupCall(peerId: peerId, joinAsPeerId: defaultJoinAsPeerId)
}))) })))
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.ChannelInfo_ScheduleVoiceChat, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Schedule"), color: theme.contextMenu.primaryColor) }, action: { _, f in items.append(.action(ContextMenuActionItem(text: scheduleVoiceChatTitle, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Schedule"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.dismissWithoutContent) f(.dismissWithoutContent)
self?.scheduleGroupCall() self?.scheduleGroupCall()