App Badge Selector
5
Swiftgram/SGAppBadgeAssets/BUILD
Normal file
@ -0,0 +1,5 @@
|
||||
filegroup(
|
||||
name = "SGAppBadgeAssets",
|
||||
srcs = glob(["Images.xcassets/**"]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
6
Swiftgram/SGAppBadgeAssets/Images.xcassets/Contents.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
21
Swiftgram/SGAppBadgeAssets/Images.xcassets/DayAppBadge.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Day@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Swiftgram/SGAppBadgeAssets/Images.xcassets/DayAppBadge.imageset/Day@3x.png
vendored
Normal file
After Width: | Height: | Size: 17 KiB |
21
Swiftgram/SGAppBadgeAssets/Images.xcassets/DuckyAppBadge.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Ducky@3.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Swiftgram/SGAppBadgeAssets/Images.xcassets/DuckyAppBadge.imageset/Ducky@3.png
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
21
Swiftgram/SGAppBadgeAssets/Images.xcassets/NightAppBadge.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Night@3-1.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Swiftgram/SGAppBadgeAssets/Images.xcassets/NightAppBadge.imageset/Night@3-1.png
vendored
Normal file
After Width: | Height: | Size: 18 KiB |
21
Swiftgram/SGAppBadgeAssets/Images.xcassets/ProAppBadge.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Pro@3.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Swiftgram/SGAppBadgeAssets/Images.xcassets/ProAppBadge.imageset/Pro@3.png
vendored
Normal file
After Width: | Height: | Size: 18 KiB |
21
Swiftgram/SGAppBadgeAssets/Images.xcassets/SkyAppBadge.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Sky@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Swiftgram/SGAppBadgeAssets/Images.xcassets/SkyAppBadge.imageset/Sky@3x.png
vendored
Normal file
After Width: | Height: | Size: 20 KiB |
21
Swiftgram/SGAppBadgeAssets/Images.xcassets/SparklingAppBadge.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Sparkling@3.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Swiftgram/SGAppBadgeAssets/Images.xcassets/SparklingAppBadge.imageset/Sparkling@3.png
vendored
Normal file
After Width: | Height: | Size: 22 KiB |
21
Swiftgram/SGAppBadgeAssets/Images.xcassets/TitaniumAppBadge.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Titanium@3.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Swiftgram/SGAppBadgeAssets/Images.xcassets/TitaniumAppBadge.imageset/Titanium@3.png
vendored
Normal file
After Width: | Height: | Size: 14 KiB |
@ -12,7 +12,7 @@ import SwiftSignalKit
|
||||
import TelegramUIPreferences
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
public func sgPayWallController(statusSignal: Signal<Int64, NoError>, replacementController: ViewController, presentationData: PresentationData? = nil, SGIAPManager: SGIAPManager, openUrl: @escaping (String, Bool) -> Void /* url, forceExternal */, paymentsEnabled: Bool, canBuyInBeta: Bool, openAppStorePage: @escaping () -> Void, proSupportUrl: String?) -> ViewController {
|
||||
// let theme = presentationData?.theme ?? (UITraitCollection.current.userInterfaceStyle == .dark ? defaultDarkColorPresentationTheme : defaultPresentationTheme)
|
||||
let theme = defaultDarkColorPresentationTheme
|
||||
@ -44,7 +44,7 @@ private let innerShadowWidth: CGFloat = 15.0
|
||||
private let accentColorHex: String = "F1552E"
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct BackgroundView: View {
|
||||
|
||||
var body: some View {
|
||||
@ -96,7 +96,7 @@ struct BackgroundView: View {
|
||||
}
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct SGPayWallFeatureDetails: View {
|
||||
|
||||
let dismissAction: () -> Void
|
||||
@ -225,7 +225,7 @@ struct SGPayWallFeatureDetails: View {
|
||||
}
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct SGProFeatureView: View {
|
||||
let feature: SGProFeature
|
||||
|
||||
@ -267,7 +267,7 @@ enum SGProFeatureId: Hashable {
|
||||
}
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct SGProFeature: Identifiable {
|
||||
|
||||
let id: SGProFeatureId
|
||||
@ -316,7 +316,7 @@ struct SGProFeature: Identifiable {
|
||||
}
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct SGPayWallView: View {
|
||||
@Environment(\.navigationBarHeight) var navigationBarHeight: CGFloat
|
||||
@Environment(\.containerViewLayout) var containerViewLayout: ContainerViewLayout?
|
||||
@ -362,11 +362,11 @@ struct SGPayWallView: View {
|
||||
|
||||
private var features: [SGProFeature] {
|
||||
return [
|
||||
SGProFeature(id: .backup, title: "PayWall.SessionBackup.Title".i18n(lang), subtitle: "PayWall.SessionBackup.Notice".i18n(lang), description: "PayWall.SessionBackup.Description".i18n(lang)),
|
||||
SGProFeature(id: .filter, title: "PayWall.MessageFilter.Title".i18n(lang), subtitle: "PayWall.MessageFilter.Notice".i18n(lang), description: "PayWall.MessageFilter.Description".i18n(lang)),
|
||||
SGProFeature(id: .notifications, title: "PayWall.Notifications.Title".i18n(lang), subtitle: "PayWall.Notifications.Notice".i18n(lang), description: "PayWall.Notifications.Description".i18n(lang)),
|
||||
SGProFeature(id: .toolbar, title: "PayWall.InputToolbar.Title".i18n(lang), subtitle: "PayWall.InputToolbar.Notice".i18n(lang), description: "PayWall.InputToolbar.Description".i18n(lang)),
|
||||
SGProFeature(id: .icons, title: "PayWall.AppIcons.Title".i18n(lang), subtitle: "PayWall.AppIcons.Notice".i18n(lang), description: nil)
|
||||
SGProFeature(id: .filter, title: "PayWall.MessageFilter.Title".i18n(lang), subtitle: "PayWall.MessageFilter.Notice".i18n(lang), description: "PayWall.MessageFilter.Description".i18n(lang)),
|
||||
SGProFeature(id: .icons, title: "PayWall.AppIcons.Title".i18n(lang), subtitle: "PayWall.AppIcons.Notice".i18n(lang), description: nil),
|
||||
SGProFeature(id: .backup, title: "PayWall.SessionBackup.Title".i18n(lang), subtitle: "PayWall.SessionBackup.Notice".i18n(lang), description: "PayWall.SessionBackup.Description".i18n(lang)),
|
||||
SGProFeature(id: .notifications, title: "PayWall.Notifications.Title".i18n(lang), subtitle: "PayWall.Notifications.Notice".i18n(lang), description: "PayWall.Notifications.Description".i18n(lang)),
|
||||
]
|
||||
}
|
||||
|
||||
@ -727,7 +727,7 @@ struct SGPayWallView: View {
|
||||
}
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct FeatureIcon: View {
|
||||
let icon: String
|
||||
let iconColor: Color
|
||||
@ -764,7 +764,7 @@ struct FeatureIcon: View {
|
||||
}
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct FeatureRow<IconContent: View>: View {
|
||||
let icon: IconContent
|
||||
let title: String
|
||||
@ -810,7 +810,7 @@ struct FeatureRow<IconContent: View>: View {
|
||||
|
||||
|
||||
// Confetti
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct ConfettiType {
|
||||
let color: Color
|
||||
let shape: ConfettiShape
|
||||
@ -824,7 +824,7 @@ struct ConfettiType {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
enum ConfettiShape: CaseIterable {
|
||||
case circle
|
||||
case triangle
|
||||
@ -849,7 +849,7 @@ enum ConfettiShape: CaseIterable {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct Triangle: Shape {
|
||||
func path(in rect: CGRect) -> Path {
|
||||
var path = Path()
|
||||
@ -861,7 +861,7 @@ struct Triangle: Shape {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
public struct SlimRectangle: Shape {
|
||||
public func path(in rect: CGRect) -> Path {
|
||||
var path = Path()
|
||||
@ -875,7 +875,7 @@ public struct SlimRectangle: Shape {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
public struct RoundedCross: Shape {
|
||||
public func path(in rect: CGRect) -> Path {
|
||||
var path = Path()
|
||||
@ -896,7 +896,7 @@ public struct RoundedCross: Shape {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct ConfettiModifier: ViewModifier {
|
||||
@Binding var isActive: Bool
|
||||
let duration: Double
|
||||
@ -917,7 +917,7 @@ struct ConfettiModifier: ViewModifier {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct ConfettiPiece: View {
|
||||
let confettiType: ConfettiType
|
||||
let duration: Double
|
||||
@ -943,7 +943,7 @@ struct ConfettiPiece: View {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct FallingModifier: ViewModifier {
|
||||
let distance: CGFloat
|
||||
let duration: Double
|
||||
@ -961,7 +961,7 @@ struct FallingModifier: ViewModifier {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
struct MoveModifier: ViewModifier {
|
||||
let offset: CGSize
|
||||
let duration: Double
|
||||
@ -985,7 +985,7 @@ struct MoveModifier: ViewModifier {
|
||||
}
|
||||
|
||||
// Extension to make it easier to use
|
||||
@available(iOS 13.0, *)
|
||||
|
||||
extension View {
|
||||
func confetti(isActive: Binding<Bool>, duration: Double = 2.0) -> some View {
|
||||
modifier(ConfettiModifier(isActive: isActive, duration: duration))
|
||||
|
@ -16,10 +16,12 @@ swift_library(
|
||||
"//Swiftgram/SGLogging:SGLogging",
|
||||
"//Swiftgram/SGSimpleSettings:SGSimpleSettings",
|
||||
"//Swiftgram/SGStrings:SGStrings",
|
||||
"//Swiftgram/SGAPI:SGAPI",
|
||||
"//Swiftgram/SGAPI:SGAPI",
|
||||
"//Swiftgram/SGAPIToken:SGAPIToken",
|
||||
"//Swiftgram/SGSwiftUI:SGSwiftUI",
|
||||
#
|
||||
"//submodules/SettingsUI:SettingsUI",
|
||||
#
|
||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||
"//submodules/Display:Display",
|
||||
"//submodules/Postbox:Postbox",
|
||||
|
149
Swiftgram/SGProUI/Sources/AppBadgeSelectorController.swift
Normal file
@ -0,0 +1,149 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import SGSwiftUI
|
||||
import SGStrings
|
||||
import SGSimpleSettings
|
||||
import LegacyUI
|
||||
import Display
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
|
||||
|
||||
struct AppBadge: Identifiable, Hashable {
|
||||
let id: UUID = .init()
|
||||
let displayName: String
|
||||
let assetName: String
|
||||
}
|
||||
|
||||
func getAvailableAppBadges() -> [AppBadge] {
|
||||
var appBadges: [AppBadge] = [
|
||||
.init(displayName: "Default", assetName: "Components/AppBadge"),
|
||||
.init(displayName: "Sky", assetName: "SkyAppBadge"),
|
||||
.init(displayName: "Night", assetName: "NightAppBadge"),
|
||||
.init(displayName: "Titanium", assetName: "TitaniumAppBadge"),
|
||||
.init(displayName: "Pro", assetName: "ProAppBadge"),
|
||||
.init(displayName: "Day", assetName: "DayAppBadge"),
|
||||
]
|
||||
|
||||
if SGSimpleSettings.shared.duckyAppIconAvailable {
|
||||
appBadges.append(.init(displayName: "Ducky", assetName: "DuckyAppBadge"))
|
||||
}
|
||||
appBadges += [
|
||||
.init(displayName: "Sparkling", assetName: "SparklingAppBadge"),
|
||||
]
|
||||
|
||||
return appBadges
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
struct AppBadgeSettingsView: View {
|
||||
weak var wrapperController: LegacyController?
|
||||
let context: AccountContext
|
||||
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
@Environment(\.lang) var lang: String
|
||||
|
||||
@State var selectedBadge: AppBadge
|
||||
let availableAppBadges: [AppBadge] = getAvailableAppBadges()
|
||||
|
||||
private enum Layout {
|
||||
static let cardCorner: CGFloat = 12
|
||||
static let imageHeight: CGFloat = 56
|
||||
static let columnSpacing: CGFloat = 16
|
||||
static let horizontalPadding: CGFloat = 20
|
||||
}
|
||||
|
||||
private var columns: [SwiftUI.GridItem] {
|
||||
Array(repeating: GridItem(.flexible(), spacing: Layout.columnSpacing), count: 2)
|
||||
}
|
||||
|
||||
init(wrapperController: LegacyController?, context: AccountContext) {
|
||||
self.wrapperController = wrapperController
|
||||
self.context = context
|
||||
|
||||
for badge in self.availableAppBadges {
|
||||
if badge.assetName == SGSimpleSettings.shared.customAppBadge {
|
||||
self._selectedBadge = State(initialValue: badge)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
self._selectedBadge = State(initialValue: self.availableAppBadges.first!)
|
||||
}
|
||||
|
||||
private func onSelectBadge(_ badge: AppBadge) {
|
||||
self.selectedBadge = badge
|
||||
let image = UIImage(bundleImageName: selectedBadge.assetName) ?? UIImage(bundleImageName: "Components/AppBadge")
|
||||
if self.context.sharedContext.immediateSGStatus.status > 1 {
|
||||
DispatchQueue.main.async {
|
||||
SGSimpleSettings.shared.customAppBadge = selectedBadge.assetName
|
||||
self.context.sharedContext.mainWindow?.badgeView.image = image
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
LazyVGrid(columns: columns, alignment: .center, spacing: Layout.columnSpacing) {
|
||||
ForEach(availableAppBadges) { badge in
|
||||
Button {
|
||||
onSelectBadge(badge)
|
||||
} label: {
|
||||
VStack(spacing: 8) {
|
||||
Image(badge.assetName)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(height: Layout.imageHeight)
|
||||
.accessibilityHidden(true)
|
||||
|
||||
Text(badge.displayName)
|
||||
.font(.footnote)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
.background(Color(colorScheme == .dark ? .secondarySystemBackground : .systemBackground))
|
||||
.cornerRadius(Layout.cardCorner)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: Layout.cardCorner)
|
||||
.stroke(selectedBadge == badge ? Color.accentColor : Color.clear, lineWidth: 2)
|
||||
)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, Layout.horizontalPadding)
|
||||
.padding(.vertical, 24)
|
||||
|
||||
}
|
||||
.background(Color(colorScheme == .light ? .secondarySystemBackground : .systemBackground).ignoresSafeArea())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
public func sgAppBadgeSettingsController(context: AccountContext, presentationData: PresentationData? = nil) -> ViewController {
|
||||
let theme = presentationData?.theme ?? (UITraitCollection.current.userInterfaceStyle == .dark ? defaultDarkColorPresentationTheme : defaultPresentationTheme)
|
||||
let strings = presentationData?.strings ?? defaultPresentationStrings
|
||||
|
||||
let legacyController = LegacySwiftUIController(
|
||||
presentation: .navigation,
|
||||
theme: theme,
|
||||
strings: strings
|
||||
)
|
||||
|
||||
legacyController.statusBar.statusBarStyle = theme.rootController
|
||||
.statusBarStyle.style
|
||||
legacyController.title = "AppBadge.Title".i18n(strings.baseLanguageCode)
|
||||
|
||||
let swiftUIView = SGSwiftUIView<AppBadgeSettingsView>(
|
||||
legacyController: legacyController,
|
||||
manageSafeArea: true,
|
||||
content: {
|
||||
AppBadgeSettingsView(wrapperController: legacyController, context: context)
|
||||
}
|
||||
)
|
||||
let controller = UIHostingController(rootView: swiftUIView, ignoreSafeArea: true)
|
||||
legacyController.bind(controller: controller)
|
||||
|
||||
return legacyController
|
||||
}
|
@ -11,6 +11,7 @@ import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import PresentationDataUtils
|
||||
import TelegramUIPreferences
|
||||
import SettingsUI
|
||||
|
||||
// Optional
|
||||
import SGSimpleSettings
|
||||
@ -19,6 +20,7 @@ import SGLogging
|
||||
|
||||
private enum SGProControllerSection: Int32, SGItemListSection {
|
||||
case base
|
||||
case appearance
|
||||
case notifications
|
||||
case footer
|
||||
}
|
||||
@ -26,6 +28,8 @@ private enum SGProControllerSection: Int32, SGItemListSection {
|
||||
private enum SGProDisclosureLink: String {
|
||||
case sessionBackupManager
|
||||
case messageFilter
|
||||
case appIcons
|
||||
case appBages
|
||||
}
|
||||
|
||||
private enum SGProToggles: String {
|
||||
@ -56,6 +60,10 @@ private func SGProControllerEntries(presentationData: PresentationData) -> [SGPr
|
||||
entries.append(.header(id: id.count, section: .notifications, text: presentationData.strings.Notifications_Title.uppercased(), badge: nil))
|
||||
entries.append(.oneFromManySelector(id: id.count, section: .notifications, settingName: .pinnedMessageNotifications, text: "Notifications.PinnedMessages.Title".i18n(lang), value: "Notifications.PinnedMessages.value.\(SGSimpleSettings.shared.pinnedMessageNotifications)".i18n(lang), enabled: true))
|
||||
entries.append(.oneFromManySelector(id: id.count, section: .notifications, settingName: .mentionsAndRepliesNotifications, text: "Notifications.MentionsAndReplies.Title".i18n(lang), value: "Notifications.MentionsAndReplies.value.\(SGSimpleSettings.shared.mentionsAndRepliesNotifications)".i18n(lang), enabled: true))
|
||||
entries.append(.header(id: id.count, section: .appearance, text: presentationData.strings.Appearance_Title.uppercased(), badge: nil))
|
||||
entries.append(.disclosure(id: id.count, section: .appearance, link: .appIcons, text: presentationData.strings.Appearance_AppIcon))
|
||||
entries.append(.disclosure(id: id.count, section: .appearance, link: .appBages, text: "AppBadge.Title".i18n(lang)))
|
||||
entries.append(.notice(id: id.count, section: .appearance, text: "AppBadge.Notice".i18n(lang)))
|
||||
|
||||
#if DEBUG
|
||||
entries.append(.action(id: id.count, section: .footer, actionType: .resetIAP, text: "Reset Pro", kind: .destructive))
|
||||
@ -124,14 +132,14 @@ public func sgProController(context: AccountContext) -> ViewController {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
switch (link) {
|
||||
case .sessionBackupManager:
|
||||
if #available(iOS 13.0, *) {
|
||||
pushControllerImpl?(sgSessionBackupManagerController(context: context, presentationData: presentationData))
|
||||
} else {
|
||||
presentControllerImpl?(context.sharedContext.makeSGUpdateIOSController(), nil)
|
||||
}
|
||||
pushControllerImpl?(sgSessionBackupManagerController(context: context, presentationData: presentationData))
|
||||
case .messageFilter:
|
||||
if #available(iOS 13.0, *) {
|
||||
pushControllerImpl?(sgMessageFilterController(presentationData: presentationData))
|
||||
pushControllerImpl?(sgMessageFilterController(presentationData: presentationData))
|
||||
case .appIcons:
|
||||
pushControllerImpl?(themeSettingsController(context: context, focusOnItemTag: .icon))
|
||||
case .appBages:
|
||||
if #available(iOS 14.0, *) {
|
||||
pushControllerImpl?(sgAppBadgeSettingsController(context: context, presentationData: presentationData))
|
||||
} else {
|
||||
presentControllerImpl?(context.sharedContext.makeSGUpdateIOSController(), nil)
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ public class SGSimpleSettings {
|
||||
{ let _ = self.startTelescopeWithRearCam },
|
||||
{ let _ = self.hideRecordingButton },
|
||||
{ let _ = self.inputToolbar },
|
||||
{ let _ = self.dismissedSGSuggestions }
|
||||
{ let _ = self.dismissedSGSuggestions },
|
||||
{ let _ = self.customAppBadge }
|
||||
]
|
||||
|
||||
tasks.forEach { task in
|
||||
@ -134,6 +135,7 @@ public class SGSimpleSettings {
|
||||
case duckyAppIconAvailable
|
||||
case transcriptionBackend
|
||||
case translationBackend
|
||||
case customAppBadge
|
||||
}
|
||||
|
||||
public enum DownloadSpeedBoostValues: String, CaseIterable {
|
||||
@ -262,7 +264,8 @@ public class SGSimpleSettings {
|
||||
Keys.dismissedSGSuggestions.rawValue: [],
|
||||
Keys.duckyAppIconAvailable.rawValue: true,
|
||||
Keys.transcriptionBackend.rawValue: TranscriptionBackend.default.rawValue,
|
||||
Keys.translationBackend.rawValue: TranslationBackend.default.rawValue
|
||||
Keys.translationBackend.rawValue: TranslationBackend.default.rawValue,
|
||||
Keys.customAppBadge.rawValue: "",
|
||||
]
|
||||
|
||||
public static let groupDefaultValues: [String: Any] = [
|
||||
@ -485,6 +488,9 @@ public class SGSimpleSettings {
|
||||
|
||||
@UserDefault(key: Keys.translationBackend.rawValue)
|
||||
public var translationBackend: String
|
||||
|
||||
@UserDefault(key: Keys.customAppBadge.rawValue)
|
||||
public var customAppBadge: String
|
||||
}
|
||||
|
||||
extension SGSimpleSettings {
|
||||
|
@ -62,6 +62,8 @@ public class UserDefault<T> /*where T: AllowedUserDefaultTypes*/ {
|
||||
return (userDefaults.bool(forKey: key) as! T)
|
||||
case is String.Type:
|
||||
return (userDefaults.string(forKey: key) as! T)
|
||||
case is Int64.Type:
|
||||
return (Int64(exactly: userDefaults.integer(forKey: key)) as! T)
|
||||
case is Int32.Type:
|
||||
return (Int32(exactly: userDefaults.integer(forKey: key)) as! T)
|
||||
case is Int.Type:
|
||||
|
@ -224,8 +224,8 @@
|
||||
"PayWall.InputToolbar.Notice" = "Bold, Italic, Links? Formatting with just a single tap.";
|
||||
"PayWall.InputToolbar.Description" = "Apply and clear Formatting or insert new lines like a Pro.";
|
||||
|
||||
"PayWall.AppIcons.Title" = "Unique App Icons";
|
||||
"PayWall.AppIcons.Notice" = "Customize Swiftgram look on your home screen.";
|
||||
"PayWall.AppIcons.Title" = "Unique App Icons and Badges";
|
||||
"PayWall.AppIcons.Notice" = "Customize Swiftgram look on your home screen and screenshots.";
|
||||
|
||||
"PayWall.About.Title" = "About Swiftgram Pro";
|
||||
"PayWall.About.Notice" = "Free version of Swiftgram provides dozens of features and improvements over Telegram app. Innovating and keeping Swiftgram in sync with monthly Telegram updates is a huge effort that requires a lot of time and expensive hardware.\n\nSwiftgram is an open-source app that respects your privacy and doesn't bother you with ads. Subscribing to Swiftgram Pro you get access to exclusive features and support an independent developer.";
|
||||
@ -258,3 +258,6 @@
|
||||
"PayWall.ValidationError" = "Validation Error";
|
||||
"PayWall.ValidationError.TryAgain" = "Something went wrong during purchase validation. No worries! Try to Restore Purchases a bit later.";
|
||||
"PayWall.ValidationError.Expired" = "Your subscription expired. Subscribe again to regain access to Pro features.";
|
||||
|
||||
"AppBadge.Title" = "App Badge";
|
||||
"AppBadge.Notice" = "Customize App Badge shown on screenshots";
|
||||
|
@ -346,7 +346,7 @@ objc_library(
|
||||
],
|
||||
)
|
||||
|
||||
SGRESOURCES = ["//Swiftgram/SGSettingsUI:SGUIAssets", "//Swiftgram/SGPayWall:SGPayWallAssets"]
|
||||
SGRESOURCES = ["//Swiftgram/SGSettingsUI:SGUIAssets", "//Swiftgram/SGPayWall:SGPayWallAssets", "//Swiftgram/SGAppBadgeAssets:SGAppBadgeAssets"]
|
||||
|
||||
swift_library(
|
||||
name = "Lib",
|
||||
|
@ -5,7 +5,8 @@ sgsrc = [
|
||||
]
|
||||
|
||||
sgdeps = [
|
||||
"//submodules/Utils/DeviceModel"
|
||||
"//submodules/Utils/DeviceModel",
|
||||
"//Swiftgram/SGSimpleSettings:SGSimpleSettings",
|
||||
]
|
||||
|
||||
swift_library(
|
||||
|
@ -2,6 +2,7 @@ import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import SGSimpleSettings
|
||||
|
||||
private struct WindowLayout: Equatable {
|
||||
let size: CGSize
|
||||
@ -339,7 +340,11 @@ public class Window1 {
|
||||
public init(hostView: WindowHostView, statusBarHost: StatusBarHost?) {
|
||||
self.hostView = hostView
|
||||
self.badgeView = UIImageView()
|
||||
if SGSimpleSettings.shared.status > 1, let image = UIImage(bundleImageName: SGSimpleSettings.shared.customAppBadge) {
|
||||
self.badgeView.image = image
|
||||
} else {
|
||||
self.badgeView.image = UIImage(bundleImageName: "Components/AppBadge")
|
||||
}
|
||||
self.badgeView.isHidden = true
|
||||
|
||||
self.systemUserInterfaceStyle = hostView.systemUserInterfaceStyle
|
||||
|
@ -4102,12 +4102,8 @@ extension SharedAccountContextImpl {
|
||||
|
||||
public func makeSGUpdateIOSController() -> ViewController {
|
||||
let presentationData = self.currentPresentationData.with { $0 }
|
||||
let controller = UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .info(title: nil, text: "Common.UpdateOS".i18n(presentationData.strings.baseLanguageCode), timeout: nil, customUndoText: nil),
|
||||
elevatedLayout: false,
|
||||
action: { _ in return false }
|
||||
)
|
||||
let controller = textAlertController(sharedContext: self, title: nil, text: "Common.UpdateOS".i18n(presentationData.strings.baseLanguageCode), actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
||||
})])
|
||||
return controller
|
||||
}
|
||||
}
|
||||
|