多语言开发

This commit is contained in:
澜声世纪 2026-01-27 15:55:28 +08:00
parent 5938c57174
commit 1b625064e6
93 changed files with 402 additions and 353 deletions

View File

@ -3089,7 +3089,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.7; MARKETING_VERSION = 1.0.8;
PRODUCT_BUNDLE_IDENTIFIER = com.lssj.ReaderHive; PRODUCT_BUNDLE_IDENTIFIER = com.lssj.ReaderHive;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -3134,7 +3134,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.7; MARKETING_VERSION = 1.0.8;
PRODUCT_BUNDLE_IDENTIFIER = com.lssj.ReaderHive; PRODUCT_BUNDLE_IDENTIFIER = com.lssj.ReaderHive;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -57,7 +57,7 @@ struct NRStoreAPI {
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<NRIAPOrderModel>) in NRNetwork.request(parameters: param) { (response: NRNetwork.Response<NRIAPOrderModel>) in
guard let data = response.data else { guard let data = response.data else {
NRToast.show(text: "network_error_2".localized) NRToast.show(text: "reader_network_error".localized)
completer?(nil) completer?(nil)
return return
} }

View File

@ -81,7 +81,7 @@ class NRNetwork: NSObject {
} else { } else {
if code == 402, parameters.isToast { if code == 402, parameters.isToast {
DispatchQueue.main.async { DispatchQueue.main.async {
NRToast.show(text: "network_error_1".localized) NRToast.show(text: "reader_kick_out_login".localized)
} }
} }
//token //token
@ -146,7 +146,7 @@ class NRNetwork: NSObject {
res.code = -1 res.code = -1
if parameters.isToast { if parameters.isToast {
DispatchQueue.main.async { DispatchQueue.main.async {
NRToast.show(text: "network_error_2".localized) NRToast.show(text: "reader_network_error".localized)
} }
} }
completion?(res) completion?(res)

View File

@ -21,7 +21,7 @@ class NRAppStartViewController: NRViewController {
var configuration = UIButton.Configuration.plain() var configuration = UIButton.Configuration.plain()
configuration.background.image = UIImage(named: "gradient_color_01") configuration.background.image = UIImage(named: "gradient_color_01")
configuration.background.cornerRadius = 24 configuration.background.cornerRadius = 24
configuration.attributedTitle = AttributedString("Open".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_open_app".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .medium), .font : UIFont.font(ofSize: 14, weight: .medium),
.foregroundColor : UIColor.white .foregroundColor : UIColor.white
])) ]))

View File

@ -13,10 +13,10 @@ class NRTabBarController: UITabBarController {
super.viewDidLoad() super.viewDidLoad()
self.view.backgroundColor = .white self.view.backgroundColor = .white
let nav1 = createNavigationController(title: "My List".localized, image: UIImage(named: "tab_bar_icon_01"), selectedImage: UIImage(named: "tab_bar_icon_01_selected"), viewController: NRMyListViewController()) let nav1 = createNavigationController(title: "reader_my_list".localized, image: UIImage(named: "tab_bar_icon_01"), selectedImage: UIImage(named: "tab_bar_icon_01_selected"), viewController: NRMyListViewController())
let nav2 = createNavigationController(title: "Home".localized, image: UIImage(named: "tab_bar_icon_02"), selectedImage: UIImage(named: "tab_bar_icon_02_selected"), viewController: NRHomeViewController()) let nav2 = createNavigationController(title: "reader_home".localized, image: UIImage(named: "tab_bar_icon_02"), selectedImage: UIImage(named: "tab_bar_icon_02_selected"), viewController: NRHomeViewController())
let nav3 = createNavigationController(title: "Explore".localized, image: UIImage(named: "tab_bar_icon_03"), selectedImage: UIImage(named: "tab_bar_icon_03_selected"), viewController: NRExploreViewController()) let nav3 = createNavigationController(title: "home_explore".localized, image: UIImage(named: "tab_bar_icon_03"), selectedImage: UIImage(named: "tab_bar_icon_03_selected"), viewController: NRExploreViewController())
let nav4 = createNavigationController(title: "Me".localized, image: UIImage(named: "tab_bar_icon_04"), selectedImage: UIImage(named: "tab_bar_icon_04_selected"), viewController: NRMeViewController()) let nav4 = createNavigationController(title: "reader_me".localized, image: UIImage(named: "tab_bar_icon_04"), selectedImage: UIImage(named: "tab_bar_icon_04_selected"), viewController: NRMeViewController())
viewControllers = [nav1, nav2, nav3, nav4] viewControllers = [nav1, nav2, nav3, nav4]

View File

@ -27,7 +27,7 @@ class NRViewController: UIViewController {
}() }()
private(set) lazy var notNetworkingEmptyView: LYEmptyView = { private(set) lazy var notNetworkingEmptyView: LYEmptyView = {
let view = NREmpty.nr_emptyView(image: UIImage(named: "empty_image_02"), title: "not_networking_empty_text".localized, btnTitleStr: "Try again".localized, contentViewOffset: 0) { [weak self] in let view = NREmpty.nr_emptyView(image: UIImage(named: "empty_image_02"), title: "not_networking_empty_text".localized, btnTitleStr: "app_try_again".localized, contentViewOffset: 0) { [weak self] in
self?.handleNotNetworkingEmptyBtn() self?.handleNotNetworkingEmptyBtn()
} }
view.autoShowEmptyView = false view.autoShowEmptyView = false

View File

@ -20,13 +20,13 @@ class NRAppWebViewController: NRWebViewController {
super.viewDidLoad() super.viewDidLoad()
if webUrl == kNRFeedBackListWebUrl { if webUrl == kNRFeedBackListWebUrl {
self.title = "Feedback History".localized self.title = "reader_feedback_history".localized
} else if webUrl == kNRFeedBackHomeWebUrl { } else if webUrl == kNRFeedBackHomeWebUrl {
self.title = "Feedback".localized self.title = "reader_feedback".localized
} else if webUrl == kNRFeedBackDetailWebUrl { } else if webUrl == kNRFeedBackDetailWebUrl {
self.title = "Feedback Details".localized self.title = "reader_feedback_detail".localized
} else if webUrl == kNRLogoutWebUrl { } else if webUrl == kNRLogoutWebUrl {
self.title = "Account Deletion".localized self.title = "reader_account_deletion".localized
} }
} }

View File

@ -37,7 +37,7 @@ class NRExploreNovelContentViewController: NRViewController {
lazy var pageMenuDataSource: JXSegmentedTitleDataSource = { lazy var pageMenuDataSource: JXSegmentedTitleDataSource = {
let dataSource = NRExploreNovelMenuDataSource() let dataSource = NRExploreNovelMenuDataSource()
dataSource.titles = ["Today".localized, "This Week".localized, "This Month".localized] dataSource.titles = ["home_today".localized, "home_week".localized, "home_month".localized]
dataSource.titleNormalFont = .font(ofSize: 12, weight: .regular) dataSource.titleNormalFont = .font(ofSize: 12, weight: .regular)
dataSource.titleSelectedFont = .font(ofSize: 12, weight: .semibold) dataSource.titleSelectedFont = .font(ofSize: 12, weight: .semibold)
dataSource.titleNormalColor = .black.withAlphaComponent(0.5) dataSource.titleNormalColor = .black.withAlphaComponent(0.5)

View File

@ -11,11 +11,11 @@ class NRExploreNovelViewModel: NSObject {
lazy var menuDataArr: [NRExploreNovelMenuItem] = { lazy var menuDataArr: [NRExploreNovelMenuItem] = {
let arr = [ let arr = [
NRExploreNovelMenuItem(type: .genres, title: "Genres".localized, icon: UIImage(named: "explore_genres_icon_01"), selectedIcon: UIImage(named: "explore_genres_icon_01_selected")), NRExploreNovelMenuItem(type: .genres, title: "reader_home_genres".localized, icon: UIImage(named: "explore_genres_icon_01"), selectedIcon: UIImage(named: "explore_genres_icon_01_selected")),
NRExploreNovelMenuItem(type: .trending, title: "Trending".localized, icon: UIImage(named: "explore_trending_icon_01"), selectedIcon: UIImage(named: "explore_trending_icon_01_selected")), NRExploreNovelMenuItem(type: .trending, title: "home_trending".localized, icon: UIImage(named: "explore_trending_icon_01"), selectedIcon: UIImage(named: "explore_trending_icon_01_selected")),
NRExploreNovelMenuItem(type: .topRated, title: "Top Rated".localized, icon: UIImage(named: "explore_top_rated_icon_01"), selectedIcon: UIImage(named: "explore_top_rated_icon_01_selected")), NRExploreNovelMenuItem(type: .topRated, title: "home_topRated".localized, icon: UIImage(named: "explore_top_rated_icon_01"), selectedIcon: UIImage(named: "explore_top_rated_icon_01_selected")),
NRExploreNovelMenuItem(type: .collected, title: "Most Collected".localized, icon: UIImage(named: "explore_most_collected_icon_01"), selectedIcon: UIImage(named: "explore_most_collected_icon_01_selected")), NRExploreNovelMenuItem(type: .collected, title: "home_mostCollected".localized, icon: UIImage(named: "explore_most_collected_icon_01"), selectedIcon: UIImage(named: "explore_most_collected_icon_01_selected")),
NRExploreNovelMenuItem(type: .bestSellers, title: "Best Sellers".localized, icon: UIImage(named: "explore_best_sellers_icon_01"), selectedIcon: UIImage(named: "explore_best_sellers_icon_01_selected")), NRExploreNovelMenuItem(type: .bestSellers, title: "home_bestSellers".localized, icon: UIImage(named: "explore_best_sellers_icon_01"), selectedIcon: UIImage(named: "explore_best_sellers_icon_01_selected")),
] ]
return arr return arr
}() }()

View File

@ -35,7 +35,7 @@ class NRHomeNovelListViewController: NRViewController {
lazy var listTitleView: NRHomeNovelHeaderContentView = { lazy var listTitleView: NRHomeNovelHeaderContentView = {
let view = NRHomeNovelHeaderContentView() let view = NRHomeNovelHeaderContentView()
view.titleLabel.text = "More Stories".localized view.titleLabel.text = "reader_home_title6".localized
return view return view
}() }()

View File

@ -55,7 +55,7 @@ class NRHomeNovelNewViewController: NRViewController {
super.viewDidLoad() super.viewDidLoad()
self.edgesForExtendedLayout = .top self.edgesForExtendedLayout = .top
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
self.title = "New".localized self.title = "reader_new".localized
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")

View File

@ -34,7 +34,7 @@ class NRHomeCoinsPackButton: UIControl {
label.textColors = [UIColor.FFEECA.cgColor, UIColor.FECE_62.cgColor] label.textColors = [UIColor.FFEECA.cgColor, UIColor.FECE_62.cgColor]
label.textStartPoint = .init(x: 0, y: 0.5) label.textStartPoint = .init(x: 0, y: 0.5)
label.textEndPoint = .init(x: 1, y: 0.5) label.textEndPoint = .init(x: 1, y: 0.5)
label.text = "Daily Coins".localized label.text = "reader_daily_coins".localized
label.setContentHuggingPriority(.required, for: .horizontal) label.setContentHuggingPriority(.required, for: .horizontal)
label.setContentCompressionResistancePriority(.required, for: .horizontal) label.setContentCompressionResistancePriority(.required, for: .horizontal)
return label return label

View File

@ -112,7 +112,7 @@ class NRHomeNovelHeaderView: UIView {
lazy var featuredView: NRHomeNovelHotGridView = { lazy var featuredView: NRHomeNovelHotGridView = {
let view = NRHomeNovelHotGridView() let view = NRHomeNovelHotGridView()
view.titleLabel.text = "Featured".localized view.titleLabel.text = "reader_home_title5".localized
return view return view
}() }()

View File

@ -13,7 +13,7 @@ class NRHomeNovelHotGridView: NRHomeNovelNewArrivalsView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
titleLabel.text = "Hot On The Grid".localized titleLabel.text = "reader_home_title2".localized
} }
@MainActor required init?(coder: NSCoder) { @MainActor required init?(coder: NSCoder) {

View File

@ -27,7 +27,7 @@ class NRHomeNovelHotTagView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "Hot Tags".localized label.text = "reader_home_title4".localized
return label return label
}() }()

View File

@ -87,7 +87,7 @@ class NRHomeNovelMustReadTodayCell: FSPagerViewCell {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 14, weight: .medium) label.font = .font(ofSize: 14, weight: .medium)
label.textColor = .white label.textColor = .white
label.text = "Read Now".localized label.text = "reader_read_now".localized
return label return label
}() }()

View File

@ -39,7 +39,7 @@ class NRHomeNovelMustReadTodayView: NRHomeNovelHeaderContentView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
self.titleLabel.text = "Must-Read Today".localized self.titleLabel.text = "reader_banner_title".localized
nr_setupUI() nr_setupUI()
} }

View File

@ -37,7 +37,7 @@ class NRHomeNovelNewArrivalsView: NRHomeNovelHeaderContentView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
self.titleLabel.text = "New Arrivals".localized self.titleLabel.text = "reader_new_arrivals".localized
nr_setupUI() nr_setupUI()
} }

View File

@ -42,7 +42,7 @@ class NRHomeNovelNextView: NRHomeNovelHeaderContentView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
self.titleLabel.text = "Next In View".localized self.titleLabel.text = "reader_home_title3".localized
nr_setupUI() nr_setupUI()
} }

View File

@ -27,7 +27,7 @@ class NRHomeNovelReadWhatView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "read_what_title".localized label.text = "reader_home_title".localized
return label return label
}() }()
@ -35,7 +35,7 @@ class NRHomeNovelReadWhatView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 12, weight: .regular) label.font = .font(ofSize: 12, weight: .regular)
label.textColor = .F_9710_D label.textColor = .F_9710_D
label.text = "read_what_subtitle".localized label.text = "reader_home_title1".localized
return label return label
}() }()
@ -80,7 +80,7 @@ class NRHomeNovelReadWhatView: UIView {
configuration.image = UIImage(named: "arrow_right_icon_02") configuration.image = UIImage(named: "arrow_right_icon_02")
configuration.imagePlacement = .trailing configuration.imagePlacement = .trailing
configuration.imagePadding = 4 configuration.imagePadding = 4
configuration.attributedTitle = AttributedString("Read Now".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_read_now".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .medium), .font : UIFont.font(ofSize: 14, weight: .medium),
.foregroundColor : UIColor.black .foregroundColor : UIColor.black
])) ]))

View File

@ -41,7 +41,7 @@ class NRSearchInputView: UIView {
textField.returnKeyType = .search textField.returnKeyType = .search
textField.font = .font(ofSize: 12, weight: .regular) textField.font = .font(ofSize: 12, weight: .regular)
textField.textColor = .black.withAlphaComponent(0.5) textField.textColor = .black.withAlphaComponent(0.5)
textField.attributedPlaceholder = NSAttributedString(string: "search_placeholder".localized, attributes: [ textField.attributedPlaceholder = NSAttributedString(string: "reader_enter_keywords_search".localized, attributes: [
.font : UIFont.font(ofSize: 12, weight: .regular), .font : UIFont.font(ofSize: 12, weight: .regular),
.foregroundColor : UIColor.black.withAlphaComponent(0.15) .foregroundColor : UIColor.black.withAlphaComponent(0.15)
]) ])

View File

@ -25,7 +25,7 @@ class NRSearchRecordView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "Recent Searches".localized label.text = "reader_searches".localized
return label return label
}() }()

View File

@ -22,7 +22,7 @@ class NRLoginView: NRPanModalContentView {
configuration.background.cornerRadius = 24 configuration.background.cornerRadius = 24
configuration.image = UIImage(named: "apple_login_logo_icon") configuration.image = UIImage(named: "apple_login_logo_icon")
configuration.imagePadding = 8 configuration.imagePadding = 8
configuration.attributedTitle = AttributedString("Login with Apple".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_login_title_apple".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .medium), .font : UIFont.font(ofSize: 14, weight: .medium),
.foregroundColor : UIColor.black .foregroundColor : UIColor.black
])) ]))
@ -40,7 +40,7 @@ class NRLoginView: NRPanModalContentView {
configuration.background.cornerRadius = 24 configuration.background.cornerRadius = 24
configuration.image = UIImage(named: "facebook_login_logo_icon") configuration.image = UIImage(named: "facebook_login_logo_icon")
configuration.imagePadding = 8 configuration.imagePadding = 8
configuration.attributedTitle = AttributedString("Login with Facebook".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_login_title_facebook".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .medium), .font : UIFont.font(ofSize: 14, weight: .medium),
.foregroundColor : UIColor.black .foregroundColor : UIColor.black
])) ]))

View File

@ -24,7 +24,7 @@ class NRMeCoinsContentView: UIView {
private lazy var coinsView: NRMeCoinsView = { private lazy var coinsView: NRMeCoinsView = {
let view = NRMeCoinsView() let view = NRMeCoinsView()
view.title = "Coins".localized view.title = "reader_coins".localized
view.addGestureRecognizer(UITapGestureRecognizer(actionBlock: { [weak self] _ in view.addGestureRecognizer(UITapGestureRecognizer(actionBlock: { [weak self] _ in
guard let self = self else { return } guard let self = self else { return }
let vc = NRWalletViewController() let vc = NRWalletViewController()
@ -35,7 +35,7 @@ class NRMeCoinsContentView: UIView {
private lazy var sendCoinsView: NRMeCoinsView = { private lazy var sendCoinsView: NRMeCoinsView = {
let view = NRMeCoinsView() let view = NRMeCoinsView()
view.title = "Bonus".localized view.title = "reader_my_bonus".localized
view.addGestureRecognizer(UITapGestureRecognizer(actionBlock: { [weak self] _ in view.addGestureRecognizer(UITapGestureRecognizer(actionBlock: { [weak self] _ in
guard let self = self else { return } guard let self = self else { return }
let vc = NRWalletViewController() let vc = NRWalletViewController()
@ -61,7 +61,7 @@ class NRMeCoinsContentView: UIView {
button.endPoint = .init(x: 1, y: 0.5) button.endPoint = .init(x: 1, y: 0.5)
button.layer.cornerRadius = 18 button.layer.cornerRadius = 18
button.layer.masksToBounds = true button.layer.masksToBounds = true
button.setTitle("Top Up".localized, for: .normal) button.setTitle("reader_top_up".localized, for: .normal)
button.setTitleColor(UIColor.white, for: .normal) button.setTitleColor(UIColor.white, for: .normal)
button.titleLabel?.font = .font(ofSize: 14, weight: .medium) button.titleLabel?.font = .font(ofSize: 14, weight: .medium)
return button return button

View File

@ -29,7 +29,7 @@ class NRMeCoinsPackView: UIView {
label.textColors = [UIColor.F_3912_F.cgColor, UIColor.FF_4_A_4_A.cgColor, UIColor.FA_9_B_1_F.cgColor] label.textColors = [UIColor.F_3912_F.cgColor, UIColor.FF_4_A_4_A.cgColor, UIColor.FA_9_B_1_F.cgColor]
label.textStartPoint = .init(x: 0, y: 0.5) label.textStartPoint = .init(x: 0, y: 0.5)
label.textEndPoint = .init(x: 1, y: 0.5) label.textEndPoint = .init(x: 1, y: 0.5)
label.text = "me_coins_pack_title".localized label.text = "reader_my_daily".localized
return label return label
}() }()
@ -37,7 +37,7 @@ class NRMeCoinsPackView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 12, weight: .regular).withItalic() label.font = .font(ofSize: 12, weight: .regular).withItalic()
label.textColor = .F_9710_D label.textColor = .F_9710_D
label.text = "me_coins_pack_subtitle".localized label.text = "reader_my_daily_tips".localized
return label return label
}() }()

View File

@ -67,7 +67,7 @@ class NRMeHeaderView: UITableViewHeaderFooterView {
let button = UIButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in let button = UIButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in
guard let self = self else { return } guard let self = self else { return }
UIPasteboard.general.string = NRLoginManager.manager.userInfo?.customer_id UIPasteboard.general.string = NRLoginManager.manager.userInfo?.customer_id
NRToast.show(text: "Success".localized) NRToast.show(text: "reader_success".localized)
})) }))
button.setImage(UIImage(named: "copy_icon_01"), for: .normal) button.setImage(UIImage(named: "copy_icon_01"), for: .normal)
return button return button
@ -75,7 +75,7 @@ class NRMeHeaderView: UITableViewHeaderFooterView {
private lazy var loginButton: UIButton = { private lazy var loginButton: UIButton = {
var configuration = UIButton.Configuration.plain() var configuration = UIButton.Configuration.plain()
configuration.attributedTitle = AttributedString("Log in".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_login".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .medium), .font : UIFont.font(ofSize: 14, weight: .medium),
.foregroundColor : UIColor.F_9710_D .foregroundColor : UIColor.F_9710_D
])) ]))

View File

@ -16,7 +16,7 @@ class NRMeVipView: UIView {
titleLabel.text = "VIP".localized titleLabel.text = "VIP".localized
let date = Date(timeIntervalSince1970: userInfo?.vip_end_time ?? 0) let date = Date(timeIntervalSince1970: userInfo?.vip_end_time ?? 0)
timeLabel.text = "Expiration Time".localized + "\(date.nr_formatString("yyyy-MM-dd"))" timeLabel.text = "reader_expiration_Time".localized + "\(date.nr_formatString("yyyy-MM-dd"))"
} }
} }

View File

@ -29,9 +29,9 @@ class NRSettingFooterView: UICollectionReusableView {
})) }))
button.configurationUpdateHandler = { [weak self] button in button.configurationUpdateHandler = { [weak self] button in
guard let self = self else { return } guard let self = self else { return }
var title = "Login".localized var title = "reader_login".localized
if userInfo?.is_tourist == false { if userInfo?.is_tourist == false {
title = "Log Out".localized title = "reader_log_out".localized
} }
button.configuration?.attributedTitle = AttributedString(title, attributes: AttributeContainer([ button.configuration?.attributedTitle = AttributedString(title, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .medium), .font : UIFont.font(ofSize: 14, weight: .medium),
@ -62,7 +62,7 @@ class NRSettingFooterView: UICollectionReusableView {
guard let userInfo = userInfo else { return } guard let userInfo = userInfo else { return }
if userInfo.is_tourist == false { if userInfo.is_tourist == false {
let alert = NRAlert(title: "Log Out".localized, detail: "logout_alert_text".localized, topIconImage: UIImage(named: "alert_top_icon_02"), highlightButtonText: "Confirm".localized) let alert = NRAlert(title: "reader_log_out".localized, detail: "reader_log_out_content".localized, topIconImage: UIImage(named: "alert_top_icon_02"), highlightButtonText: "reader_confirm".localized)
alert.highlightHandle = { alert.highlightHandle = {
NRLoginManager.manager.logout(completer: nil) NRLoginManager.manager.logout(completer: nil)
self.viewController?.navigationController?.popViewController(animated: true) self.viewController?.navigationController?.popViewController(animated: true)

View File

@ -13,9 +13,9 @@ class NRAboutViewController: NRViewController {
private lazy var dataArr: [NRMeItem] = { private lazy var dataArr: [NRMeItem] = {
let arr = [ let arr = [
NRMeItem(type: .web, title: "Privacy Policy".localized, url: kNRPrivacyPolicyWebUrl), NRMeItem(type: .web, title: "reader_privacy_policy".localized, url: kNRPrivacyPolicyWebUrl),
NRMeItem(type: .web, title: "User Agreement".localized, url: kNRUserAgreementWebUrl), NRMeItem(type: .web, title: "reader_user_agreement".localized, url: kNRUserAgreementWebUrl),
NRMeItem(type: .web, title: "Visit Website".localized, url: NRWebBaseURL), NRMeItem(type: .web, title: "reader_website".localized, url: NRWebBaseURL),
] ]
return arr return arr
}() }()
@ -39,7 +39,7 @@ class NRAboutViewController: NRViewController {
super.viewDidLoad() super.viewDidLoad()
self.edgesForExtendedLayout = .top self.edgesForExtendedLayout = .top
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
self.title = "About".localized self.title = "reader_about_us".localized
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")

View File

@ -15,7 +15,7 @@ class NRHistoryViewController: NRViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.title = "History".localized self.title = "reader_delete_title_3".localized
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")

View File

@ -12,14 +12,6 @@ class NRLanguageViewController: NRViewController {
private lazy var dataArr: [NRLanguageModel] = [] private lazy var dataArr: [NRLanguageModel] = []
// private lazy var tableView: NRTableView = {
// let tableView = NRTableView(frame: .zero, style: .insetGrouped)
// tableView.delegate = self
// tableView.dataSource = self
// tableView.register(NRLanguageCell.self, forCellReuseIdentifier: "cell")
// return tableView
// }()
private lazy var collectionViewLayout: UICollectionViewFlowLayout = { private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout() let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: UIScreen.width - 32, height: 60) layout.itemSize = .init(width: UIScreen.width - 32, height: 60)
@ -38,7 +30,7 @@ class NRLanguageViewController: NRViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.title = "Language".localized self.title = "reader_choose_language".localized
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")
@ -88,6 +80,16 @@ extension NRLanguageViewController: UICollectionViewDelegate, UICollectionViewDa
return self.dataArr.count return self.dataArr.count
} }
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let model = self.dataArr[indexPath.row]
if model.lang_key == NRLocalizedManager.shared.currentLocalizedKey { return }
guard let key = model.lang_key else { return }
Task {
await NRLocalizedManager.shared.switchLocalized(key)
}
}
} }
extension NRLanguageViewController { extension NRLanguageViewController {

View File

@ -143,14 +143,14 @@ extension NRMeViewController {
private func reloadDataArr() { private func reloadDataArr() {
var dataArr: [NRMeItem] = [] var dataArr: [NRMeItem] = []
dataArr.append(NRMeItem(type: .history, icon: UIImage(named: "history_icon_01"), title: "History".localized)) dataArr.append(NRMeItem(type: .history, icon: UIImage(named: "history_icon_01"), title: "reader_delete_title_3".localized))
dataArr.append(NRMeItem(type: .wallet, icon: UIImage(named: "wallet_icon_01"), title: "My Wallet".localized)) dataArr.append(NRMeItem(type: .wallet, icon: UIImage(named: "wallet_icon_01"), title: "reader_wallet".localized))
// dataArr.append(NRMeItem(type: .language, icon: UIImage(named: "language_icon_01"), title: "Language".localized)) dataArr.append(NRMeItem(type: .language, icon: UIImage(named: "language_icon_01"), title: "reader_choose_language".localized))
dataArr.append(NRMeItem(type: .feedback, icon: UIImage(named: "feedback_icon_01"), title: "Feedback".localized)) dataArr.append(NRMeItem(type: .feedback, icon: UIImage(named: "feedback_icon_01"), title: "reader_feedback".localized))
if NRLoginManager.manager.userInfo?.is_tourist == false { if NRLoginManager.manager.userInfo?.is_tourist == false {
dataArr.append(NRMeItem(type: .settings, icon: UIImage(named: "settings_icon_02"), title: "Settings".localized)) dataArr.append(NRMeItem(type: .settings, icon: UIImage(named: "settings_icon_02"), title: "reader_settings".localized))
} }
dataArr.append(NRMeItem(type: .about, icon: UIImage(named: "about_icon_01"), title: "About".localized)) dataArr.append(NRMeItem(type: .about, icon: UIImage(named: "about_icon_01"), title: "reader_about_us".localized))
self.dataArr = dataArr self.dataArr = dataArr
self.tableView.reloadData() self.tableView.reloadData()
} }

View File

@ -122,7 +122,7 @@ extension NRSettingViewController {
] ]
} else { } else {
return [ return [
NRMeItem(type: .accountDeletion, title: "Account Deletion".localized), NRMeItem(type: .accountDeletion, title: "reader_account_deletion".localized),
// NRMeItem(type: .myUnlocks, title: "My Unlocks".localized), // NRMeItem(type: .myUnlocks, title: "My Unlocks".localized),
] ]
} }

View File

@ -137,8 +137,9 @@ extension NRMyListNovelViewController: UICollectionViewDelegate, UICollectionVie
cell.nr_isEditing = self.nr_isEditing cell.nr_isEditing = self.nr_isEditing
cell.didClickDelete = { [weak self] cell in cell.didClickDelete = { [weak self] cell in
guard let self = self else { return } guard let self = self else { return }
guard let indexPath = collectionView.indexPath(for: cell) else { return }
let alert = NRAlert(title: "detail_collect_alert_title".localized, detail: "detail_collect_alert_text".localized, topIconImage: UIImage(named: "alert_top_icon_04"), highlightButtonText: "Confirm".localized) let alert = NRAlert(title: "detail_collect_alert_title".localized, detail: "detail_collect_alert_text".localized, topIconImage: UIImage(named: "alert_top_icon_04"), highlightButtonText: "reader_confirm".localized)
alert.show() alert.show()
alert.highlightHandle = { [weak self] in alert.highlightHandle = { [weak self] in

View File

@ -25,7 +25,7 @@ class NRMyListViewController: NRViewController {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "My List".localized label.text = "reader_my_list".localized
return label return label
}() }()

View File

@ -33,9 +33,9 @@ class NRReadChapterCatalogModel: NSObject, SmartCodable {
func parserEmpty() { func parserEmpty() {
let chapterModel = NRReadChapterModel() let chapterModel = NRReadChapterModel()
if self.is_lock == true { if self.is_lock == true {
chapterModel.parserEmpty("Chapter Locked".localized) chapterModel.parserEmpty("reader_chapter_locked".localized)
} else { } else {
chapterModel.parserEmpty("Loading".localized) chapterModel.parserEmpty("reader_status_load".localized)
} }
self.chapterModel = chapterModel self.chapterModel = chapterModel
} }

View File

@ -75,7 +75,7 @@ class NRDetailRechargeView: NRPanModalContentView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 12, weight: .regular) label.font = .font(ofSize: 12, weight: .regular)
label.textColor = .black label.textColor = .black
label.text = "Balance".localized + ":" label.text = "reader_balance".localized + ":"
return label return label
}() }()

View File

@ -45,7 +45,7 @@ class NRNovelDetailBottomView: UIView {
vc.novelId = id vc.novelId = id
self.viewController?.navigationController?.pushViewController(vc, animated: true) self.viewController?.navigationController?.pushViewController(vc, animated: true)
})) }))
button.setTitle("Start Reading".localized, for: .normal) button.setTitle("reader_book_startReading".localized, for: .normal)
button.setTitleColor(.white, for: .normal) button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = .font(ofSize: 14, weight: .medium) button.titleLabel?.font = .font(ofSize: 14, weight: .medium)
return button return button
@ -57,7 +57,7 @@ class NRNovelDetailBottomView: UIView {
configuration.contentInsets = .zero configuration.contentInsets = .zero
configuration.imagePadding = 4 configuration.imagePadding = 4
configuration.imagePlacement = .top configuration.imagePlacement = .top
configuration.attributedTitle = AttributedString("Collect".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_book_collects".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 10, weight: .regular), .font : UIFont.font(ofSize: 10, weight: .regular),
.foregroundColor : UIColor.black .foregroundColor : UIColor.black
])) ]))

View File

@ -36,7 +36,7 @@ class NRNovelDetailHeaderView: UIView {
desLabel.text = des desLabel.text = des
contentsTextLabel.text = "## Chapters".localizedReplace(text: "\(model?.episode_total ?? 0)") contentsTextLabel.text = "\(model?.episode_total ?? 0) " + "reader_book_chapters".localized
collectDataView.num = CGFloat(model?.collect_total ?? 0) collectDataView.num = CGFloat(model?.collect_total ?? 0)
heatsDataView.num = CGFloat(model?.heats ?? 0) heatsDataView.num = CGFloat(model?.heats ?? 0)
@ -75,7 +75,7 @@ class NRNovelDetailHeaderView: UIView {
let view = DataView() let view = DataView()
view.num = 0 view.num = 0
view.icon = UIImage(named: "collect_icon_02") view.icon = UIImage(named: "collect_icon_02")
view.title = "Collects".localized view.title = "reader_book_collects".localized
return view return view
}() }()
@ -83,7 +83,7 @@ class NRNovelDetailHeaderView: UIView {
let view = DataView() let view = DataView()
view.num = 0 view.num = 0
view.icon = UIImage(named: "hot_icon_04") view.icon = UIImage(named: "hot_icon_04")
view.title = "Heats".localized view.title = "reader_book_heats".localized
return view return view
}() }()
@ -91,7 +91,7 @@ class NRNovelDetailHeaderView: UIView {
let view = DataView() let view = DataView()
view.num = 0 view.num = 0
view.icon = UIImage(named: "word_icon_01") view.icon = UIImage(named: "word_icon_01")
view.title = "Words".localized view.title = "reader_book_words".localized
return view return view
}() }()
@ -100,7 +100,7 @@ class NRNovelDetailHeaderView: UIView {
view.num = 0 view.num = 0
view.minimumFractionDigits = 1 view.minimumFractionDigits = 1
view.icon = UIImage(named: "rate_icon_01") view.icon = UIImage(named: "rate_icon_01")
view.title = "Rate".localized view.title = "reader_book_rate".localized
return view return view
}() }()
@ -132,7 +132,7 @@ class NRNovelDetailHeaderView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "Synopsis".localized label.text = "reader_book_synopsis".localized
return label return label
}() }()
@ -173,7 +173,7 @@ class NRNovelDetailHeaderView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "Contents" label.text = "reader_book_contents".localized
return label return label
}() }()
@ -200,7 +200,7 @@ class NRNovelDetailHeaderView: UIView {
button.configurationUpdateHandler = { [weak self] button in button.configurationUpdateHandler = { [weak self] button in
guard let self = self else { return } guard let self = self else { return }
button.configuration?.attributedTitle = AttributedString("Completed".localized, attributes: AttributeContainer([ button.configuration?.attributedTitle = AttributedString("reader_book_completed".localized, attributes: AttributeContainer([
// button.configuration?.attributedTitle = AttributedString(self.model?.process ?? "", attributes: AttributeContainer([ // button.configuration?.attributedTitle = AttributedString(self.model?.process ?? "", attributes: AttributeContainer([
.font : UIFont.font(ofSize: 12, weight: .regular), .font : UIFont.font(ofSize: 12, weight: .regular),
.foregroundColor : UIColor.black.withAlphaComponent(0.5) .foregroundColor : UIColor.black.withAlphaComponent(0.5)

View File

@ -43,7 +43,7 @@ class NRVipRetainAlert: NRBaseAlert {
label.textColors = [UIColor.FFEECA.cgColor, UIColor.FECE_62.cgColor] label.textColors = [UIColor.FFEECA.cgColor, UIColor.FECE_62.cgColor]
label.textStartPoint = .init(x: 0, y: 0.5) label.textStartPoint = .init(x: 0, y: 0.5)
label.textEndPoint = .init(x: 1, y: 0.5) label.textEndPoint = .init(x: 1, y: 0.5)
label.text = "retain_alert_text".localized label.text = "vip_retain_alert_text".localized
label.numberOfLines = 0 label.numberOfLines = 0
label.textAlignment = .center label.textAlignment = .center
return label return label

View File

@ -12,7 +12,6 @@ class NRNovelCatalogCell: NRTableViewCell {
var model: NRReadChapterCatalogModel? { var model: NRReadChapterCatalogModel? {
didSet { didSet {
// titleLabel.text = "Chapter.##".localizedReplace(text: model?.episode ?? "")
titleLabel.text = model?.name titleLabel.text = model?.name
lockImageView.isHidden = !(model?.is_lock ?? false) lockImageView.isHidden = !(model?.is_lock ?? false)

View File

@ -41,7 +41,7 @@ class NRNovelReadBottomView: UIView {
}() }()
lazy var nightButton: UIButton = { lazy var nightButton: UIButton = {
let button = self.createButton(title: "Night".localized, nightTitle: "Default".localized, icon: UIImage(named: "night_icon_01"), nightIcon: UIImage(named: "night_icon_02")) let button = self.createButton(title: "reader_night".localized, nightTitle: "reader_default".localized, icon: UIImage(named: "night_icon_01"), nightIcon: UIImage(named: "night_icon_02"))
button.addAction(UIAction(handler: { [weak self] _ in button.addAction(UIAction(handler: { [weak self] _ in
guard let self = self else { return } guard let self = self else { return }
let manager = NRNovelReadSetManager.manager let manager = NRNovelReadSetManager.manager
@ -52,7 +52,7 @@ class NRNovelReadBottomView: UIView {
}() }()
lazy var settingsButton: UIButton = { lazy var settingsButton: UIButton = {
let button = self.createButton(title: "Settings".localized, icon: UIImage(named: "settings_icon_01"), nightIcon: UIImage(named: "settings_icon_03")) let button = self.createButton(title: "reader_settings".localized, icon: UIImage(named: "settings_icon_01"), nightIcon: UIImage(named: "settings_icon_03"))
button.addAction(UIAction(handler: { [weak self] _ in button.addAction(UIAction(handler: { [weak self] _ in
guard let self = self else { return } guard let self = self else { return }
self.viewModel?.showSettingView() self.viewModel?.showSettingView()
@ -74,7 +74,7 @@ class NRNovelReadBottomView: UIView {
self.viewModel?.skipToPrevChapter() self.viewModel?.skipToPrevChapter()
})) }))
button.titleLabel?.font = .font(ofSize: 12, weight: .regular) button.titleLabel?.font = .font(ofSize: 12, weight: .regular)
button.setTitle("Prev".localized, for: .normal) button.setTitle("reader_prev".localized, for: .normal)
button.setTitleColor(.black, for: .normal) button.setTitleColor(.black, for: .normal)
button.setContentHuggingPriority(.required, for: .horizontal) button.setContentHuggingPriority(.required, for: .horizontal)
button.setContentCompressionResistancePriority(.required, for: .horizontal) button.setContentCompressionResistancePriority(.required, for: .horizontal)
@ -92,7 +92,7 @@ class NRNovelReadBottomView: UIView {
} }
})) }))
button.titleLabel?.font = .font(ofSize: 12, weight: .regular) button.titleLabel?.font = .font(ofSize: 12, weight: .regular)
button.setTitle("Next".localized, for: .normal) button.setTitle("reader_next".localized, for: .normal)
button.setTitleColor(.black, for: .normal) button.setTitleColor(.black, for: .normal)
button.setContentHuggingPriority(.required, for: .horizontal) button.setContentHuggingPriority(.required, for: .horizontal)
button.setContentCompressionResistancePriority(.required, for: .horizontal) button.setContentCompressionResistancePriority(.required, for: .horizontal)
@ -130,14 +130,14 @@ class NRNovelReadBottomView: UIView {
if self.viewModel?.novelModel?.is_collect == true { if self.viewModel?.novelModel?.is_collect == true {
button.configuration?.background.backgroundColor = .FFEFD_4 button.configuration?.background.backgroundColor = .FFEFD_4
button.configuration?.image = UIImage(named: "done_icon_01") button.configuration?.image = UIImage(named: "done_icon_01")
button.configuration?.attributedTitle = AttributedString("In My List".localized, attributes: AttributeContainer([ button.configuration?.attributedTitle = AttributedString("reader_bookshelf_tip".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 12, weight: .medium), .font : UIFont.font(ofSize: 12, weight: .medium),
.foregroundColor : UIColor.F_9710_D .foregroundColor : UIColor.F_9710_D
])) ]))
} else { } else {
button.configuration?.background.backgroundColor = .F_9710_D button.configuration?.background.backgroundColor = .F_9710_D
button.configuration?.image = UIImage(named: "+_icon_01") button.configuration?.image = UIImage(named: "+_icon_01")
button.configuration?.attributedTitle = AttributedString("Add to My List".localized, attributes: AttributeContainer([ button.configuration?.attributedTitle = AttributedString("reader_add_bookshelf".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 12, weight: .medium), .font : UIFont.font(ofSize: 12, weight: .medium),
.foregroundColor : UIColor.white .foregroundColor : UIColor.white
])) ]))

View File

@ -53,7 +53,7 @@ class NRNovelReadContentTopView: UIView {
button.configuration?.image = UIImage(named: "arrow_left_icon_04") button.configuration?.image = UIImage(named: "arrow_left_icon_04")
} }
// let text = "Chapter.##".localizedReplace(text: self.catalogModel?.episode ?? "")
let text = self.catalogModel?.name ?? "" let text = self.catalogModel?.name ?? ""

View File

@ -55,7 +55,7 @@ class NRNovelReadFinishHeaderView: UICollectionReusableView {
label.textColors = [UIColor.F_3912_F.cgColor, UIColor.FF_4_A_4_A.cgColor, UIColor.FA_9_B_1_F.cgColor] label.textColors = [UIColor.F_3912_F.cgColor, UIColor.FF_4_A_4_A.cgColor, UIColor.FA_9_B_1_F.cgColor]
label.textStartPoint = .init(x: 0, y: 0.5) label.textStartPoint = .init(x: 0, y: 0.5)
label.textEndPoint = .init(x: 1, y: 0.5) label.textEndPoint = .init(x: 1, y: 0.5)
label.text = "read_finish_title".localized label.text = "reader_book_finished".localized
return label return label
}() }()
@ -65,7 +65,7 @@ class NRNovelReadFinishHeaderView: UICollectionReusableView {
label.textColor = .black.withAlphaComponent(0.5) label.textColor = .black.withAlphaComponent(0.5)
label.textAlignment = .center label.textAlignment = .center
label.numberOfLines = 0 label.numberOfLines = 0
label.text = "read_finish_text".localized label.text = "reader_book_finished_tips".localized
return label return label
}() }()

View File

@ -94,7 +94,7 @@ class NRNovelReadGradeView: NRPanModalContentView {
var configuration = UIButton.Configuration.plain() var configuration = UIButton.Configuration.plain()
configuration.imagePadding = 8 configuration.imagePadding = 8
configuration.image = UIImage(named: "done_icon_02") configuration.image = UIImage(named: "done_icon_02")
configuration.attributedTitle = AttributedString("Rating Submitted!".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_rating_submitted".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 12, weight: .medium), .font : UIFont.font(ofSize: 12, weight: .medium),
.foregroundColor : UIColor.black .foregroundColor : UIColor.black
])) ]))

View File

@ -24,13 +24,13 @@ class NRNovelReadSettingView: NRPanModalContentView {
lazy var lineSpacingView: NRReadSettingSpacingView = { lazy var lineSpacingView: NRReadSettingSpacingView = {
let view = NRReadSettingSpacingView(type: .line) let view = NRReadSettingSpacingView(type: .line)
view.titleLabel.text = "Line Spacing".localized view.titleLabel.text = "reader_line_spacing".localized
return view return view
}() }()
lazy var paragraphSpacingView: NRReadSettingSpacingView = { lazy var paragraphSpacingView: NRReadSettingSpacingView = {
let view = NRReadSettingSpacingView(type: .paragraph) let view = NRReadSettingSpacingView(type: .paragraph)
view.titleLabel.text = "Paragraph Spacing".localized view.titleLabel.text = "reader_paragrapg".localized
return view return view
}() }()

View File

@ -20,12 +20,13 @@ class NRNovelReadStarGradeView: UIView {
didSet { didSet {
let self_rate = model?.self_rate ?? 0 let self_rate = model?.self_rate ?? 0
if self_rate < 0 { if self_rate < 0 {
label.text = "Enjoying this book?".localized label.text = "reader_enjoying_tip".localized
gradeView.grade = 0 gradeView.grade = 0
// gradeView.updateOnTouch = true // gradeView.updateOnTouch = true
// gradeView.fillMode = .full // gradeView.fillMode = .full
} else { } else {
label.text = "My Rate##".localizedReplace(text: NSNumber(value: self_rate).toString(maximumFractionDigits: 1, minimumFractionDigits: 1))
label.text = "reader_my_rate".localized + NSNumber(value: self_rate).toString(maximumFractionDigits: 1, minimumFractionDigits: 1)
gradeView.grade = self_rate / 2 gradeView.grade = self_rate / 2
// gradeView.updateOnTouch = false // gradeView.updateOnTouch = false
// gradeView.fillMode = .precise // gradeView.fillMode = .precise
@ -54,7 +55,7 @@ class NRNovelReadStarGradeView: UIView {
var configuration = UIButton.Configuration.plain() var configuration = UIButton.Configuration.plain()
configuration.imagePadding = 8 configuration.imagePadding = 8
configuration.image = UIImage(named: "done_icon_02") configuration.image = UIImage(named: "done_icon_02")
configuration.attributedTitle = AttributedString("Rating Submitted!".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_rating_submitted".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 12, weight: .medium), .font : UIFont.font(ofSize: 12, weight: .medium),
.foregroundColor : UIColor.black .foregroundColor : UIColor.black
])) ]))

View File

@ -50,12 +50,11 @@ class NRNovelReadTopView: UIView {
color = .white color = .white
} }
button.configuration?.attributedTitle = /*AttributedString("Chapter.##".localizedReplace(text: chapter), attributes:*/ button.configuration?.attributedTitle = AttributedString(chapter, attributes:
AttributedString(chapter, attributes: AttributeContainer([
AttributeContainer([ .font : UIFont.font(ofSize: 12, weight: .regular),
.font : UIFont.font(ofSize: 12, weight: .regular), .foregroundColor : color
.foregroundColor : color ]))
]))
button.configuration?.image = UIImage(named: "arrow_left_icon_03")?.withTintColor(color) button.configuration?.image = UIImage(named: "arrow_left_icon_03")?.withTintColor(color)
} }

View File

@ -17,7 +17,8 @@ class NRNovelReaderCatalogView: UIView {
coverImageView.nr_setImage(novelModel?.image_url) coverImageView.nr_setImage(novelModel?.image_url)
nameLabel.text = novelModel?.name nameLabel.text = novelModel?.name
totalChaptersLabel.text = "## Chapters".localizedReplace(text: "\(novelModel?.episode_total ?? 0)") totalChaptersLabel.text = "\(novelModel?.episode_total ?? 0) " + "reader_book_chapters".localized
} }
} }
@ -152,14 +153,14 @@ class NRNovelReaderCatalogView: UIView {
private func updateProgress() { private func updateProgress() {
guard catalogDataArr.count > 0, self.currentCatalogModel != nil else { guard catalogDataArr.count > 0, self.currentCatalogModel != nil else {
self.redProgressLabel.text = "## read".localizedReplace(text: "0%") self.redProgressLabel.text = "0% " + "reader_read".localized
return return
} }
let currentIndex = getCurrentIndex() let currentIndex = getCurrentIndex()
let progress = NSNumber(value: CGFloat(currentIndex + 1) / CGFloat(catalogDataArr.count) * 100).toString(maximumFractionDigits: 0) let progress = NSNumber(value: CGFloat(currentIndex + 1) / CGFloat(catalogDataArr.count) * 100).toString(maximumFractionDigits: 0)
self.redProgressLabel.text = "## read".localizedReplace(text: "\(progress)%") self.redProgressLabel.text = "\(progress)% " + "reader_read".localized
} }

View File

@ -28,7 +28,7 @@ class NRReadSettingBrightnessView: NRNovelReadSettingItemView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
self.titleLabel.text = "Brightness".localized self.titleLabel.text = "reader_brightness".localized
let imageSize = progressView.thumbImage?.size ?? .zero let imageSize = progressView.thumbImage?.size ?? .zero
contentView.addSubview(progressView) contentView.addSubview(progressView)

View File

@ -54,7 +54,7 @@ class NRReadSettingFontView: NRNovelReadSettingItemView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
self.titleLabel.text = "Font Size".localized self.titleLabel.text = "reader_font_size".localized
nr_setupUI() nr_setupUI()

View File

@ -24,7 +24,7 @@ class NRReadSettingThemeView: NRNovelReadSettingItemView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
self.titleLabel.text = "Theme".localized self.titleLabel.text = "reader_theme".localized
nr_setupUI() nr_setupUI()
updateSelection() updateSelection()
} }

View File

@ -15,7 +15,7 @@ class NRNovelDetailCatalogViewController: NRViewController {
coverImageView.nr_setImage(novelModel?.image_url) coverImageView.nr_setImage(novelModel?.image_url)
nameLabel.text = novelModel?.name nameLabel.text = novelModel?.name
totalChaptersLabel.text = "## Chapters".localizedReplace(text: "\(novelModel?.episode_total ?? 0)") totalChaptersLabel.text = "\(novelModel?.episode_total ?? 0) " + "reader_book_chapters".localized
} }
} }
@ -66,7 +66,7 @@ class NRNovelDetailCatalogViewController: NRViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
self.title = "Catalog".localized self.title = "reader_book_catalog".localized
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")
nr_setupUI() nr_setupUI()

View File

@ -24,7 +24,7 @@ class NRNovelDetailRecommandViewController: NRViewController {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "More Like This".localized label.text = "reader_book_more".localized
return label return label
}() }()

View File

@ -65,7 +65,7 @@ extension NRNovelReadViewModel {
} }
await MainActor.run { await MainActor.run {
let alert = NRAlert(title: "alert_title_01".localized, detail: "alert_detail_01".localized, topIconImage: UIImage(named: "alert_top_icon_01"), highlightButtonText: "Yes, Recommend".localized) let alert = NRAlert(title: "reader_recommend_book".localized, detail: "reader_recommend_book_tip".localized, topIconImage: UIImage(named: "alert_top_icon_01"), highlightButtonText: "reader_recommend_book_ok".localized)
alert.closeHandle = { [weak self] in alert.closeHandle = { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self._backReadPage() self._backReadPage()

View File

@ -126,16 +126,16 @@ class NRPayItem: NSObject, SmartCodable {
func getVipTitle() -> String? { func getVipTitle() -> String? {
switch self.vip_type_key { switch self.vip_type_key {
case .week: case .week:
return "Weekly VIP".localized return "pay_template_1018".localized
case .month: case .month:
return "Monthly VIP".localized return "month_vip".localized
case .quarter: case .quarter:
return "Quarterly VIP".localized return "three_months_vip".localized
case .year: case .year:
return "Yearly VIP".localized return "yearly_vip".localized
default: default:
return nil return nil

View File

@ -19,7 +19,7 @@ class NRCoinsPackBuyView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = ._714_A_1_B label.textColor = ._714_A_1_B
label.text = "Weekly Refills".localized label.text = "weekly_refill".localized
return label return label
}() }()

View File

@ -25,7 +25,7 @@ class NRCoinsPackClaimCell: UICollectionViewCell {
titleAtt.yy_color = ._714_A_1_B titleAtt.yy_color = ._714_A_1_B
titleAtt.yy_font = .font(ofSize: 14, weight: .bold) titleAtt.yy_font = .font(ofSize: 14, weight: .bold)
let day = "Day".localized let day = "d".localized
let dayAtt = NSMutableAttributedString(string: " (\(day) \(model?.day_text ?? ""))") let dayAtt = NSMutableAttributedString(string: " (\(day) \(model?.day_text ?? ""))")
dayAtt.yy_color = ._946_A_37 dayAtt.yy_color = ._946_A_37
dayAtt.yy_font = .font(ofSize: 14, weight: .regular) dayAtt.yy_font = .font(ofSize: 14, weight: .regular)
@ -65,7 +65,7 @@ class NRCoinsPackClaimCell: UICollectionViewCell {
private lazy var coinsView1: CoinsView = { private lazy var coinsView1: CoinsView = {
let view = CoinsView() let view = CoinsView()
view.title = "Total Reward".localized view.title = "reader_total_reward".localized
return view return view
}() }()
@ -107,7 +107,7 @@ class NRCoinsPackClaimCell: UICollectionViewCell {
])) ]))
button.configuration?.attributedTitle = AttributedString("Claim".localized, attributes: AttributeContainer([ button.configuration?.attributedTitle = AttributedString("reader_claim".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .bold), .font : UIFont.font(ofSize: 14, weight: .bold),
.foregroundColor : UIColor._714_A_1_B .foregroundColor : UIColor._714_A_1_B
])) ]))
@ -118,7 +118,7 @@ class NRCoinsPackClaimCell: UICollectionViewCell {
button.colors = [UIColor.E_0_E_0_E_0.cgColor, UIColor.E_0_E_0_E_0.cgColor] button.colors = [UIColor.E_0_E_0_E_0.cgColor, UIColor.E_0_E_0_E_0.cgColor]
button.layer.borderColor = UIColor.clear.cgColor button.layer.borderColor = UIColor.clear.cgColor
button.configuration?.attributedTitle = AttributedString("Claimed".localized, attributes: AttributeContainer([ button.configuration?.attributedTitle = AttributedString("reader_claimed".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .bold), .font : UIFont.font(ofSize: 14, weight: .bold),
.foregroundColor : UIColor.black.withAlphaComponent(0.25) .foregroundColor : UIColor.black.withAlphaComponent(0.25)
])) ]))

View File

@ -22,7 +22,7 @@ class NRCoinsPackClaimView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = ._714_A_1_B label.textColor = ._714_A_1_B
label.text = "Active Refills".localized label.text = "reader_active_refills".localized
return label return label
}() }()

View File

@ -12,10 +12,10 @@ class NRCoinsPackConfirmTitleView: NRCoinsPackConfirmItemView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
titleLabel.text = "Bonus You Get".localized titleLabel.text = "reader_bonus_you_get".localized
let view1 = getItemView(image: UIImage(named: "gift_icon_02"), text: "Weekly Refill Package".localized) let view1 = getItemView(image: UIImage(named: "gift_icon_02"), text: "reader_weekly_refill_package".localized)
let view2 = getItemView(image: UIImage(named: "calendar_icon_01"), text: "Daily Bonuses".localized) let view2 = getItemView(image: UIImage(named: "calendar_icon_01"), text: "reader_dailu_bonuses".localized)
addSubview(view1) addSubview(view1)
addSubview(view2) addSubview(view2)

View File

@ -43,7 +43,7 @@ class NRCoinsPackConfirmView: NRPanModalContentView {
let label = NRLabel() let label = NRLabel()
label.font = .font(ofSize: 24, weight: .bold) label.font = .font(ofSize: 24, weight: .bold)
label.textColorImage = UIImage(named: "gradient_color_01") label.textColorImage = UIImage(named: "gradient_color_01")
label.text = "What You Get".localized label.text = "reader_what_you_get".localized
return label return label
}() }()

View File

@ -34,20 +34,20 @@ class NRCoinsPackHeaderView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = ._714_A_1_B label.textColor = ._714_A_1_B
label.text = "Rewards Overview".localized label.text = "reader_rewards_overview".localized
return label return label
}() }()
private lazy var coinsView1: CoinsView = { private lazy var coinsView1: CoinsView = {
let view = CoinsView() let view = CoinsView()
view.title = "Weekly Total".localized view.title = "reader_weekly_total".localized
view.coins = 0 view.coins = 0
return view return view
}() }()
private lazy var coinsView2: CoinsView = { private lazy var coinsView2: CoinsView = {
let view = CoinsView() let view = CoinsView()
view.title = "Claimable Coins".localized view.title = "reader_claimable_coins".localized
view.coins = 0 view.coins = 0
return view return view
}() }()
@ -56,7 +56,7 @@ class NRCoinsPackHeaderView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 12, weight: .regular) label.font = .font(ofSize: 12, weight: .regular)
label.textColor = .black.withAlphaComponent(0.5) label.textColor = .black.withAlphaComponent(0.5)
label.text = "Active Refills".localized + ": " label.text = "reader_active_refills".localized + ": "
return label return label
}() }()
@ -86,7 +86,7 @@ class NRCoinsPackHeaderView: UIView {
coinText.bounds = .init(x: 0, y: -3, width: coinImage.size.width, height: coinImage.size.height) coinText.bounds = .init(x: 0, y: -3, width: coinImage.size.width, height: coinImage.size.height)
let coinAtt = AttributedString(NSAttributedString(attachment: coinText)) let coinAtt = AttributedString(NSAttributedString(attachment: coinText))
let textAtt = AttributedString("Claim All".localized + " ", attributes: AttributeContainer([ let textAtt = AttributedString("reader_claim_all".localized + " ", attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .semibold), .font : UIFont.font(ofSize: 14, weight: .semibold),
.foregroundColor : UIColor.white .foregroundColor : UIColor.white
])) ]))
@ -102,7 +102,7 @@ class NRCoinsPackHeaderView: UIView {
} else { } else {
button.configuration?.background.image = UIImage(color: .E_0_E_0_E_0) button.configuration?.background.image = UIImage(color: .E_0_E_0_E_0)
button.configuration?.attributedTitle = AttributedString("Claimed".localized, attributes: AttributeContainer([ button.configuration?.attributedTitle = AttributedString("reader_claimed".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 14, weight: .semibold), .font : UIFont.font(ofSize: 14, weight: .semibold),
.foregroundColor : UIColor.black.withAlphaComponent(0.25) .foregroundColor : UIColor.black.withAlphaComponent(0.25)
])) ]))

View File

@ -12,10 +12,10 @@ class NRConsumptionRecordsCell: NRTableViewCell {
var model: NRBuyRecordsModel? { var model: NRBuyRecordsModel? {
didSet { didSet {
titleLabel.text = "Purchase Single Episode".localized titleLabel.text = "reader_single_episode".localized
subtitleLabel.text = "Ch.##".localizedReplace(text: "\(model?.episode ?? "")") + " " + "\(model?.name ?? "")" subtitleLabel.text = "Ch.##".localizedReplace(text: "\(model?.episode ?? "")") + " " + "\(model?.name ?? "")"
timeLabel.text = model?.created_at timeLabel.text = model?.created_at
coinsLabel.text = "-\(model?.coins ?? 0)" + "Coins".localized coinsLabel.text = "-\(model?.coins ?? 0)" + "reader_coins".localized
} }
} }

View File

@ -19,7 +19,8 @@ class NRRewardCoinsCell: NRTableViewCell {
remainingLabel.text = model?.left_coins remainingLabel.text = model?.left_coins
if model?.is_effective == 1 { if model?.is_effective == 1 {
expiresLabel.text = "Expires in ## days".localizedReplace(text: model?.diff_datetime ?? "") // expiresLabel.text = "Expires in ## days".localizedReplace(text: model?.diff_datetime ?? "")
expiresLabel.text = "reader_expires_in".localized + (model?.diff_datetime ?? "")
} else { } else {
expiresLabel.text = "Expired".localized expiresLabel.text = "Expired".localized
} }

View File

@ -22,7 +22,7 @@ class NRStoreCoinsBigCell: NRStoreCoinsCell {
if sendCoins > 0 { if sendCoins > 0 {
sendCountLabel.isHidden = false sendCountLabel.isHidden = false
ratioBgView.isHidden = false ratioBgView.isHidden = false
sendCountLabel.text = "+ \(sendCoins) " + "Bonus".localized sendCountLabel.text = "+ \(sendCoins) " + "reader_my_bonus".localized
let ratio = String(format: "%.0f", CGFloat(sendCoins) / CGFloat(coins) * 100) let ratio = String(format: "%.0f", CGFloat(sendCoins) / CGFloat(coins) * 100)
ratioLabel.text = "+\(ratio)%" ratioLabel.text = "+\(ratio)%"

View File

@ -47,7 +47,7 @@ class NRStoreCoinsPackCell: NRStoreCoinsCell {
label.textColors = [UIColor.BA_8_A_2_A.cgColor, UIColor._8_B_5801.cgColor] label.textColors = [UIColor.BA_8_A_2_A.cgColor, UIColor._8_B_5801.cgColor]
label.textStartPoint = .init(x: 0, y: 0.5) label.textStartPoint = .init(x: 0, y: 0.5)
label.textEndPoint = .init(x: 1, y: 0.5) label.textEndPoint = .init(x: 1, y: 0.5)
label.text = "Weekly Refill".localized label.text = "weekly_refill".localized
return label return label
}() }()

View File

@ -21,7 +21,7 @@ class NRStoreCoinsSmallCell: NRStoreCoinsCell {
if sendCoins > 0 { if sendCoins > 0 {
sendCountLabel.isHidden = false sendCountLabel.isHidden = false
ratioBgView.isHidden = false ratioBgView.isHidden = false
sendCountLabel.text = "+ \(sendCoins) " + "Bonus".localized sendCountLabel.text = "+ \(sendCoins) " + "reader_my_bonus".localized
let ratio = String(format: "%.0f", CGFloat(sendCoins) / CGFloat(coins) * 100) let ratio = String(format: "%.0f", CGFloat(sendCoins) / CGFloat(coins) * 100)
ratioLabel.text = "+\(ratio)%" ratioLabel.text = "+\(ratio)%"

View File

@ -64,7 +64,7 @@ class NRStoreCoinsView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "Coins Purchase".localized label.text = "purchase_coins".localized
return label return label
}() }()

View File

@ -18,7 +18,7 @@ class NRStoreVipCell: UICollectionViewCell {
desLabel.text = model?.nr_description desLabel.text = model?.nr_description
if let coins = model?.send_coins, coins > 0 { if let coins = model?.send_coins, coins > 0 {
extraLabel.text = "+\(coins) \("Extra".localized)" extraLabel.text = "+\(coins) \("reader_extra".localized)"
extraBgView.isHidden = false extraBgView.isHidden = false
} else { } else {
extraBgView.isHidden = true extraBgView.isHidden = true

View File

@ -60,7 +60,7 @@ class NRStoreVipView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "VIP Membership".localized label.text = "reader_vip_Membership".localized
return label return label
}() }()
@ -68,7 +68,7 @@ class NRStoreVipView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 12, weight: .regular) label.font = .font(ofSize: 12, weight: .regular)
label.textColor = .black.withAlphaComponent(0.25) label.textColor = .black.withAlphaComponent(0.25)
label.text = "Auto renew,cancel anytime".localized label.text = "reade_store_vip_title".localized
return label return label
}() }()

View File

@ -37,7 +37,7 @@ class NRWalletHeaderView: UITableViewHeaderFooterView {
button.endPoint = .init(x: 1, y: 0.5) button.endPoint = .init(x: 1, y: 0.5)
button.layer.cornerRadius = 24 button.layer.cornerRadius = 24
button.layer.masksToBounds = true button.layer.masksToBounds = true
button.setTitle("Store".localized, for: .normal) button.setTitle("reader_store".localized, for: .normal)
button.setTitleColor(.white, for: .normal) button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = .font(ofSize: 14, weight: .medium) button.titleLabel?.font = .font(ofSize: 14, weight: .medium)
return button return button
@ -45,13 +45,13 @@ class NRWalletHeaderView: UITableViewHeaderFooterView {
private lazy var coinsView: CoinsView = { private lazy var coinsView: CoinsView = {
let view = CoinsView() let view = CoinsView()
view.title = "Coins".localized view.title = "reader_coins".localized
return view return view
}() }()
private lazy var bonusCoinsView: CoinsView = { private lazy var bonusCoinsView: CoinsView = {
let view = CoinsView() let view = CoinsView()
view.title = "Bonus".localized view.title = "reader_my_bonus".localized
return view return view
}() }()

View File

@ -99,7 +99,7 @@ class NRCoinsPackViewController: NRViewController {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 12, weight: .medium) label.font = .font(ofSize: 12, weight: .medium)
label.textColor = .black.withAlphaComponent(0.25) label.textColor = .black.withAlphaComponent(0.25)
label.text = "coins_pack_tips_title".localized label.text = "reader_subscription_rules".localized
return label return label
}() }()
@ -117,7 +117,7 @@ class NRCoinsPackViewController: NRViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.title = "My Refills".localized self.title = "reader_my_refills".localized
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")
payDataModel = NRIapManager.manager.payDateModel payDataModel = NRIapManager.manager.payDateModel

View File

@ -35,7 +35,7 @@ class NRConsumptionRecordsViewController: NRViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.title = "Consumption Records".localized self.title = "reader_wallet_tab1".localized
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")

View File

@ -11,7 +11,7 @@ import SnapKit
class NROrderRecordsPageViewController: NRViewController { class NROrderRecordsPageViewController: NRViewController {
private lazy var titles = ["Coin Record".localized, "VIP Record".localized] private lazy var titles = ["reader_coin_record".localized, "reader_vip_record".localized]
private lazy var viewControllers: [NROrderRecordsViewController] = { private lazy var viewControllers: [NROrderRecordsViewController] = {
let vc1 = NROrderRecordsViewController() let vc1 = NROrderRecordsViewController()
vc1.type = .coins vc1.type = .coins
@ -60,7 +60,7 @@ class NROrderRecordsPageViewController: NRViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.title = "Order Records".localized self.title = "reader_order_record".localized
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")

View File

@ -35,7 +35,7 @@ class NRRewardCoinsViewController: NRViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.title = "Reward Coins".localized self.title = "reader_wallet_tab4".localized
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")

View File

@ -64,17 +64,17 @@ class NRStoreViewController: NRViewController {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 10, weight: .regular) label.font = .font(ofSize: 10, weight: .regular)
label.textColor = .black.withAlphaComponent(0.5) label.textColor = .black.withAlphaComponent(0.5)
label.text = "store_tips".localized label.text = "store_tips_ios".localized
label.numberOfLines = 0 label.numberOfLines = 0
return label return label
}() }()
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.title = "Store".localized self.title = "reader_store".localized
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")
let barButtonItem = UIBarButtonItem(title: "Restore".localized, style: .plain, target: self, action: #selector(handleRestore)) let barButtonItem = UIBarButtonItem(title: "reader_restore".localized, style: .plain, target: self, action: #selector(handleRestore))
barButtonItem.tintColor = .black.withAlphaComponent(0.5) barButtonItem.tintColor = .black.withAlphaComponent(0.5)
self.navigationItem.rightBarButtonItem = barButtonItem self.navigationItem.rightBarButtonItem = barButtonItem

View File

@ -12,9 +12,9 @@ class NRWalletViewController: NRViewController {
private lazy var dataArr: [NRMeItem] = { private lazy var dataArr: [NRMeItem] = {
let arr = [ let arr = [
NRMeItem(type: .consumptionRecords, title: "Consumption Records".localized), NRMeItem(type: .consumptionRecords, title: "reader_wallet_tab1".localized),
NRMeItem(type: .purchaseRecords, title: "Purchase Records".localized), NRMeItem(type: .purchaseRecords, title: "reader_purchase_list".localized),
NRMeItem(type: .rewardCoins, title: "Reward Coins".localized), NRMeItem(type: .rewardCoins, title: "reader_wallet_tab4".localized),
] ]
return arr return arr
}() }()
@ -38,7 +38,7 @@ class NRWalletViewController: NRViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.title = "My Wallet".localized self.title = "reader_wallet".localized
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
configNavigationBack("arrow_left_icon_05") configNavigationBack("arrow_left_icon_05")

View File

@ -49,7 +49,7 @@ extension AppDelegate {
#endif #endif
let alert = NRAlert(title: "apns_alert_title".localized, detail: "apns_alert_text".localized, topIconImage: UIImage(named: "alert_top_icon_06"), highlightButtonText: "Open".localized, normalButtonText: "Later".localized) let alert = NRAlert(title: "reader_open_notification".localized, detail: "reader_open_notification_info".localized, topIconImage: UIImage(named: "alert_top_icon_06"), highlightButtonText: "reader_open_notification_open".localized, normalButtonText: "reader_open_notification_later".localized)
alert.highlightHandle = { alert.highlightHandle = {
NRTool.openApnsSetting() NRTool.openApnsSetting()
NROpenAppManager.manager.apnsAuthorizationFinish() NROpenAppManager.manager.apnsAuthorizationFinish()

View File

@ -7,6 +7,7 @@
import UIKit import UIKit
import YYText import YYText
import MJRefresh
class SceneDelegate: UIResponder, UIWindowSceneDelegate { class SceneDelegate: UIResponder, UIWindowSceneDelegate {
@ -18,6 +19,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return } guard let windowScene = (scene as? UIWindowScene) else { return }
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(localizedDidChangeNotification), name: NRLocalizedManager.localizedDidChangeNotification, object: nil)
NRTool.sceneDelegate = self NRTool.sceneDelegate = self
NRTool.windowScene = windowScene NRTool.windowScene = windowScene
@ -25,7 +27,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
window = UIWindow(windowScene: windowScene) window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible() window?.makeKeyAndVisible()
self.setRootVC() self.startApp()
onLineTimer = Timer.scheduledTimer(timeInterval: 60 * 10, target: YYTextWeakProxy(target: self), selector: #selector(handleOnLine), userInfo: nil, repeats: true) onLineTimer = Timer.scheduledTimer(timeInterval: 60 * 10, target: YYTextWeakProxy(target: self), selector: #selector(handleOnLine), userInfo: nil, repeats: true)
@ -69,6 +71,26 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
extension SceneDelegate { extension SceneDelegate {
private func startApp() {
let localizedManager = NRLocalizedManager.shared
if localizedManager.localizedDataLocalizedKey != localizedManager.currentLocalizedKey {
let vc = NRTool.lanuchViewController
window?.rootViewController = vc
Task {
let _ = await localizedManager.updateLocalizedData()
self.setRootVC()
}
} else {
Task {
let _ = await localizedManager.updateLocalizedData()
}
setRootVC()
}
}
private func setRootVC() { private func setRootVC() {
/// ///
let hasOpenApp = UserDefaults.standard.object(forKey: kNRHasFirstOpenedAPPDefaultsKey) as? Bool let hasOpenApp = UserDefaults.standard.object(forKey: kNRHasFirstOpenedAPPDefaultsKey) as? Bool
@ -81,7 +103,6 @@ extension SceneDelegate {
self.setTabBarController() self.setTabBarController()
} }
window?.rootViewController = vc window?.rootViewController = vc
window?.makeKeyAndVisible()
} else { } else {
self.setTabBarController() self.setTabBarController()
} }
@ -90,7 +111,6 @@ extension SceneDelegate {
private func setTabBarController() { private func setTabBarController() {
window?.rootViewController = NRTabBarController() window?.rootViewController = NRTabBarController()
window?.makeKeyAndVisible()
NROpenAppManager.manager.openAppFinish() NROpenAppManager.manager.openAppFinish()
} }
@ -105,8 +125,17 @@ extension SceneDelegate {
@objc private func networkStatusDidChangeNotification() { @objc private func networkStatusDidChangeNotification() {
guard NRNetworkReachableManager.manager.isReachable == true else { return } guard NRNetworkReachableManager.manager.isReachable == true else { return }
handleOnLine() self.handleOnLine()
self.retryHandleOpenAppMessage() self.retryHandleOpenAppMessage()
if NRLocalizedManager.shared.localizedData == nil, !NROpenAppManager.manager.isOpenApp {
self.startApp()
}
}
@objc private func localizedDidChangeNotification() {
MJRefreshConfig.default.languageCode = NRLocalizedManager.shared.mjLocalizedKey
self.setTabBarController()
} }
} }

View File

@ -32,9 +32,9 @@ class NRCoinsPackAlert: NRAlert {
coinsLabel.textColor = .F_9710_D coinsLabel.textColor = .F_9710_D
coinsLabel.text = "+\(model.coins ?? 0)" coinsLabel.text = "+\(model.coins ?? 0)"
highlightButton.setTitle("Claim Now".localized, for: .normal) highlightButton.setTitle("receive_now".localized, for: .normal)
normalButton.setTitle("Later".localized, for: .normal) normalButton.setTitle("reader_open_notification_later".localized, for: .normal)
bgView.addSubview(titleLabel) bgView.addSubview(titleLabel)

View File

@ -31,7 +31,7 @@ class NRUpdatesAlert: NRAlert {
titleLabel.numberOfLines = 0 titleLabel.numberOfLines = 0
titleLabel.font = .font(ofSize: 20, weight: .medium) titleLabel.font = .font(ofSize: 20, weight: .medium)
titleLabel.textColor = .F_9710_D titleLabel.textColor = .F_9710_D
titleLabel.text = "New Version".localized titleLabel.text = "reader_update_now".localized
let versionView = UIView() let versionView = UIView()
versionView.backgroundColor = .F_9710_D versionView.backgroundColor = .F_9710_D
@ -83,7 +83,7 @@ class NRUpdatesAlert: NRAlert {
highlightButton.setTitle("Update Now".localized, for: .normal) highlightButton.setTitle("reader_update_now_ok".localized, for: .normal)
buttonStackView.addArrangedSubview(highlightButton) buttonStackView.addArrangedSubview(highlightButton)
bgView.addSubview(stackView) bgView.addSubview(stackView)

View File

@ -11,7 +11,7 @@ import LYEmptyView
struct NREmpty { struct NREmpty {
static func nr_emptyView(image: UIImage? = UIImage(named: "empty_image_01"), static func nr_emptyView(image: UIImage? = UIImage(named: "empty_image_01"),
title: String? = "No data".localized, title: String? = "reader_no_data".localized,
btnTitleStr: String? = nil, btnTitleStr: String? = nil,
contentViewOffset: CGFloat = -100, contentViewOffset: CGFloat = -100,
btnClickBlock: (() -> Void)? = nil) -> LYEmptyView { btnClickBlock: (() -> Void)? = nil) -> LYEmptyView {

View File

@ -153,7 +153,7 @@ class NRIapManager {
} }
if isLoding { if isLoding {
NRToast.show(text: "Success".localized) NRToast.show(text: "reader_success".localized)
} }
completer?(true, buyType) completer?(true, buyType)
if buyType == .subVip { if buyType == .subVip {
@ -224,7 +224,7 @@ extension NRIapManager: JXIAPManagerDelegate {
NRLoginManager.manager.userInfo?.is_vip = true NRLoginManager.manager.userInfo?.is_vip = true
} }
NRToast.show(text: "Success".localized) NRToast.show(text: "reader_success".localized)
self.completionHandler?(true) self.completionHandler?(true)
if buyType == .subVip { if buyType == .subVip {
NotificationCenter.default.post(name: NRIapManager.buyVipFinishNotification, object: nil) NotificationCenter.default.post(name: NRIapManager.buyVipFinishNotification, object: nil)

View File

@ -8,11 +8,14 @@
import UIKit import UIKit
class NRLocalizedManager: NSObject { class NRLocalizedManager: NSObject {
static let shared = NRLocalizedManager() static let localizedDidChangeNotification = Notification.Name(rawValue: "NRLocalizedManager.localizedDidChangeNotification")
private let LocalizedUserDefaultsKey = "NRLocalizedManager.LocalizedUserDefaultsKey" private let LocalizedUserDefaultsKey = "NRLocalizedManager.LocalizedUserDefaultsKey"
private let LocalizedDataUserDefaultsKey = "NRLocalizedManager.LocalizedDataUserDefaultsKey" private let LocalizedDataUserDefaultsKey = "NRLocalizedManager.LocalizedDataUserDefaultsKey"
private let LocalizedDataLocalizedKeyUserDefaultsKey = "NRLocalizedManager.LocalizedDataLocalizedKeyUserDefaultsKey" private let LocalizedDataLocalizedKeyUserDefaultsKey = "NRLocalizedManager.LocalizedDataLocalizedKeyUserDefaultsKey"
static let shared = NRLocalizedManager()
/// ///
private(set) lazy var localizedData: [String : String]? = UserDefaults.standard.object(forKey: LocalizedDataUserDefaultsKey) as? [String : String] private(set) lazy var localizedData: [String : String]? = UserDefaults.standard.object(forKey: LocalizedDataUserDefaultsKey) as? [String : String]
@ -34,18 +37,16 @@ class NRLocalizedManager: NSObject {
// //
var currentLocalizedKey: String { var currentLocalizedKey: String {
get { get {
// var key = (UserDefaults.standard.string(forKey: LocalizedUserDefaultsKey) ?? Locale.preferredLanguages.first) ?? "en" var key = (UserDefaults.standard.string(forKey: LocalizedUserDefaultsKey) ?? Locale.preferredLanguages.first) ?? "en"
// if key.contains("zh-Hans") { if key.contains("zh-Hans") {
// key = "zh" key = "zh"
// } else if key.contains("zh-Hant") { } else if key.contains("zh-Hant") {
// key = "zh_hk" key = "zh_hk"
// } else { } else {
// let arr = key.components(separatedBy: "-") let arr = key.components(separatedBy: "-")
// key = arr.first ?? "en" key = arr.first ?? "en"
// } }
// return key return key
return "en"
// return "zh"
} }
set { set {
UserDefaults.standard.set(newValue, forKey: LocalizedUserDefaultsKey) UserDefaults.standard.set(newValue, forKey: LocalizedUserDefaultsKey)
@ -74,6 +75,10 @@ class NRLocalizedManager: NSObject {
UserDefaults.standard.synchronize() UserDefaults.standard.synchronize()
} }
// //
func localizedString(forKey key: String, tableName: String? = nil) -> String { func localizedString(forKey key: String, tableName: String? = nil) -> String {
if let localizedData = localizedData, if let localizedData = localizedData,
@ -92,8 +97,31 @@ class NRLocalizedManager: NSObject {
} }
extension NRLocalizedManager { extension NRLocalizedManager {
//
func switchLocalized(_ key: String) async -> Bool {
await MainActor.run {
NRHud.show()
}
guard let model = await NRSettingAPI.requestLocalizedData(key: key) else { return false }
guard let localizedData = model.translates else { return false }
self.currentLocalizedKey = key
self.localizedDataLocalizedKey = key
self.localizedData = localizedData
await MainActor.run {
NRHud.dismiss()
NotificationCenter.default.post(name: NRLocalizedManager.localizedDidChangeNotification, object: nil)
}
return true
}
/// ///
func updateLocalizedData(key: String = NRLocalizedManager.shared.currentLocalizedKey) async -> Bool { func updateLocalizedData() async -> Bool {
let key = self.currentLocalizedKey
guard let model = await NRSettingAPI.requestLocalizedData(key: key) else { return false } guard let model = await NRSettingAPI.requestLocalizedData(key: key) else { return false }
@ -107,14 +135,6 @@ extension NRLocalizedManager {
} }
} }
extension NRLocalizedManager {
static let localizedDidChange = Notification.Name(rawValue: "SPLocalizedManager.localizedDidChange")
}
extension String { extension String {
var localized: String { var localized: String {

View File

@ -16,11 +16,11 @@ class NRNovelReadSet: NSObject, NSSecureCoding {
var title: String { var title: String {
switch self { switch self {
case .small: case .small:
return "Small".localized return "reader_small".localized
case .standard: case .standard:
return "Standard".localized return "reader_standard".localized
case .large: case .large:
return "Large".localized return "reader_large".localized
} }
} }
} }

View File

@ -172,7 +172,7 @@ private var layoutGrid_str: String!
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 16, weight: .semibold) label.font = .font(ofSize: 16, weight: .semibold)
label.textColor = .black label.textColor = .black
label.text = "Contents" label.text = "reader_book_contents"
return label return label
}() }()

View File

@ -23,7 +23,7 @@ var chaptersIdx: Int? = 0
didSet { didSet {
let self_rate = model?.self_rate ?? 0 let self_rate = model?.self_rate ?? 0
if self_rate < 0 { if self_rate < 0 {
label.text = "Enjoying this book?".localized label.text = "reader_enjoying_tip".localized
gradeView.grade = 0 gradeView.grade = 0
gradeView.updateOnTouch = true gradeView.updateOnTouch = true
gradeView.fillMode = .full gradeView.fillMode = .full
@ -57,7 +57,7 @@ var chaptersIdx: Int? = 0
var configuration = UIButton.Configuration.plain() var configuration = UIButton.Configuration.plain()
configuration.imagePadding = 8 configuration.imagePadding = 8
configuration.image = UIImage(named: "ategoryCryptorOgin") configuration.image = UIImage(named: "ategoryCryptorOgin")
configuration.attributedTitle = AttributedString("Rating Submitted!".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_rating_submitted".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 12, weight: .medium), .font : UIFont.font(ofSize: 12, weight: .medium),
.foregroundColor : UIColor.black .foregroundColor : UIColor.black
])) ]))

View File

@ -81,7 +81,7 @@ private var ranges_mark: Int? = 0
var configuration = UIButton.Configuration.plain() var configuration = UIButton.Configuration.plain()
configuration.imagePadding = 8 configuration.imagePadding = 8
configuration.image = UIImage(named: "ategoryCryptorOgin") configuration.image = UIImage(named: "ategoryCryptorOgin")
configuration.attributedTitle = AttributedString("Rating Submitted!".localized, attributes: AttributeContainer([ configuration.attributedTitle = AttributedString("reader_rating_submitted".localized, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 12, weight: .medium), .font : UIFont.font(ofSize: 12, weight: .medium),
.foregroundColor : UIColor.black .foregroundColor : UIColor.black
])) ]))

View File

@ -512,7 +512,7 @@ _ = nationalityTelegraph
} }
await MainActor.run { await MainActor.run {
let alert = IJRecordsWindow(title: "alert_title_01".localized, detail: "alert_detail_01".localized, topIconImage: UIImage(named: "vibeoEtting"), highlightButtonText: "Yes, Recommend".localized) let alert = IJRecordsWindow(title: "reader_recommend_book".localized, detail: "reader_recommend_book_tip".localized, topIconImage: UIImage(named: "vibeoEtting"), highlightButtonText: "reader_recommend_book_ok".localized)
alert.closeHandle = { [weak self] in alert.closeHandle = { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self._absoluteMagnitudeBatteryKeyboardNickFormat() self._absoluteMagnitudeBatteryKeyboardNickFormat()

View File

@ -69,7 +69,7 @@ var minish_margin: Double? = 0.0
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 12, weight: .regular) label.font = .font(ofSize: 12, weight: .regular)
label.textColor = .black.withAlphaComponent(0.25) label.textColor = .black.withAlphaComponent(0.25)
label.text = "Auto renew,cancel anytime".localized label.text = "reade_store_vip_title".localized
return label return label
}() }()

View File

@ -70,7 +70,7 @@ withUnsafeMutablePointer(to: &ameraPaths) { pointer in
} else { } else {
if code == 402, parameters.isToast { if code == 402, parameters.isToast {
DispatchQueue.main.async { DispatchQueue.main.async {
RKDrama.show(text: "network_error_1".localized) RKDrama.show(text: "reader_kick_out_login".localized)
} }
} }
@ -135,7 +135,7 @@ withUnsafeMutablePointer(to: &ameraPaths) { pointer in
res.code = -1 res.code = -1
if parameters.isToast { if parameters.isToast {
DispatchQueue.main.async { DispatchQueue.main.async {
RKDrama.show(text: "network_error_2".localized) RKDrama.show(text: "reader_network_error".localized)
} }
} }
completion?(res) completion?(res)

View File

@ -57,7 +57,7 @@ var nickLocalizableFillStr: String?
JPScreen.request(parameters: param) { (response: JPScreen.Response<JAAbel>) in JPScreen.request(parameters: param) { (response: JPScreen.Response<JAAbel>) in
guard let data = response.data else { guard let data = response.data else {
RKDrama.show(text: "network_error_2".localized) RKDrama.show(text: "reader_network_error".localized)
completer?(nil) completer?(nil)
return return
} }

View File

@ -8,169 +8,165 @@
"Error" = "Error"; "Error" = "Error";
"My List" = "My List"; "reader_my_list" = "My List";
"Home" = "Home"; "reader_home" = "Home";
"Explore" = "Explore"; "home_explore" = "Explore";
"Me" = "Me"; "reader_me" = "Me";
"Must-Read Today" = "Must-Read Today"; "reader_banner_title" = "Must-Read Today";
"New Arrivals" = "New Arrivals"; "reader_new_arrivals" = "New Arrivals";
"read_what_title" = "Not Sure what to read?"; "reader_home_title" = "Not Sure what to read?";
"read_what_subtitle" = "Our Editors have some suggests."; "reader_home_title1" = "Our Editors have some suggests.";
"Read Now" = "Read Now"; "reader_read_now" = "Read Now";
"Hot On The Grid" = "Hot On The Grid"; "reader_home_title2" = "Hot On The Grid";
"Next In View" = "Next In View"; "reader_home_title3" = "Next In View";
"Hot Tags" = "Hot Tags"; "reader_home_title4" = "Hot Tags";
"Featured" = "Featured"; "reader_home_title5" = "Featured";
"More Stories" = "More Stories"; "reader_home_title6" = "More Stories";
"search_placeholder" = "What are you looking for?"; "reader_enter_keywords_search" = "What are you looking for?";
"Recent Searches" = "Recent Searches"; "reader_searches" = "Recent Searches";
"Genres" = "Genres"; "reader_home_genres" = "Genres";
"Trending" = "Trending"; "home_trending" = "Trending";
"Top Rated" = "Top Rated"; "home_topRated" = "Top Rated";
"Most Collected" = "Most Collected"; "home_mostCollected" = "Most Collected";
"Best Sellers" = "Best Sellers"; "home_bestSellers" = "Best Sellers";
"Today" = "Today"; "home_today" = "Today";
"This Week" = "This Week"; "home_week" = "This Week";
"This Month" = "This Month"; "home_month" = "This Month";
"Start Reading" = "Start Reading"; "reader_book_startReading" = "Start Reading";
"Collect" = "Collect"; "reader_book_collects" = "Collect";
"Collects" = "Collects"; "reader_book_heats" = "Heats";
"Heats" = "Heats"; "reader_book_words" = "Words";
"Words" = "Words"; "reader_book_rate" = "Rate";
"Rate" = "Rate"; "reader_book_synopsis" = "Synopsis";
"Synopsis" = "Synopsis"; "reader_book_completed" = "Completed";
"Completed" = "Completed"; "reader_book_more" = "More Like This";
"More Like This" = "More Like This"; "reader_book_chapters" = "Chapters";
"## Chapters" = "## Chapters"; "reader_book_catalog" = "Catalog";
"Catalog" = "Catalog"; "reader_book_contents" = "Contents";
"Night" = "Night"; "reader_night" = "Night";
"Settings" = "Settings"; "reader_settings" = "Settings";
"Prev" = "Prev"; "reader_prev" = "Prev";
"Next" = "Next"; "reader_next" = "Next";
"Brightness" = "Brightness"; "reader_brightness" = "Brightness";
"Theme" = "Theme"; "reader_theme" = "Theme";
"Line Spacing" = "Line Spacing"; "reader_line_spacing" = "Line Spacing";
"Paragraph Spacing" = "Paragraph Spacing"; "reader_paragrapg" = "Paragraph Spacing";
"Small" = "Small"; "reader_small" = "Small";
"Standard" = "Standard"; "reader_standard" = "Standard";
"Large" = "Large"; "reader_large" = "Large";
"Chapter.##" = "Chapter.##"; "reader_read" = "read";
"## read" = "## read"; "reader_font_size" = "Font Size";
"Font Size" = "Font Size"; "reader_add_bookshelf" = "Add to My List";
"Add to My List" = "Add to My List"; "reader_bookshelf_tip" = "In My List";
"In My List" = "In My List"; "reader_enjoying_tip" = "Enjoying this book?";
"Enjoying this book?" = "Enjoying this book?"; "reader_my_rate" = "My Rate";
"My Rate##" = "My Rate##"; "reader_rating_submitted" = "Rating Submitted!";
"Rating Submitted!" = "Rating Submitted!"; "reader_book_finished" = "You Finished!";
"read_finish_title" = "You Finished!"; "reader_book_finished_tips" = "Congratulations On Completing This Epic Story!";
"read_finish_text" = "Congratulations On Completing This Epic Story!"; "reader_book_finished_list_title" = "You May Also Like";
"read_finish_list_title" = "You May Also Like"; "reader_success" = "Success";
"Success" = "Success"; "reader_delete_title_3" = "History";
"History" = "History"; "reader_about_us" = "About";
"About" = "About"; "reader_privacy_policy" = "Privacy Policy";
"Privacy Policy" = "Privacy Policy"; "reader_user_agreement" = "User Agreement";
"User Agreement" = "User Agreement"; "reader_website" = "Visit Website";
"Visit Website" = "Visit Website";
"Ch.##" = "Ch.##"; "Ch.##" = "Ch.##";
"New" = "New"; "reader_new" = "New";
"alert_title_01" = "Recommend this book?"; "reader_recommend_book" = "Recommend this book?";
"alert_detail_01" = "Help us share this story with others."; "reader_recommend_book_tip" = "Help us share this story with others.";
"Yes, Recommend" = "Yes, Recommend"; "reader_recommend_book_ok" = "Yes, Recommend";
"Chapter Locked" = "Chapter Locked"; "reader_chapter_locked" = "Chapter Locked";
"No data" = "No data"; "reader_no_data" = "No data";
"Coins" = "Coins"; "reader_coins" = "Coins";
"Bonus" = "Bonus"; "reader_my_bonus" = "Bonus";
"Top Up" = "Top Up"; "reader_top_up" = "Top Up";
"Language" = "Language"; "reader_choose_language" = "Language";
"Loading" = "Loading"; "reader_status_load" = "Loading";
"Store" = "Store"; "reader_store" = "Store";
"Coins Purchase" = "Coins Purchase"; "purchase_coins" = "Coins Purchase";
"VIP Membership" = "VIP Membership"; "reader_vip_Membership" = "VIP Membership";
"Auto renew,cancel anytime" = "Auto renew,cancel anytime"; "reade_store_vip_title" = "Auto renew,cancel anytime";
"Feedback" = "Feedback"; "reader_feedback" = "Feedback";
"Feedback History" = "Feedback History"; "reader_feedback_history" = "Feedback History";
"Feedback Details" = "Feedback Details"; "reader_feedback_detail" = "Feedback Details";
"Account Deletion" = "Account Deletion"; "reader_account_deletion" = "Account Deletion";
"me_coins_pack_title" = "Daily reward ready!"; "reader_my_daily" = "Daily reward ready!";
"me_coins_pack_subtitle" = "Claim your rewards now."; "reader_my_daily_tips" = "Claim your rewards now.";
"Weekly VIP" = "Weekly VIP"; "pay_template_1018" = "Weekly VIP";
"Monthly VIP" = "Monthly VIP"; "month_vip" = "Monthly VIP";
"Quarterly VIP" = "Quarterly VIP"; "three_months_vip" = "Quarterly VIP";
"Yearly VIP" = "Yearly VIP"; "yearly_vip" = "Yearly VIP";
"week" = "week"; "week" = "week";
"month" = "month"; "month" = "month";
"quarter" = "quarter"; "quarter" = "quarter";
"year" = "year"; "year" = "year";
"My Wallet" = "My Wallet"; "reader_wallet" = "My Wallet";
"Consumption Records" = "Consumption Records"; "reader_wallet_tab1" = "Consumption Records";
"Purchase Records" = "Purchase Records"; "reader_purchase_list" = "Purchase Records";
"Reward Coins" = "Reward Coins"; "reader_wallet_tab4" = "Reward Coins";
"Purchase Single Episode" = "Purchase Single Episode"; "reader_single_episode" = "Purchase Single Episode";
"Expired" = "Expired"; "Expired" = "Expired";
"Expires in ## days" = "Expires in ## days"; "reader_expires_in" = "Expires in:";
"Order Records" = "Order Records"; "reader_order_record" = "Order Records";
"Coin Record" = "Coin Record"; "reader_coin_record" = "Coin Record";
"VIP Record" = "VIP Record"; "reader_vip_record" = "VIP Record";
"Weekly Refill" = "Weekly Refill"; "weekly_refill" = "Weekly Refill";
"Extra" = "Extra"; "reader_extra" = "Extra";
"Bonus You Get" = "Bonus You Get"; "reader_bonus_you_get" = "Bonus You Get";
"Weekly Refill Package" = "Weekly Refill Package"; "reader_weekly_refill_package" = "Weekly Refill Package";
"Daily Bonuses" = "Daily Bonuses"; "reader_dailu_bonuses" = "Daily Bonuses";
"What You Get" = "What You Get"; "reader_what_you_get" = "What You Get";
"coins_pack_confirm_tip_title" = "How Do I Receive Coins"; "coins_pack_confirm_tip_title" = "How Do I Receive Coins";
"Continue" = "Continue"; "reader_continue" = "Continue";
"Expiration Time" = "Expiration Time"; "reader_expiration_Time" = "Expiration Time";
"My Refills" = "My Refills"; "reader_my_refills" = "My Refills";
"Rewards Overview" = "Rewards Overview"; "reader_rewards_overview" = "Rewards Overview";
"Weekly Total" = "Weekly Total"; "reader_weekly_total" = "Weekly Total";
"Claimable Coins" = "Claimable Coins"; "reader_claimable_coins" = "Claimable Coins";
"Active Refills" = "Active Refills"; "reader_active_refills" = "Active Refills";
"Claim All" = "Claim All"; "reader_claim_all" = "Claim All";
"Claimed" = "Claimed"; "reader_claimed" = "Claimed";
"Weekly Refills" = "Weekly Refills"; "reader_total_reward" = "Total Reward";
"Total Reward" = "Total Reward";
"Remaining" = "Remaining"; "Remaining" = "Remaining";
"Claim" = "Claim"; "reader_claim" = "Claim";
"Day" = "Day"; "d" = "Day";
"Restore" = "Restore"; "reader_restore" = "Restore";
"Balance" = "Balance"; "reader_balance" = "Balance";
"Daily Coins" = "Daily Coins"; "reader_daily_coins" = "Daily Coins";
"Buy Now" = "Buy Now"; "reader_buy_now" = "Buy Now";
"Login with Apple" = "Login with Apple"; "reader_login_title_apple" = "Login with Apple";
"Login with Facebook" = "Login with Facebook"; "reader_login_title_facebook" = "Login with Facebook";
"My Wallet" = "My Wallet";
"Account Deletion" = "Account Deletion";
"My Unlocks" = "My Unlocks"; "My Unlocks" = "My Unlocks";
"Login" = "Login"; "reader_log_out" = "Log Out";
"Log Out" = "Log Out"; "reader_confirm" = "Confirm";
"Confirm" = "Confirm";
"Unlocked Chapters" = "Unlocked Chapters"; "Unlocked Chapters" = "Unlocked Chapters";
"Update Now" = "Update Now"; "reader_update_now_ok" = "Update Now";
"New Version" = "New Version"; "reader_update_now" = "New Version";
"Try again" = "Try again"; "app_try_again" = "Try again";
"Open" = "Open"; "reader_open_app" = "Open";
"Claim Now" = "Claim Now"; "reader_open_notification_open" = "Open";
"Later" = "Later"; "receive_now" = "Claim Now";
"Default" = "Default"; "reader_open_notification_later" = "Later";
"Log in" = "Log in"; "reader_default" = "Default";
"reader_login" = "Log in";
"Chapter Price" = "Chapter Price"; "Chapter Price" = "Chapter Price";
"retain_alert_text" = "Unlock every show you love!"; "vip_retain_alert_text" = "Unlock every show you love!";
"logout_alert_text" = "Are you sure you want to log out?"; "reader_log_out_content" = "Are you sure you want to log out?";
"detail_collect_alert_title" = "Delete This Book?"; "detail_collect_alert_title" = "Delete This Book?";
"detail_collect_alert_text" = "Confirm to delete this book from the list"; "detail_collect_alert_text" = "Confirm to delete this book from the list";
"coins_pack_alert_title" = "Daily Reward is waiting!"; "coins_pack_alert_title" = "Daily Reward is waiting!";
"apns_alert_title" = "Enable Notifications"; "reader_open_notification" = "Enable Notifications";
"apns_alert_text" = "Stay informed with popular recommendations and latest updates!"; "reader_open_notification_info" = "Stay informed with popular recommendations and latest updates!";
"not_networking_empty_text" = "Check the network and try again~"; "not_networking_empty_text" = "Check the network and try again~";
"vip_tip_01" = "Unlimited access to all series"; "vip_tip_01" = "Unlimited access to all series";
"coins_pack_tips_title" = "Subscription Rules"; "reader_subscription_rules" = "Subscription Rules";
"coins_pack_tips" = "1.Coins are delivered instantly upon purchase.<br>2.Daily bonus coins available from the next day.<br>3.All coins will be revoked when the subscription expires, including both initial and daily coins."; "coins_pack_tips" = "1.Coins are delivered instantly upon purchase.<br>2.Daily bonus coins available from the next day.<br>3.All coins will be revoked when the subscription expires, including both initial and daily coins.";
"store_tips" = "1. Coins are virtual items and cannot be refunded. Use it for this product.<br>2. Both the coins and the reward coins will never expire.<br>3. Coins will be used first when unlocking episodes. If the amount is insufficient, reward coins will automatically be used.<br>4. The purchase has not been credited, click <Restore> torefresh.<br>5. For other questions, contact us via Profile > Feedback."; "store_tips_ios" = "1. Coins are virtual items and cannot be refunded. Use it for this product.<br>2. Both the coins and the reward coins will never expire.<br>3. Coins will be used first when unlocking episodes. If the amount is insufficient, reward coins will automatically be used.<br>4. The purchase has not been credited, click <Restore> torefresh.<br>5. For other questions, contact us via Profile > Feedback.";
"pay_error_1" = "You are already a member!"; "pay_error_1" = "You are already a member!";
"pay_error_2" = "You have unfinished in-app purchases, please restore them first."; "pay_error_2" = "You have unfinished in-app purchases, please restore them first.";
@ -179,6 +175,6 @@
"pay_error_5" = "Invalid in-app purchase"; "pay_error_5" = "Invalid in-app purchase";
"pay_error_6" = "Payment has been cancelled"; "pay_error_6" = "Payment has been cancelled";
"network_error_1" = "Your account is already logged in on another device~"; "reader_kick_out_login" = "Your account is already logged in on another device~";
"network_error_2" = "The service is abnormal. Check the network."; "reader_network_error" = "The service is abnormal. Check the network.";