Skip to content

Commit

Permalink
Initial support to change app/content language.
Browse files Browse the repository at this point in the history
R.swift dependency was removed.
Closes #188
  • Loading branch information
pietrocaselani committed May 12, 2019
1 parent 312d0b6 commit d21b69a
Show file tree
Hide file tree
Showing 57 changed files with 754 additions and 180 deletions.
4 changes: 4 additions & 0 deletions .swiftlint.yml
Expand Up @@ -21,6 +21,10 @@ opt_in_rules:
- unused_import
- yoda_condition

type_name:
excluded:
- S # Used for cleaner access to private and static properties

yoda_condition:
severity: error

Expand Down
332 changes: 278 additions & 54 deletions CouchTracker.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Expand Up @@ -2,6 +2,7 @@ import CouchTrackerCore
import RxSwift

final class AppStateViewController: UITableViewController {
private typealias Strings = CouchTrackerCoreStrings
private static let defaultCellIdentifier = "DefaultAppConfigCell"
private let disposeBag = DisposeBag()
private let presenter: AppStatePresenter
Expand All @@ -22,7 +23,7 @@ final class AppStateViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()

title = R.string.localizable.settings()
title = Strings.settings()

view.backgroundColor = Colors.View.background
tableView.separatorColor = Colors.View.background
Expand Down
17 changes: 12 additions & 5 deletions CouchTrackerApp/AppFlow/AppFlowiOSModuleDataSource.swift
@@ -1,18 +1,25 @@
import CouchTrackerCore
import CouchTrackerDebug

final class AppFlowiOSModuleDataSource: AppFlowModuleDataSource {
private typealias Strings = CouchTrackerCoreStrings
var modulePages: [ModulePage]

init() {
init(buildConfig: BuildConfig) {
let moviesView = MoviesManagerModule.setupModule()
let moviesPage = ModulePage(page: moviesView, title: R.string.localizable.movies())
let moviesPage = ModulePage(page: moviesView, title: Strings.movies())

let showsView = ShowsManagerModule.setupModule()
let showsPage = ModulePage(page: showsView, title: R.string.localizable.shows())
let showsPage = ModulePage(page: showsView, title: Strings.shows())

let appConfigsView = AppStateModule.setupModule()
let appConfigsPage = ModulePage(page: appConfigsView, title: R.string.localizable.settings())
let appConfigsPage = ModulePage(page: appConfigsView, title: Strings.settings())

modulePages = [moviesPage, showsPage, appConfigsPage]
if buildConfig.debug {
let debugPage = ModulePage(page: DebugMenuModule.setupModule(), title: "Debug")
modulePages = [moviesPage, showsPage, appConfigsPage, debugPage]
} else {
modulePages = [moviesPage, showsPage, appConfigsPage]
}
}
}
20 changes: 20 additions & 0 deletions CouchTrackerApp/Core/Bundle+CouchTrackerApp.swift
@@ -0,0 +1,20 @@
import CouchTrackerCore

extension Bundle {
// swiftlint:disable force_unwrapping
public static let couchTrackerApp = Bundle(identifier: "io.github.pietrocaselani.CouchTrackerApp")!
// swiftlint:enable force_unwrapping
}

public final class CouchTrackerAppBundleProvider: BundleProvider {
public static let instance = CouchTrackerAppBundleProvider()
public var bundle = Bundle.couchTrackerApp

private init() {}
}

public func couchTrackerAppImage(named name: String,
bundleProvider: BundleProvider = CouchTrackerAppBundleProvider.instance,
compatibleWith traits: UITraitCollection? = nil) -> UIImage? {
return UIImage(named: name, in: bundleProvider.bundle, compatibleWith: traits)
}
2 changes: 1 addition & 1 deletion CouchTrackerApp/Extensions/UIAlertController+Error.swift
@@ -1,7 +1,7 @@
import CouchTrackerCore

extension UIAlertController {
static func createErrorAlert(with title: String = "Error".localized, message: String) -> UIAlertController {
static func createErrorAlert(with title: String = "Error", message: String) -> UIAlertController {
let errorAlert = UIAlertController(title: title, message: message, preferredStyle: .alert)

let okAction = UIAlertAction(title: "Ok", style: .default) { _ in
Expand Down
18 changes: 18 additions & 0 deletions CouchTrackerApp/Images/Images.swift
@@ -0,0 +1,18 @@
public enum Images {
// swiftlint:disable force_unwrapping
public static func filter() -> UIImage {
return couchTrackerAppImage(named: "Filter")!
}

public static func direction() -> UIImage {
return couchTrackerAppImage(named: "Direction")!
}

public static func posterPlacehoder() -> UIImage {
return couchTrackerAppImage(named: "PosterPlacehoder")!
}

public static func backdropPlaceholder() -> UIImage {
return couchTrackerAppImage(named: "BackdropPlaceholder")!
}
}
23 changes: 12 additions & 11 deletions CouchTrackerApp/MovieDetails/MovieDetailsViewController.swift
Expand Up @@ -3,6 +3,7 @@ import Kingfisher
import RxSwift

public final class MovieDetailsViewController: UIViewController {
private typealias Strings = CouchTrackerCoreStrings
private let presenter: MovieDetailsPresenter
private let schedulers: Schedulers
private let disposeBag = DisposeBag()
Expand Down Expand Up @@ -95,7 +96,7 @@ public final class MovieDetailsViewController: UIViewController {

if let traktError = error as? TraktError {
switch traktError {
case .loginRequired: message = R.string.localizable.traktLoginRequired()
case .loginRequired: message = Strings.requiresTraktLogin()
}
} else {
message = error.localizedDescription
Expand All @@ -116,31 +117,31 @@ public final class MovieDetailsViewController: UIViewController {

if let watchedDate = details.watchedAt {
watchedText = formatter.string(from: watchedDate)
watchButtonTitle = R.string.localizable.removeFromHistory()
watchButtonTitle = Strings.removeFromHistory()
} else {
watchedText = R.string.localizable.unwatched()
watchButtonTitle = R.string.localizable.addToHistory()
watchedText = Strings.unwatched()
watchButtonTitle = Strings.addToHistory()
}

let releaseDate = details.releaseDate.map(formatter.string(from:)) ?? R.string.localizable.unknown()
let genres = details.genres?.map { $0.name }.joined(separator: ", ") ?? R.string.localizable.unknown()
let releaseDate = details.releaseDate.map(formatter.string(from:)) ?? Strings.unknown()
let genres = details.genres?.map { $0.name }.joined(separator: ", ") ?? Strings.unknown()

movieView.titleLabel.text = details.title
movieView.taglineLabel.text = details.tagline
movieView.overviewLabel.text = details.overview
movieView.releaseDateLabel.setText(title: "Release date", detail: releaseDate)
movieView.genresLabel.setText(title: "Genres", detail: genres)
movieView.watchedAtLabel.setText(title: "Watched at", detail: watchedText)
movieView.releaseDateLabel.setText(title: "Release date", detail: releaseDate) // TODO: Translate
movieView.genresLabel.setText(title: "Genres", detail: genres) // TODO: Translate
movieView.watchedAtLabel.setText(title: "Watched at", detail: watchedText) // TODO: Translate
movieView.watchButton.button.setTitle(watchButtonTitle, for: .normal)
}

private func show(images: ImagesViewModel) {
if let backdropLink = images.backdropLink {
movieView.backdropImageView.kf.setImage(with: backdropLink.toURL, placeholder: R.image.backdropPlaceholder())
movieView.backdropImageView.kf.setImage(with: backdropLink.toURL, placeholder: Images.backdropPlaceholder())
}

if let posterLink = images.posterLink {
movieView.posterImageView.kf.setImage(with: posterLink.toURL, placeholder: R.image.posterPlacehoder())
movieView.posterImageView.kf.setImage(with: posterLink.toURL, placeholder: Images.posterPlacehoder())
}
}
}
Expand Up @@ -4,6 +4,7 @@ import RxSwift
import Tabman

final class MoviesManagerViewController: TabmanViewController, TMBarCouchTracker {
private typealias Strings = CouchTrackerCoreStrings
private let presenter: MoviesManagerPresenter
private let disposeBag = DisposeBag()
private var pages = [ModulePage]()
Expand All @@ -21,7 +22,7 @@ final class MoviesManagerViewController: TabmanViewController, TMBarCouchTracker
override func viewDidLoad() {
super.viewDidLoad()

title = R.string.localizable.movies()
title = Strings.movies()
navigationItem.title = nil
dataSource = self
delegate = self
Expand Down
17 changes: 9 additions & 8 deletions CouchTrackerApp/Show/Episode/ShowEpisodeViewController.swift
Expand Up @@ -4,6 +4,7 @@ import RxCocoa
import RxSwift

final class ShowEpisodeViewController: UIViewController {
private typealias Strings = CouchTrackerCoreStrings
private let presenter: ShowEpisodePresenter
private let schedulers: Schedulers
private let disposeBag = DisposeBag()
Expand Down Expand Up @@ -67,30 +68,30 @@ final class ShowEpisodeViewController: UIViewController {
}

private func showEmptyView() {
print("Nothing to show here!")
print("Nothing to show here!") // TODO: Translate
}

private func showLoadingView() {
print("Loading view...")
print("Loading view...") // TODO: Translate
}

private func showErrorView(_ error: Error) {
print("Error view: \(error.localizedDescription)")
print("Error view: \(error.localizedDescription)") // TODO: Translate
}

private func updateView(episode: WatchedEpisodeEntity, images: ShowEpisodeImages? = nil) {
episodeView.previewImageView.kf.setImage(with: images?.previewURL)
episodeView.posterImageView.kf.setImage(with: images?.posterURL)

episodeView.titleLabel.text = episode.episode.title
episodeView.overviewLabel.text = episode.episode.overview ?? "No overview"
episodeView.releaseDateLabel.text = episode.episode.firstAired?.shortString() ?? "Unknown".localized
episodeView.watchedAtLabel.text = episode.lastWatched?.shortString() ?? "Unwatched"
episodeView.overviewLabel.text = episode.episode.overview ?? "No overview" // TODO: Translate
episodeView.releaseDateLabel.text = episode.episode.firstAired?.shortString() ?? Strings.unknown()
episodeView.watchedAtLabel.text = episode.lastWatched?.shortString() ?? Strings.unwatched()
episodeView.seasonAndNumberLabel.text = episode.episode.seasonAndNumberFormatted()

let buttonTitle = episode.lastWatched == nil ?
R.string.localizable.addToHistory() :
R.string.localizable.removeFromHistory()
Strings.addToHistory() :
Strings.removeFromHistory()

episodeView.watchButton.button.setTitle(buttonTitle, for: .normal)
}
Expand Down
16 changes: 9 additions & 7 deletions CouchTrackerApp/Show/Overview/ShowOverviewViewController.swift
Expand Up @@ -3,6 +3,7 @@ import Kingfisher
import RxSwift

public final class ShowOverviewViewController: UIViewController {
private typealias Strings = CouchTrackerCoreStrings
private let presenter: ShowOverviewPresenter
private let schedulers: Schedulers
private let disposeBag = DisposeBag()
Expand Down Expand Up @@ -71,25 +72,26 @@ public final class ShowOverviewViewController: UIViewController {
}

func show(details: ShowEntity) {
let firstAired = details.firstAired?.parse() ?? "Unknown".localized

let firstAired = details.firstAired?.parse() ?? Strings.unknown()
let genres = details.genres.map { $0.name }.joined(separator: " | ")
let status = details.status.map { Strings.showStatus(status: $0) } ?? Strings.unknown()

showView.titleLabel.text = details.title ?? Strings.toBeAnnounced()

showView.titleLabel.text = details.title ?? R.string.localizable.tbA()
showView.statusLabel.text = details.status?.rawValue.localized ?? R.string.localizable.unknown()
showView.networkLabel.text = details.network ?? R.string.localizable.unknown()
showView.statusLabel.text = status
showView.networkLabel.text = details.network ?? Strings.unknown()
showView.overviewLabel.text = details.overview
showView.genresLabel.text = genres
showView.releaseDateLabel.text = firstAired
}

func show(images: ImagesViewModel) {
if let posterLink = images.posterLink {
showView.posterImageView.kf.setImage(with: posterLink.toURL, placeholder: R.image.posterPlacehoder())
showView.posterImageView.kf.setImage(with: posterLink.toURL, placeholder: Images.posterPlacehoder())
}

if let backdropLink = images.backdropLink {
showView.backdropImageView.kf.setImage(with: backdropLink.toURL, placeholder: R.image.backdropPlaceholder())
showView.backdropImageView.kf.setImage(with: backdropLink.toURL, placeholder: Images.backdropPlaceholder())
}
}
}
Expand Up @@ -4,6 +4,7 @@ import RxSwift
import Tabman

final class ShowsManagerViewController: TabmanViewController, TMBarCouchTracker {
private typealias Strings = CouchTrackerCoreStrings
private let presenter: ShowsManagerPresenter
private let disposeBag = DisposeBag()
private var pages = [ModulePage]()
Expand All @@ -21,7 +22,7 @@ final class ShowsManagerViewController: TabmanViewController, TMBarCouchTracker
override func viewDidLoad() {
super.viewDidLoad()

title = R.string.localizable.shows()
title = Strings.shows()
navigationItem.title = nil
dataSource = self
delegate = self
Expand Down
23 changes: 12 additions & 11 deletions CouchTrackerApp/Shows/Progress/ShowsProgressViewController.swift
Expand Up @@ -6,6 +6,7 @@ import RxDataSources
import RxSwift

final class ShowsProgressViewController: UIViewController {
private typealias Strings = CouchTrackerCoreStrings
private let presenter: ShowsProgressPresenter
private let cellInteractor: ShowProgressCellInteractor
private let schedulers: Schedulers
Expand Down Expand Up @@ -76,9 +77,9 @@ final class ShowsProgressViewController: UIViewController {

switch state {
case .empty:
showEmptyData(message: "Go watch some shows")
showEmptyData(message: "Go watch some shows") // TODO: Translate
case .filterEmpty:
showEmptyData(message: "A lot of filters!")
showEmptyData(message: "A lot of filters!") // TODO: Translate
case .notLogged:
showNotLogged()
case .loading:
Expand Down Expand Up @@ -111,30 +112,30 @@ final class ShowsProgressViewController: UIViewController {
private func showNotLogged() {
showsView.tableView.isHidden = true
showsView.emptyView.isHidden = false
showsView.emptyView.label.text = R.string.localizable.traktLoginRequired()
showsView.emptyView.label.text = Strings.requiresTraktLogin()
}

private func showLoadingData() {
showsView.tableView.isHidden = true
showsView.emptyView.isHidden = false
showsView.emptyView.label.text = "Loading..."
showsView.emptyView.label.text = "Loading..." // TODO: Translate
}

private func cleanBarButtonItems() {
navigationItem.rightBarButtonItems = nil
}

private func configureBarButtonItems(menu: ShowsProgressMenuOptions) {
let sortTitles = menu.sort.map { $0.rawValue.localized }
let filterTitles = menu.filter.map { $0.rawValue.localized }
let sortTitles = menu.sort.map { $0.rawValue } // TODO: Translate
let filterTitles = menu.filter.map { $0.rawValue } // TODO: Translate

let filterItem = UIBarButtonItem(image: R.image.filter(), style: .plain, target: nil, action: nil)
let filterItem = UIBarButtonItem(image: Images.filter(), style: .plain, target: nil, action: nil)
filterItem.rx.tap.asDriver().drive(onNext: { [weak self] in
self?.showOptions(sorting: sortTitles, filtering: filterTitles,
currentSort: menu.currentSort, currentFilter: menu.currentFilter)
}).disposed(by: disposeBag)

let directionItem = UIBarButtonItem(image: R.image.direction(), style: .plain, target: nil, action: nil)
let directionItem = UIBarButtonItem(image: Images.direction(), style: .plain, target: nil, action: nil)

directionItem.rx.tap.flatMapLatest { [localPresenter = presenter] in
localPresenter.toggleDirection()
Expand All @@ -147,10 +148,10 @@ final class ShowsProgressViewController: UIViewController {

private func showOptions(sorting: [String], filtering: [String],
currentSort: ShowProgressSort, currentFilter: ShowProgressFilter) {
let initialSort = sorting.firstIndex(of: currentSort.rawValue.localized) ?? 0
let initialFilter = filtering.firstIndex(of: currentFilter.rawValue.localized) ?? 0
let initialSort = sorting.firstIndex(of: currentSort.rawValue) ?? 0 // TODO: Translate
let initialFilter = filtering.firstIndex(of: currentFilter.rawValue) ?? 0 // TODO: Translate

let title = "Sort & Filter"
let title = "Sort & Filter" // TODO: Translate
let rows = [sorting, filtering]
let initial = [initialSort, initialFilter]

Expand Down

0 comments on commit d21b69a

Please sign in to comment.