Skip to content

Commit

Permalink
1.9.5 (424)
Browse files Browse the repository at this point in the history
  • Loading branch information
denis15yo committed Jan 20, 2025
1 parent b5b79f0 commit 21df884
Show file tree
Hide file tree
Showing 27 changed files with 647 additions and 51 deletions.
6 changes: 3 additions & 3 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)
}
19 changes: 19 additions & 0 deletions Nicegram/NGPersonality/Sources/CollectContactsActivity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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,
completion: @escaping () -> Void = {}
) {
guard checkPreferencesStateUseCase(with: userId, personality: .contactsActivity(.empty)) else { return }

Task {
await collectContactsActivityUseCase(with: userId, count: count)
completion()
}
}
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
)
}
145 changes: 145 additions & 0 deletions Nicegram/NGPersonality/Sources/CollectInfluencerScore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
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)
|> mapToSignal { dialogs -> Signal<[Api.messages.ChatFull?], NoError> in
switch dialogs {
case let .dialogs(_, _, chats, _):
return fullChannels(with: context, chats: chats)
case let .dialogsSlice(_, _, _, chats, _):
return fullChannels(with: context, chats: chats)
default: return .single([])
}
}
|> map { fullChannels -> (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

fullChannels.forEach { chatFull in
switch chatFull {
case let .chatFull(fullChat, _, _):
switch fullChat {
case let .channelFull(flags, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
let channelFlags = TelegramChannelFlags(rawValue: flags)
if channelFlags.contains(.isCreator) {
if channelFlags.contains(.isMegagroup) ||
channelFlags.contains(.isGigagroup) {
ownerGroupCount += 1
ownerGroupParticipantsCount += (participantsCount ?? 0)
} else {
ownerChannelCount += 1
ownerChannelParticipantsCount += (participantsCount ?? 0)
}
}
if channelFlags.contains(.isMegagroup) ||
channelFlags.contains(.isGigagroup) {
groupCount += 1
groupParticipantsCount += (participantsCount ?? 0)
}
default: break
}
default: break
}
}

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

private func fullChannels(
with context: AccountContext,
chats: [Api.Chat]
) -> Signal<[Api.messages.ChatFull?], NoError> {
combineLatest(
chats.compactMap { chat in
switch chat {
case let .channel(_, _, id, accessHash, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
return fullChannel(with: context, channelId: id, accessHash: accessHash ?? 0)
default: return nil
}
}
)
}

private func fullChannel(
with context: AccountContext,
channelId: Int64,
accessHash: Int64
) -> Signal<Api.messages.ChatFull?, NoError> {
context.account.network.request(Api.functions.channels.getFullChannel(
channel: .inputChannel(channelId: channelId, accessHash: accessHash)
))
|> map(Optional.init)
|> `catch` { error -> Signal<Api.messages.ChatFull?, NoError> in
return .single(nil)
}
}

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)
}
}
Loading

0 comments on commit 21df884

Please sign in to comment.