Skip to content

Commit

Permalink
1.9.5 (427)
Browse files Browse the repository at this point in the history
  • Loading branch information
denis15yo committed Jan 21, 2025
1 parent 6791b44 commit 2f4e897
Show file tree
Hide file tree
Showing 57 changed files with 685 additions and 597 deletions.
12 changes: 6 additions & 6 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Nicegram/NGData/Sources/NGSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,17 @@ public func checkPremium(completion: @escaping (Bool) -> Void) {
}

public func isPremium() -> Bool {
#if DEBUG
return true
#else
if #available(iOS 13.0, *) {
return PremiumContainer.shared
.getPremiumStatusUseCase()
.hasPremiumOnDevice()
} else {
return false
}
#endif
}

public func usetrButton() -> [(Bool, [String])] {
Expand Down
38 changes: 38 additions & 0 deletions Nicegram/NGLab/Sources/RegDate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,44 @@ public func makeNiceRegDateStr(_ date: String) -> String {
}
}

public func getDaysFromRegDate(with id: Int64) -> Signal<Int?, NoError> {
if let dateString = getCachedRegDate(id) {
return .single(days(from: dateString))
} else {
return getRegDate(id)
.skipError()
|> map { dateString in
days(from: dateString)
}
}
}

private func days(from dateString: String, to: Date = Date()) -> Int? {
let monthDateFormatter = DateFormatter()
monthDateFormatter.dateFormat = "yyyy-MM"

let dayDateFormatter = DateFormatter()
dayDateFormatter.dateFormat = "yyyy-MM-dd"

var convertDateFormatter = DateFormatter()

var date: Date?
if let monthDate = monthDateFormatter.date(from: dateString) {
date = monthDate
} else if let dayDate = dayDateFormatter.date(from: dateString) {
date = dayDate
}

if let date {
let calendar = Calendar.current
let components = calendar.dateComponents([.day], from: date, to: to)
if let days = components.day {
return days
}
}

return nil
}

public func resetRegDateCache() -> Void {
UserDefaults.standard.removePersistentDomain(forName: "CachedRegDate")
Expand Down
22 changes: 22 additions & 0 deletions Nicegram/NGPersonality/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")

swift_library(
name = "NGPersonality",
module_name = "NGPersonality",
srcs = glob([
"Sources/**/*.swift",
]),
deps = [
"//submodules/TelegramCore:TelegramCore",
"//submodules/TelegramApi:TelegramApi",
"//submodules/AccountContext:AccountContext",
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
"//submodules/AvatarNode:AvatarNode",
"//Nicegram/NGUtils:NGUtils",
"//Nicegram/NGLab:NGLab",
"@swiftpkg_nicegram_assistant_ios//:FeatPersonality"
],
visibility = [
"//visibility:public",
],
)
32 changes: 32 additions & 0 deletions Nicegram/NGPersonality/Sources/CollectActiveHours.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Foundation
import FeatPersonality

private let container = PersonalityContainer.shared
private let checkPreferencesStateUseCase = container.checkPreferencesStateUseCase()
private let collectActiveHoursUseCase = container.collectActiveHoursUseCase()

public func collectMessageActivity(with userId: Int64) {
guard checkPreferencesStateUseCase(with: userId, personality: .activeHours([])) else { return }

Task {
await collectActiveHoursUseCase.collectMessageActivity(with: userId)
}
}

public func collectScrollActivity(with userId: Int64) {
guard checkPreferencesStateUseCase(with: userId, personality: .activeHours([])) else { return }

collectActiveHoursUseCase.collectScrollActivity(with: userId)
}

public func collectCallActivity(with userId: Int64) {
guard checkPreferencesStateUseCase(with: userId, personality: .activeHours([])) else { return }

collectActiveHoursUseCase.collectCallActivity(with: userId)
}

public func collectVideoActivity(with userId: Int64) {
guard checkPreferencesStateUseCase(with: userId, personality: .activeHours([])) else { return }

collectActiveHoursUseCase.collectVideoActivity(with: userId)
}
17 changes: 17 additions & 0 deletions Nicegram/NGPersonality/Sources/CollectContactsActivity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation
import FeatPersonality

private let container = PersonalityContainer.shared
private let checkPreferencesStateUseCase = container.checkPreferencesStateUseCase()
private let collectContactsActivityUseCase = container.collectContactsActivityUseCase()

public func collectContactsActivity(
with userId: Int64,
count: Int
) {
guard checkPreferencesStateUseCase(with: userId, personality: .contactsActivity(.empty)) else { return }

Task {
await collectContactsActivityUseCase(with: userId, count: count)
}
}
15 changes: 15 additions & 0 deletions Nicegram/NGPersonality/Sources/CollectDailyActivity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import UIKit
import FeatPersonality

private let container = PersonalityContainer.shared
private let checkPreferencesStateUseCase = container.checkPreferencesStateUseCase()
private let collectDailyActivityUseCases = container.collectDailyActivityUseCases()

public func collectDailyActivity(
with userId: Int64,
notificationName: NSNotification.Name
) async {
guard checkPreferencesStateUseCase(with: userId, personality: .dailyActivity(.empty)) else { return }

await collectDailyActivityUseCases(with: userId, notificationName: notificationName)
}
37 changes: 37 additions & 0 deletions Nicegram/NGPersonality/Sources/CollectGhostScore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import TelegramApi
import TelegramCore
import AccountContext
import SwiftSignalKit
import Network
import MtProtoKit
import Postbox
import FeatPersonality

private let container = PersonalityContainer.shared
private let checkCollectStateUseCase = container.checkCollectStateUseCase()
private let checkPreferencesStateUseCase = container.checkPreferencesStateUseCase()
private let collectGhostScoreUseCase = container.collectGhostScoreUseCase()

public func collectGhostScore(
with context: AccountContext
) async {
let id = context.account.peerId.toInt64()
guard checkPreferencesStateUseCase(with: id, personality: .ghostScore(.empty)) else { return }
guard checkCollectStateUseCase(with: id, personality: .ghostScore(.empty)) else { return }

let count = await withCheckedContinuation { continuation in
_ = context.account.postbox.transaction { transaction -> ChatListTotalUnreadState in
transaction.getTotalUnreadState(groupId: .root)
}
.start { state in
let count = state.count(for: .filtered, in: .messages, with: .contact)

continuation.resume(returning: count)
}
}

await collectGhostScoreUseCase(
with: context.account.peerId.toInt64(),
count: count
)
}
130 changes: 130 additions & 0 deletions Nicegram/NGPersonality/Sources/CollectInfluencerScore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import TelegramApi
import TelegramCore
import AccountContext
import SwiftSignalKit
import Network
import MtProtoKit
import Postbox
import FeatPersonality

private let container = PersonalityContainer.shared
private let checkCollectStateUseCase = container.checkCollectStateUseCase()
private let checkPreferencesStateUseCase = container.checkPreferencesStateUseCase()
private let collectInfluencerScoreUseCase = container.collectInfluencerScoreUseCase()

public func collectInfluencerScore(
with context: AccountContext
) async {
let id = context.account.peerId.toInt64()
guard checkPreferencesStateUseCase(with: id, personality: .influencerScore(.empty)) else { return }
guard checkCollectStateUseCase(with: id, personality: .influencerScore(.empty)) else { return }

let result = await withCheckedContinuation { continuation in
_ = influencerScore(with: context)
.start(next: { result in
continuation.resume(returning: result)
})
}

await collectInfluencerScoreUseCase(
with: context.account.peerId.toInt64(),
ownerChannelCount: result.0,
ownerChannelParticipantsCount: result.1,
ownerGroupCount: result.2,
ownerGroupParticipantsCount: result.3,
groupCount: result.4,
groupParticipantsCount: result.5
)
}

private func influencerScore(
with context: AccountContext
) -> Signal<(Int32, Int32, Int32, Int32, Int32, Int32), NoError> {
dialogs(with: context)
|> map { dialogs -> [(PeerId.Namespace, Bool, Int32)] in
switch dialogs {
case let .dialogs(_, _, chats, _):
return chats.compactMap { information(from: $0) }
case let .dialogsSlice(_, _, _, chats, _):
return chats.compactMap { information(from: $0) }
default: return []
}
}
|> map { chats -> (Int32, Int32, Int32, Int32, Int32, Int32) in
var ownerChannelCount: Int32 = 0
var ownerChannelParticipantsCount: Int32 = 0
var ownerGroupCount: Int32 = 0
var ownerGroupParticipantsCount: Int32 = 0

var groupCount: Int32 = 0
var groupParticipantsCount: Int32 = 0

chats.forEach { chat in
if chat.0 == Namespaces.Peer.CloudChannel {
if chat.1 {
ownerChannelCount += 1
ownerChannelParticipantsCount += chat.2
}
} else if chat.0 == Namespaces.Peer.CloudGroup {
if chat.1 {
ownerGroupCount += 1
ownerGroupParticipantsCount += chat.2
}
groupCount += 1
groupParticipantsCount += chat.2
}
}

return (
ownerChannelCount,
ownerChannelParticipantsCount,
ownerGroupCount,
ownerGroupParticipantsCount,
groupCount,
groupParticipantsCount
)
}
}

private func dialogs(
with context: AccountContext
) -> Signal<Api.messages.Dialogs?, NoError> {
context.account.network.request(Api.functions.messages.getDialogs(
flags: 0,
folderId: nil,
offsetDate: 0,
offsetId: 0,
offsetPeer: .inputPeerSelf,
limit: .max,
hash: 0
))
|> map(Optional.init)
|> `catch` { error -> Signal<Api.messages.Dialogs?, NoError> in
return .single(nil)
}
}

private func information(from chat: Api.Chat) -> (PeerId.Namespace, Bool, Int32)? {
switch chat {
case let .chat(flags, _, _, _, participantsCount, _, _, _, _, _):
guard participantsCount > 0 else { return nil }

let isCreator = (flags & (1 << 0)) != 0

return (Namespaces.Peer.CloudGroup, isCreator, participantsCount)
case let .channel(flags, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _):
guard let participantsCount,
participantsCount > 0 else { return nil }

let isCreator = (flags & (1 << 0)) != 0

var type = Namespaces.Peer.CloudChannel
if (flags & Int32(1 << 8)) != 0 {
type = Namespaces.Peer.CloudGroup
}

return (type, isCreator, participantsCount)
case .chatEmpty, .chatForbidden, .channelForbidden:
return nil
}
}
Loading

0 comments on commit 2f4e897

Please sign in to comment.