Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/approximate-presence-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Approximate presence tests

on:
pull_request:
branches: [master]
paths:
- 'submodules/TelegramCore/Sources/Donutgram/DonutgramApproximatePresence.swift'
- 'submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramUserPresence.swift'
- 'submodules/TelegramCore/Sources/UpdatePeers.swift'
- 'submodules/TelegramStringFormatting/Sources/PresenceStrings.swift'
- 'submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoData.swift'
- 'Tests/approximate_presence/**'
- '.github/workflows/approximate-presence-tests.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
regression:
runs-on: macos-26
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Check message activity, persistence and status formatting
run: python3 Tests/approximate_presence/run.py
14 changes: 9 additions & 5 deletions Donutgram/DGSettingsUI/Sources/DGFeatureControllers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -481,13 +481,16 @@ func dgProfilesSettingsController(context: AccountContext, focusKey: String? = n
.toggle(12, 1, "regDate", "Показывать дату регистрации", s.showRegistrationDate, true),
.toggle(13, 1, "chatDate", "Показывать дату создания чата", s.showChatCreationDate, true),
.toggle(14, 1, "mutualContact", "Показывать взаимный контакт", s.showMutualContact, true),
.toggle(15, 1, "relativeOnlineTime", "Относительное время онлайна", s.relativeOnlineTime, true),
.toggle(16, 1, "hidePhoneNumber", "Скрыть номер телефона", s.hidePhoneNumber, true),
.info(17, 1, "Номера скрываются только на экране этого устройства. Кто видит ваш номер, настраивается в «Конфиденциальности» Telegram."),
.header(20, 2, "ЗНАЧКИ У ИМЁН"),
.toggle(21, 2, "premiumStatuses", "Скрыть премиум-статусы", s.hidePremiumStatuses, true),
.toggle(22, 2, "hideVerification", "Скрыть верификацию", s.hideVerification, true),
.info(23, 2, "Без галочек официальные аккаунты и подделки выглядят одинаково. Telegram никогда не просит код входа в сообщениях.")
.header(20, 2, "ВРЕМЯ В СЕТИ"),
.toggle(21, 2, "relativeOnlineTime", "Относительное время онлайна", s.relativeOnlineTime, true),
.toggle(22, 2, "approximateLastSeen", "Примерный онлайн", s.approximateLastSeen, true),
.info(23, 2, "«Примерный онлайн» показывает вместо «был(а) недавно» время последнего нового сообщения человека в личном чате или общей группе, с отметкой ~. Отметка держится 3 дня, считаются только сообщения после включения."),
.header(30, 3, "ЗНАЧКИ У ИМЁН"),
.toggle(31, 3, "premiumStatuses", "Скрыть премиум-статусы", s.hidePremiumStatuses, true),
.toggle(32, 3, "hideVerification", "Скрыть верификацию", s.hideVerification, true),
.info(33, 3, "Без галочек официальные аккаунты и подделки выглядят одинаково. Telegram никогда не просит код входа в сообщениях.")
])
return result
}, restartRequiredKeys: ["premiumStatuses", "hideVerification"], toggle: { key, value in
Expand All @@ -498,6 +501,7 @@ func dgProfilesSettingsController(context: AccountContext, focusKey: String? = n
case "chatDate": s.showChatCreationDate = value
case "mutualContact": s.showMutualContact = value
case "relativeOnlineTime": s.relativeOnlineTime = value
case "approximateLastSeen": s.approximateLastSeen = value
case "hidePhoneNumber": s.hidePhoneNumber = value
case "premiumStatuses": s.hidePremiumStatuses = value
case "hideVerification": s.hideVerification = value
Expand Down
3 changes: 3 additions & 0 deletions Donutgram/DGSimpleSettings/Sources/DGLocalization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ private let dgEnglishStrings: [String: String] = [
"Показывать дату создания чата": "Show Chat Creation Date",
"Показывать взаимный контакт": "Show Mutual Contact",
"Относительное время онлайна": "Relative Last Seen Time",
"Примерный онлайн": "Approximate Last Seen",
"«Примерный онлайн» показывает вместо «был(а) недавно» время последнего нового сообщения человека в личном чате или общей группе, с отметкой ~. Отметка держится 3 дня, считаются только сообщения после включения.": "“Approximate Last Seen” shows the time of the person's latest new message in your private chat or a shared group, marked with ~, instead of “last seen recently”. The mark lasts 3 days, and only messages after you turn it on count.",
"Скрыть номер телефона": "Hide Phone Number",
"Отключить рекламу": "Disable Ads",
"Предпросмотр": "Preview",
Expand Down Expand Up @@ -261,6 +263,7 @@ private let dgEnglishStrings: [String: String] = [
"Скрыть реакции в личных чатах": "Hide Reactions in Private Chats",
"Информация": "Information",
"Значки у имён": "Badges Next to Names",
"Время в сети": "Last Seen",
"Пауза музыки": "Pause Music",
"При записи кружков": "While Recording Round Videos",
"При записи голосовых": "While Recording Voice Messages",
Expand Down
26 changes: 26 additions & 0 deletions Donutgram/DGSimpleSettings/Sources/DGSimpleSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ public final class DGSimpleSettings {
static let saveInBotChats = "donutgram.spy.saveInBotChats"
static let saveOwnDeletedMessages = "donutgram.spy.saveOwnDeletedMessages"
static let showDisappearedGifts = "donutgram.spy.showDisappearedGifts"
static let approximateLastSeen = "donutgram.spy.approximateLastSeen"
static let approximateLastSeenStartedAt = "donutgram.spy.approximateLastSeenStartedAt"

static let ghostModeEnabled = "donutgram.ghost.enabled"
static let ghostReadMessages = "donutgram.ghost.readMessages"
Expand Down Expand Up @@ -264,6 +266,10 @@ public final class DGSimpleSettings {
init(defaults: UserDefaults = .standard) {
self.defaults = defaults

if defaults.bool(forKey: Key.approximateLastSeen) && defaults.object(forKey: Key.approximateLastSeenStartedAt) == nil {
defaults.set(Int32(Date().timeIntervalSince1970), forKey: Key.approximateLastSeenStartedAt)
}

if defaults.object(forKey: Key.saveDeletedMessages) == nil {
defaults.set(true, forKey: Key.saveDeletedMessages)
}
Expand Down Expand Up @@ -675,6 +681,26 @@ public final class DGSimpleSettings {
public var showProfileId: Bool { get { bool(Key.showProfileId) } set { setBool(newValue, Key.showProfileId) } }
public var dialogIdFormat: DialogIdFormat { get { DialogIdFormat(rawValue: integer(Key.dialogIdFormat)) ?? .telegramApi } set { setInteger(newValue.rawValue, Key.dialogIdFormat) } }
public var relativeOnlineTime: Bool { get { bool(Key.relativeOnlineTime) } set { setBool(newValue, Key.relativeOnlineTime) } }
public var approximateLastSeen: Bool {
get { bool(Key.approximateLastSeen) }
set {
guard newValue != self.approximateLastSeen else {
return
}
if newValue {
self.defaults.set(Int32(Date().timeIntervalSince1970), forKey: Key.approximateLastSeenStartedAt)
} else {
self.defaults.removeObject(forKey: Key.approximateLastSeenStartedAt)
}
setBool(newValue, Key.approximateLastSeen)
}
}
public var approximateLastSeenStartedAt: Int32? {
guard self.approximateLastSeen, self.defaults.object(forKey: Key.approximateLastSeenStartedAt) != nil else {
return nil
}
return Int32(clamping: self.defaults.integer(forKey: Key.approximateLastSeenStartedAt))
}
public var hidePhoneNumber: Bool { get { bool(Key.hidePhoneNumber) } set { setBool(newValue, Key.hidePhoneNumber) } }
public var showDc: Bool { get { bool(Key.showDc) } set { setBool(newValue, Key.showDc) } }
public var showRegistrationDate: Bool { get { bool(Key.showRegistrationDate) } set { setBool(newValue, Key.showRegistrationDate) } }
Expand Down
Loading
Loading