Skip to content

Commit b909f61

Browse files
authored
Release v0.5.0
2 parents df34c4d + 5711543 commit b909f61

File tree

92 files changed

+3392
-1577
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+3392
-1577
lines changed

ForPDA.xcodeproj/project.pbxproj

Lines changed: 373 additions & 100 deletions
Large diffs are not rendered by default.

ForPDA.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ForPDA.xcodeproj/xcshareddata/xcschemes/ForPDA.xcscheme

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1420"
3+
LastUpgradeVersion = "1500"
44
version = "1.7">
55
<BuildAction
66
parallelizeBuildables = "YES"
@@ -9,7 +9,7 @@
99
<ExecutionAction
1010
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
1111
<ActionContent
12-
title = "Run Script"
12+
title = "Generate build phase file lists"
1313
scriptText = "cd $SOURCE_ROOT&#10;${SOURCE_ROOT}/swiftlint/swiftlint_helper.sh&#10;">
1414
<EnvironmentBuildable>
1515
<BuildableReference

ForPDA/Resources/en.lproj/Localizable.strings

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@
7272
"background.dark" = "Dark";
7373
"background.black" = "Black";
7474
"advanced" = "Advanced";
75-
"fast.loading.system" = "Fast loading";
76-
"fast.loading.system.warning" = "After activiting this option some of last news may not load, also amount of likes and comments can be wrong";
75+
"fast.loading.system" = "Fast loading news";
76+
"fast.loading.system.warning" = "After activiting this option latest news may not load and show wrong amount of comments, and likes may not appear in articles";
7777
"comments.show.likes" = "Show likes";
78-
"comments.show.likes.warning" = "After activiting this option you may see increase of internet traffic from this app, also likes may update with some delay";
78+
"comments.show.likes.warning" = "After activiting this option with \"Fast loading article\" you may see increase in traffic usage";
7979
"account" = "Account";
8080
"sign.out" = "Sign Out";
8181
"about.app" = "About App";

ForPDA/Resources/ru.lproj/Localizable.strings

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@
7272
"background.dark" = "Темный";
7373
"background.black" = "Черный";
7474
"advanced" = "Продвинутые";
75-
"fast.loading.system" = "Быстрая загрузка";
76-
"fast.loading.system.warning" = "При активации этой функции последние статьи могут не отображаться, а также количество лайков и комментариев может не соответствовать реальности";
75+
"fast.loading.system" = "Быстрая загрузка новостей";
76+
"fast.loading.system.warning" = "При активации этой функции статьи могут обновляться с задержкой, отображать неверное количество комментариев, а лайки в статьях не отображаться";
7777
"comments.show.likes" = "Отображать лайки";
78-
"comments.show.likes.warning" = "При активации этой функции может быть увеличеный расход трафика в приложении, также лайки могут отображаться с задержкой";
78+
"comments.show.likes.warning" = "При активации этой функции вместе с \"Быстрая загрузка новостей\" может быть увеличенный расход трафика";
7979
"account" = "Аккаунт";
8080
"sign.out" = "Выйти";
8181
"about.app" = "О приложении";

ForPDA/Sources/Application/AppDelegate.swift

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import RouteComposer
1717
class AppDelegate: UIResponder, UIApplicationDelegate {
1818

1919
@Injected(\.settingsService) private var settingsService
20+
@Injected(\.cookiesService) private var cookiesService
2021

2122
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
2223

@@ -27,13 +28,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2728

2829
return true
2930
}
30-
31-
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
32-
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
33-
}
34-
35-
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) { }
36-
3731
}
3832

3933
// MARK: - Configuration
@@ -68,28 +62,7 @@ extension AppDelegate {
6862

6963
// MARK: Cookies
7064

71-
func configureCookies() {
72-
// We need 3 cookies to authorize: anonymous, member_id, pass_hash
73-
// There's also __fixmid cookie, but it lasts for a second and then removed
74-
if let cookies = HTTPCookieStorage.shared.cookies, cookies.count < 3 {
75-
// Getting saved cookies if present
76-
if let cookiesData = settingsService.getCookiesAsData() {
77-
// Decoding custom Cookie class since HTTPCookie doesn't support Codable
78-
if let cookies = try? JSONDecoder().decode([Cookie].self, from: cookiesData) {
79-
// Force-casting Cookie to HTTPCookie and setting them for 4pda.to domain
80-
let mappedCookies = cookies.map { $0.httpCookie! }
81-
HTTPCookieStorage.shared.setCookies(mappedCookies, for: URL.fourpda, mainDocumentURL: nil)
82-
// WKWebView cookies are added in SceneDelegate
83-
} else {
84-
// Deleting saved cookies in defaults if we can't decode them and logout
85-
settingsService.removeCookies()
86-
settingsService.removeUser()
87-
}
88-
} else {
89-
// Deleting all cookies in case we don't have them saved to prevent different sources of truth and logout
90-
settingsService.removeCookies()
91-
settingsService.removeUser()
92-
}
93-
}
65+
private func configureCookies() {
66+
cookiesService.configureCookies()
9467
}
9568
}

ForPDA/Sources/Application/SceneDelegate.swift

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,50 +13,62 @@ import WebKit
1313
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
1414

1515
@Injected(\.settingsService) private var settingsService
16+
@Injected(\.cookiesService) private var cookiesService
1617

1718
var window: UIWindow?
1819

19-
var webView: WKWebView!
20+
var webView: WKWebView = {
21+
let config = WKWebViewConfiguration()
22+
let webView = WKWebView(frame: .zero, configuration: config)
23+
webView.tag = 666
24+
return webView
25+
}()
2026

2127
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
2228
guard let windowScene = (scene as? UIWindowScene) else { return }
2329
self.window = UIWindow(windowScene: windowScene)
2430

2531
window?.rootViewController = UIViewController()
32+
window?.addSubview(webView)
2633
window?.makeKeyAndVisible()
2734

2835
overrideApplicationThemeStyle(with: settingsService.getAppTheme())
29-
configureWKWebView()
30-
31-
if let url = connectionOptions.urlContexts.first?.url {
36+
cookiesService.syncCookies()
37+
handleNavigation(to: connectionOptions.urlContexts.first?.url)
38+
}
39+
}
40+
41+
extension SceneDelegate {
42+
43+
// MARK: - Navigation
44+
45+
private func handleNavigation(to url: URL?) {
46+
if let url {
3247
// Cold start deeplink
3348
handleDeeplinkUrl(url)
3449
} else {
35-
try? DefaultRouter().navigate(to: RouteMap.tabBarScreen, with: nil)
50+
// Handle all 'try?' on routers? (todo)
51+
// Wrong link is not showing anything (todo)
52+
let testLink = "" // format starts/ends with slash: /2023/../../....../
53+
if testLink.isEmpty {
54+
try? DefaultRouter().navigate(to: RouteMap.newsScreen, with: nil)
55+
} else {
56+
// Testing purposes only
57+
handleDeeplinkUrl(URL(string: "forpda://article\(testLink)")!)
58+
}
3659
}
3760
}
3861

3962
private func handleDeeplinkUrl(_ url: URL) {
4063
if url.absoluteString == "forpda://article//" {
41-
// Если share в браузере не сработал, то открываем новости
42-
// todo обработать нормально
64+
// If share didn't work in browser, fallback to news (also bug with share inside app) (todo)
4365
try? DefaultRouter().navigate(to: RouteMap.newsScreen, with: nil)
4466
} else {
67+
settingsService.setIsDeeplinking(to: true)
4568
let id = url.absoluteString.components(separatedBy: "article/")[1]
46-
let url = "https://4pda.to/\(id)"
69+
let url = URL.fourpda.absoluteString + id
4770
let article = Article(url: url, info: nil)
48-
try? DefaultRouter().navigate(to: RouteMap.articleScreen, with: article)
49-
}
50-
}
51-
52-
private func configureWKWebView() {
53-
let config = WKWebViewConfiguration()
54-
webView = WKWebView(frame: .zero, configuration: config)
55-
webView.tag = 666
56-
window?.addSubview(webView)
57-
58-
for cookie in HTTPCookieStorage.shared.cookies ?? [] {
59-
WKWebsiteDataStore.default().httpCookieStore.setCookie(cookie)
71+
try? DefaultRouter().navigate(to: RouteMap.newArticleScreen, with: article)
6072
}
6173
}
6274

@@ -67,18 +79,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
6779
}
6880
}
6981

70-
func sceneDidDisconnect(_ scene: UIScene) { }
71-
72-
func sceneDidBecomeActive(_ scene: UIScene) { }
73-
74-
func sceneWillResignActive(_ scene: UIScene) { }
75-
76-
func sceneWillEnterForeground(_ scene: UIScene) { }
77-
78-
func sceneDidEnterBackground(_ scene: UIScene) { }
79-
}
80-
81-
extension SceneDelegate {
82+
// MARK: - Themes
83+
8284
func overrideApplicationThemeStyle(with theme: AppTheme) {
8385
window?.overrideUserInterfaceStyle = UIUserInterfaceStyle(rawValue: theme.ordinal())!
8486
}

ForPDA/Sources/Coordinator/LoginInterceptor.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,25 @@
77

88
import UIKit
99
import RouteComposer
10+
import Factory
1011

1112
final class LoginInterceptor<C>: RoutingInterceptor {
13+
14+
@Injected(\.analyticsService) private var analytics
15+
@Injected(\.settingsService) private var settings
1216

1317
typealias Context = C
1418

1519
func perform(with context: Context, completion: @escaping (_: RoutingResult) -> Void) {
16-
guard SettingsService().getUser() == nil else {
20+
guard settings.getUser() == nil else {
21+
analytics.event(Event.Menu.profileOpen.rawValue)
1722
completion(.success)
1823
return
1924
}
2025

21-
let router = DefaultRouter()
2226
do {
23-
try router.navigate(to: LoginConfiguration.loginScreen, with: nil, animated: true) { routingResult in
27+
analytics.event(Event.Menu.loginOpen.rawValue)
28+
try DefaultRouter().navigate(to: LoginConfiguration.loginScreen, with: nil, animated: true) { routingResult in
2429
guard routingResult.isSuccessful,
2530
let viewController = ClassFinder<LoginVC, Any?>().getViewController() else {
2631
completion(.failure(RoutingError.compositionFailed(.init("LoginViewController was not found."))))

ForPDA/Sources/Coordinator/RouteMap.swift

Lines changed: 20 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,20 @@ protocol RouteMapProtocol {
1515

1616
struct RouteMap: RouteMapProtocol {
1717

18-
// MARK: - [TabBar]
19-
20-
static var tabBarScreen: DestinationStep<PDATabBarController, Any?> {
21-
StepAssembly(
22-
finder: ClassFinder(), // В чем разница с <PDATabBarController, Any?>(options: .current, startingPoint: .root)?
23-
factory: CompleteFactoryAssembly(factory: PDATabBarControllerFactory<PDATabBarController, Any?>())
24-
.with(createNewsWithNavigationFactory(), using: PDATabBarController.add())
25-
.with(createForumWithNavigationFactory(), using: PDATabBarController.add())
26-
.with(createMenuWithNavigationFactory(), using: PDATabBarController.add())
27-
.assemble())
28-
.using(GeneralAction.replaceRoot())
29-
.from(GeneralStep.root())
30-
.assemble()
31-
}
32-
3318
// MARK: - [News]
3419

3520
static var newsScreen: DestinationStep<NewsVC, Any?> {
3621
StepAssembly(
37-
finder: ClassFinder<NewsVC, Any?>(),
38-
factory: NilFactory())
39-
.from(tabBarScreen)
22+
finder: ClassFinder(),
23+
factory: NewsFactory()
24+
)
25+
.using(PDANavigationController.push())
26+
.from(SingleContainerStep(
27+
finder: NilFinder(),
28+
factory: NavigationControllerFactory<PDANavigationController, Any?>())
29+
)
30+
.using(GeneralAction.replaceRoot())
31+
.from(GeneralStep.root())
4032
.assemble()
4133
}
4234

@@ -51,22 +43,23 @@ struct RouteMap: RouteMapProtocol {
5143
.assemble()
5244
}
5345

54-
// MARK: - [Forum]
55-
56-
static var forumScreen: DestinationStep<ForumVC, Any?> {
57-
StepAssembly(finder: ClassFinder<ForumVC, Any?>(),
58-
factory: NilFactory())
59-
.from(tabBarScreen)
46+
static var newArticleScreen: DestinationStep<NewArticleVC, Article> {
47+
StepAssembly(
48+
finder: ClassFinder<NewArticleVC, Article>(),
49+
factory: NewArticleFactory())
50+
.using(UINavigationController.push())
51+
.from(newsScreen.expectingContainer())
6052
.assemble()
6153
}
6254

6355
// MARK: - [Menu]
6456

6557
static var menuScreen: DestinationStep<MenuVC, Any?> {
6658
StepAssembly(
67-
finder: ClassFinder<MenuVC, Any?>(),
68-
factory: NilFactory())
69-
.from(tabBarScreen)
59+
finder: ClassFinder(),
60+
factory: MenuFactory())
61+
.using(UINavigationController.push())
62+
.from(newsScreen.expectingContainer())
7063
.assemble()
7164
}
7265

@@ -79,7 +72,6 @@ struct RouteMap: RouteMapProtocol {
7972
.adding(LoginInterceptor())
8073
.using(UINavigationController.push())
8174
.from(menuScreen.expectingContainer())
82-
// .from(GeneralStep.custom(using: ClassFinder<UINavigationController, Any?>()))
8375
.assemble()
8476
}
8577

@@ -115,29 +107,3 @@ struct LoginConfiguration {
115107
// .assemble()
116108
// }
117109
}
118-
119-
// MARK: - NavCon Factories
120-
121-
extension RouteMap {
122-
123-
static func createNewsWithNavigationFactory() -> CompleteFactory<NavigationControllerFactory<UINavigationController, Any?>> {
124-
return CompleteFactoryAssembly(
125-
factory: NavigationControllerFactory())
126-
.with(NewsFactory(), using: UINavigationController.pushAsRoot())
127-
.assemble()
128-
}
129-
130-
static func createForumWithNavigationFactory() -> CompleteFactory<NavigationControllerFactory<UINavigationController, Any?>> {
131-
return CompleteFactoryAssembly(
132-
factory: NavigationControllerFactory())
133-
.with(ForumFactory(), using: UINavigationController.pushAsRoot())
134-
.assemble()
135-
}
136-
137-
static func createMenuWithNavigationFactory() -> CompleteFactory<NavigationControllerFactory<UINavigationController, Any?>> {
138-
return CompleteFactoryAssembly(
139-
factory: NavigationControllerFactory())
140-
.with(MenuFactory(), using: UINavigationController.pushAsRoot())
141-
.assemble()
142-
}
143-
}

ForPDA/Sources/Extensions/NSNotificationName+Ext.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ import Foundation
99

1010
extension NSNotification.Name {
1111
static let userDidChange = Self(rawValue: "userDidChange")
12-
static let darkThemeBackgroundColorDidChange = Self(rawValue: "darkThemeBackgroundColorDidChange")
12+
static let nightModeBackgroundColorDidChange = Self(rawValue: "nightModeBackgroundColorDidChange")
1313
}

0 commit comments

Comments
 (0)