telegram ui style
iOS CI / Build and Test SwiftUI App (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build Unsigned iOS IPA (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build macOS ZIP (push) Canceled after 0s

This commit is contained in:
wt committed 2026-08-31 09:38:09 +07:00
1 parent 7db327c588
commit f7e22364fd
9 files changed
+663 -476

No files matched your search

+4 -4
View File
@@ -435,12 +435,12 @@
D8C81B9255E9886FB86E0785 /* InlineVideoPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlineVideoPlayer.swift; sourceTree = "<group>"; }; D8C81B9255E9886FB86E0785 /* InlineVideoPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlineVideoPlayer.swift; sourceTree = "<group>"; };
D9BBE412EAF54DFE968B2E54 /* ArchiveSyncCheckpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchiveSyncCheckpoint.swift; sourceTree = "<group>"; }; D9BBE412EAF54DFE968B2E54 /* ArchiveSyncCheckpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchiveSyncCheckpoint.swift; sourceTree = "<group>"; };
D9FCE089ABBF05EF9F55D451 /* VideoNoteRecordingLifecycleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoNoteRecordingLifecycleTests.swift; sourceTree = "<group>"; }; D9FCE089ABBF05EF9F55D451 /* VideoNoteRecordingLifecycleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoNoteRecordingLifecycleTests.swift; sourceTree = "<group>"; };
DF8C531E464C9C4EDE2648C6 /* Luma.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Luma.app; sourceTree = BUILT_PRODUCTS_DIR; }; DF8C531E464C9C4EDE2648C6 /* Luma.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Luma.app; sourceTree = BUILT_PRODUCTS_DIR; };
E619B2C85B0DD2E80653D6D3 /* VideoNoteRecordingCompletionPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoNoteRecordingCompletionPolicy.swift; sourceTree = "<group>"; }; E619B2C85B0DD2E80653D6D3 /* VideoNoteRecordingCompletionPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoNoteRecordingCompletionPolicy.swift; sourceTree = "<group>"; };
E6A5C32B4DACD56DA733A0DB /* ServerInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerInformation.swift; sourceTree = "<group>"; }; E6A5C32B4DACD56DA733A0DB /* ServerInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerInformation.swift; sourceTree = "<group>"; };
E9F226A1F8D82B39630F9CEB /* LumaRoomStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LumaRoomStore.swift; sourceTree = "<group>"; }; E9F226A1F8D82B39630F9CEB /* LumaRoomStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LumaRoomStore.swift; sourceTree = "<group>"; };
EA1D94FE541121DAE9DCE3B0 /* LegacyArchiveImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyArchiveImporter.swift; sourceTree = "<group>"; }; EA1D94FE541121DAE9DCE3B0 /* LegacyArchiveImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyArchiveImporter.swift; sourceTree = "<group>"; };
EA54340DD785335237158BEF /* LumaMac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LumaMac.app; sourceTree = BUILT_PRODUCTS_DIR; }; EA54340DD785335237158BEF /* LumaMac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = LumaMac.app; path = Luma.app; sourceTree = BUILT_PRODUCTS_DIR; };
F0A35C9A7B52458996513382 /* WatchVoiceRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchVoiceRecorder.swift; sourceTree = "<group>"; }; F0A35C9A7B52458996513382 /* WatchVoiceRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchVoiceRecorder.swift; sourceTree = "<group>"; };
F207C1B20DE3780F1754F81D /* ConnectionBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionBanner.swift; sourceTree = "<group>"; }; F207C1B20DE3780F1754F81D /* ConnectionBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionBanner.swift; sourceTree = "<group>"; };
F26F91180E43DE9C135B68C1 /* EmojiCatalog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiCatalog.swift; sourceTree = "<group>"; }; F26F91180E43DE9C135B68C1 /* EmojiCatalog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiCatalog.swift; sourceTree = "<group>"; };
@@ -1295,7 +1295,7 @@
DEVELOPMENT_TEAM = K3AS449A74; DEVELOPMENT_TEAM = K3AS449A74;
INFOPLIST_FILE = "Config/Luma-Info.plist"; INFOPLIST_FILE = "Config/Luma-Info.plist";
INFOPLIST_KEY_CFBundleIconName = AppIcon; INFOPLIST_KEY_CFBundleIconName = AppIcon;
IPHONEOS_DEPLOYMENT_TARGET = 17.0; IPHONEOS_DEPLOYMENT_TARGET = 26.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@@ -1554,7 +1554,7 @@
DEVELOPMENT_TEAM = K3AS449A74; DEVELOPMENT_TEAM = K3AS449A74;
INFOPLIST_FILE = "Config/Luma-Info.plist"; INFOPLIST_FILE = "Config/Luma-Info.plist";
INFOPLIST_KEY_CFBundleIconName = AppIcon; INFOPLIST_KEY_CFBundleIconName = AppIcon;
IPHONEOS_DEPLOYMENT_TARGET = 17.0; IPHONEOS_DEPLOYMENT_TARGET = 26.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@@ -2,53 +2,60 @@ import SwiftUI
struct ConnectionBanner: View { struct ConnectionBanner: View {
@ObservedObject var model: AppModel @ObservedObject var model: AppModel
var text: String
var body: some View { var body: some View {
switch model.connectionStatus { switch model.connectionStatus {
case .connected: case .connected:
if model.isArchiveSyncing || !model.isOMEMOReady { if model.isArchiveSyncing || !model.isOMEMOReady {
banner( banner(
icon: model.isArchiveSyncing ? "arrow.triangle.2.circlepath" : "lock.rotation", // text: model.isArchiveSyncing ? "Синхронизация истории…" : "Публикация ключей OMEMO…",
text: model.isArchiveSyncing ? "Синхронизация истории…" : "Публикация ключей OMEMO…", text: "Обновление",
color: .blue, color: .clear,
progress: true progress: true
) )
} else {
Text(text)
.font(.headline)
} }
case .connecting: case .connecting:
banner(icon: "antenna.radiowaves.left.and.right", text: "Подключение…", color: .orange, progress: true) // banner(icon: "antenna.radiowaves.left.and.right", text: "Подключение…", color: .clear, progress: true)
case .disconnected(let reason): banner(text: "Подключение", color: .clear, progress: true)
HStack(spacing: 8) { case .disconnected:
Image(systemName: "wifi.exclamationmark") banner(text: "Ожидание сети", color: .clear, progress: true)
Text(reason ?? "Нет соединения") // HStack(spacing: 8) {
.lineLimit(1) // Image(systemName: "wifi.exclamationmark")
Spacer() // Text(reason ?? "Нет соединения")
Button("Повторить") { Task { await model.reconnect() } } // .lineLimit(1)
.buttonStyle(.borderless) // Spacer()
.fontWeight(.semibold) // Button { Task { await model.reconnect() } } label: {
} // Label("Обновить", systemImage: "arrow.clockwise")
.font(.caption) // }
.foregroundStyle(.white) // .buttonStyle(.borderless)
.padding(.horizontal, 12) // .fontWeight(.semibold)
.padding(.vertical, 8) // }
.background(Color.red.opacity(0.88)) // .font(.caption)
// .foregroundStyle(.white)
// .padding(.horizontal, 12)
// .padding(.vertical, 8)
//// .background(Color.red.opacity(0.88))
// .background(Color.clear)
} }
} }
private func banner(icon: String, text: String, color: Color, progress: Bool) -> some View { private func banner(text: String, color: Color, progress: Bool) -> some View {
HStack(spacing: 8) { HStack(spacing: 8) {
if progress { if progress {
ProgressView().controlSize(.mini).tint(.white) ProgressView().controlSize(.mini).tint(.white)
} else {
Image(systemName: icon)
} }
Text(text) Text(text)
Spacer() // Spacer()
} }
.font(.caption) .font(.caption)
.foregroundStyle(.white) .foregroundStyle(.white)
.padding(.horizontal, 12) // .padding(.horizontal, 12)
.padding(.vertical, 8) // .padding(.vertical, 8)
.background(color.opacity(0.88)) // .background(color.opacity(0.88))
} }
} }
File diff suppressed because it is too large. Load diff
+3
View File
@@ -13,6 +13,9 @@ struct NewChatView: View {
Section("Контакт") { Section("Контакт") {
TextField("user@example.org", text: $jid) TextField("user@example.org", text: $jid)
.disableAutocorrection(true) .disableAutocorrection(true)
#if os(iOS)
.keyboardType(.emailAddress)
#endif
TextField("Имя (необязательно)", text: $name) TextField("Имя (необязательно)", text: $name)
} }
Section { Section {
+6
View File
@@ -19,6 +19,9 @@ struct NewGroupView: View {
VStack(alignment: .leading, spacing: 12) { VStack(alignment: .leading, spacing: 12) {
TextField("room@conference.example.org", text: $roomJID) TextField("room@conference.example.org", text: $roomJID)
.disableAutocorrection(true) .disableAutocorrection(true)
#if os(iOS)
.keyboardType(.emailAddress)
#endif
TextField("Название (необязательно)", text: $name) TextField("Название (необязательно)", text: $name)
TextField("Ваш псевдоним", text: $nickname) TextField("Ваш псевдоним", text: $nickname)
} }
@@ -31,6 +34,9 @@ struct NewGroupView: View {
VStack(alignment: .leading, spacing: 8) { VStack(alignment: .leading, spacing: 8) {
TextField("alice@example.org, bob@example.org", text: $invitees, axis: .vertical) TextField("alice@example.org, bob@example.org", text: $invitees, axis: .vertical)
.lineLimit(2...5) .lineLimit(2...5)
#if os(iOS)
.keyboardType(.emailAddress)
#endif
Text("Укажите JID через запятую или с новой строки. Если комнаты ещё нет, Prosody создаст её с настройками по умолчанию.") Text("Укажите JID через запятую или с новой строки. Если комнаты ещё нет, Prosody создаст её с настройками по умолчанию.")
.font(.footnote) .font(.footnote)
.foregroundStyle(.secondary) .foregroundStyle(.secondary)
+2 -2
View File
@@ -120,7 +120,7 @@ struct ServerInfoView: View {
.font(.caption) .font(.caption)
} }
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
.listRowBackground(Color.clear) .listRowBackground(Color.gray.opacity(0.16))
} }
private func connectionRows() -> some View { private func connectionRows() -> some View {
@@ -271,7 +271,7 @@ private extension ServerInformation.CapabilityStatus {
var color: Color { var color: Color {
switch self { switch self {
case .success: return Color.green.opacity(0.16) case .success: return Color.green.opacity(0.16)
case .normal: return Color.clear case .normal: return Color.gray.opacity(0.16)
case .warning: return Color.orange.opacity(0.16) case .warning: return Color.orange.opacity(0.16)
case .error: return Color.red.opacity(0.16) case .error: return Color.red.opacity(0.16)
} }
+6 -1
View File
@@ -153,8 +153,13 @@ struct SettingsView: View {
} }
} }
} }
.navigationTitle("Настройки") .navigationTitle("")
.navigationBarTitleDisplayMode(.inline)
.toolbar { .toolbar {
ToolbarItem(placement: .principal) {
Text("Настройки")
.font(.headline)
}
if !presentedAsTab { if !presentedAsTab {
ToolbarItem(placement: .confirmationAction) { ToolbarItem(placement: .confirmationAction) {
Button("Готово") { dismiss() } Button("Готово") { dismiss() }
+1 -1
View File
@@ -388,7 +388,7 @@ final class LumaOMEMO2Module: AbstractPEPModule, XmppModule {
public func decode(message: Message, from: BareJID, serverMsgId: String? = nil) -> DecryptionResult<Message, SignalError> { public func decode(message: Message, from: BareJID, serverMsgId: String? = nil) -> DecryptionResult<Message, SignalError> {
guard context != nil else { return .failure(.unknown) } guard context != nil else { return .failure(.unknown) }
guard let encryptedEl = message.findChild(name: "encrypted", xmlns: Self.XMLNS), guard let encryptedEl = message.firstChild(name: "encrypted", xmlns: Self.XMLNS),
let headerEl = encryptedEl.findChild(name: "header"), let headerEl = encryptedEl.findChild(name: "header"),
let sid = UInt32(headerEl.getAttribute("sid") ?? "") let sid = UInt32(headerEl.getAttribute("sid") ?? "")
else { else {
@@ -29,7 +29,7 @@ final class LumaSaslFailureModule: XmppModuleBase, XmppModule {
func process(stanza: Stanza) throws { func process(stanza: Stanza) throws {
let condition = stanza.findChild()?.name let condition = stanza.findChild()?.name
let text = stanza.findChild(name: "text")?.value let text = stanza.firstChild(name: "text")?.value
lock.lock() lock.lock()
stored = Failure(condition: condition, text: text) stored = Failure(condition: condition, text: text)
lock.unlock() lock.unlock()