Skip to content

Commit

Permalink
Merge pull request #67 from NatLibFi/ekirjasto-67-select-application-…
Browse files Browse the repository at this point in the history
…language

EKIRJASTO-67 Select application language
  • Loading branch information
natlibfi-ptalosel authored Nov 6, 2024
2 parents 697d548 + bb79e69 commit 5b94ac2
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 125 deletions.
6 changes: 3 additions & 3 deletions Palace/AppInfrastructure/TPPUserNotifications.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,16 @@ let DefaultActionIdentifier = "UNNotificationDefaultActionIdentifier"
return TPPBookRegistry.shared.heldBooks.count > 0
}

// Notification banner informing the user that a previously reserved book is now available for download
private class func createNotificationForReadyCheckout(book: TPPBook)
{
let unCenter = UNUserNotificationCenter.current()
unCenter.getNotificationSettings { (settings) in
guard settings.authorizationStatus == .authorized else { return }

let title = DisplayStrings.downloadReady
let content = UNMutableNotificationContent()
content.body = NSLocalizedString("The title you reserved, \(book.title), is available.", comment: "")
content.title = title
content.body = String.localizedStringWithFormat(DisplayStrings.readyForDownloadBody, book.title)
content.title = DisplayStrings.readyForDownloadTitle
content.sound = UNNotificationSound.default
content.categoryIdentifier = HoldNotificationCategoryIdentifier
content.userInfo = ["bookID" : book.identifier]
Expand Down
2 changes: 1 addition & 1 deletion Palace/Catalog/TPPCatalogSearchViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ - (void)viewDidLoad

self.searchBar = [[UISearchBar alloc] init];
self.searchBar.delegate = self;
self.searchBar.placeholder = self.searchDescription.humanReadableDescription;
self.searchBar.placeholder = NSLocalizedString(@"Search", nil);
self.searchBar.searchTextField.leftView.tintColor = [UIColor colorNamed:@"ColorEkirjastoSearchBarText"];
self.searchBar.searchTextField.textColor = [UIColor colorNamed:@"ColorEkirjastoAlwaysBlack"];
self.searchBar.searchTextField.tintColor = [UIColor colorNamed:@"ColorEkirjastoSearchBarText"];
Expand Down
250 changes: 138 additions & 112 deletions Palace/Settings/NewSettings/PreferencesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,141 +6,142 @@
// Copyright © 2024 The Palace Project. All rights reserved.
//

import SwiftUI
import Combine
import SwiftUI

// View for the user to set application prefences for the E-kirjasto app
struct PreferencesView: View {
typealias tsx = Strings.Preferences
var language = [tsx.en, tsx.fi, tsx.sv]
var fontSizeList = [tsx.hundred, tsx.oneTwentyFive, tsx.oneFifty, tsx.oneSeventyFive, tsx.twoHundred]
@State private var selectLang = "English"
@State private var langPreference = "fi"

@State private var toggleState = false
@State private var setFontSize: Double = 18.0
@State private var showAlert = false
@State private var setFontSize: Double = 16.0

// The values saved to userDefaults
@AppStorage("fontMultiplier") private var fontMultiplier: Double = 1.0
@AppStorage("fontPercent") private var selectPercent: String = "100%"
@AppStorage("enablePreferences") private var enablepreferences: Bool = false
@AppStorage("enablePreferences") private var enablePreferences: Bool = false

// View that lists all available application preferences for the user
// and the setting for the user to enable the use of these preferences in the application
var body: some View {
List {
Section {
Toggle(isOn: $toggleState) {
Text(tsx.togglePref)
.font(.system(size: CGFloat(setFontSize)))
// Store the new value of the toggle and save it to userDefaults
.onChange(of: toggleState) { newValue in
print("toggle state: \(toggleState) and newValue: \(newValue)")
enablepreferences = newValue
print(enablepreferences)
print(setFontSize)
print(fontMultiplier)
print(selectPercent)

// Set default values to userDefaults if disabled
if toggleState == false {
selectPercent = "100%"
fontMultiplier = 1.0
print("setting to defaults")
}
}
}
.padding(.vertical, 5)
// The toggle button to enable or disable app preferences
enablePreferencesSection

// If user has disabled the app preferences
// the language preferences cannot be accessed straight from app.
// However, the app specific language can be changed from device system settings
languagePreferencesSection
.disabled(toggleState == false)
}

// If user has disabled the app preferences
// the text size preferences cannot be accessed straight from app.
// However, the app specific text size can be changed from device control center
textSizePreferencesSection
.disabled(toggleState == false)
}

// User can enable the application prefences for the device.
// App prefences are disabled by default.
// The user's setting for using preferences (or not) is stored in the AppStorage (UserDefaults)
// and it will be remembered the next time the application is used.
@ViewBuilder private var enablePreferencesSection: some View {
Section {
Toggle(isOn: $toggleState) {
Text(tsx.togglePref)
.font(Font(uiFont: UIFont.palaceFont(ofSize: 16)))
}
.onChange(of: toggleState) { newValue in
// User has now toggled the "Enable prefences" button

//TODO: remove preferences if toggle is set to false
print("[PreferencesView] Current toggle state is \(toggleState) and the new value of toggle is \(newValue)")

.font(.system(size: CGFloat(setFontSize)))
.accessibilityLabel(tsx.selectEnable)
// Store the new value of the toggle
// and save it to AppStorage
enablePreferences = newValue

/*
//construct alert message
.alert(isPresented: $showAlert) {
Alert(title: Text(tsx.restartTitle), message: Text(tsx.restartText), dismissButton: .default(Text("OK")))
}
*/
print(
enablePreferences
? "[PreferencesView] App preferences enabled"
: "[PreferencesView] App prefences disabled"
)

//before view appears, get saved values
.onAppear {
toggleState = enablepreferences

if let savedLangPreference = UserDefaults.standard.string(forKey: "langPreference") {
selectLang = savedLangPreference
} else {
selectLang = "Finnish"
}

print("toggle state: \(toggleState)")
print("setFontSize: \(setFontSize)")
print("multiplier: \(fontMultiplier)")
print("percent: \(selectPercent)")
print(selectLang)

printCurrentTextSizePrefences()

// If user disables using app preferences
// reset userDefaults to app defaults
if toggleState == false {
resetAppPrefences()
}

// VStack{
// //Picker for language
// Picker(tsx.langButton, selection: $selectLang) {
// ForEach(language, id: \.self) {
// Text($0)
// .font(.system(size: setFontSize))
// }
// }
// .font(.system(size: CGFloat(setFontSize)))
// .pickerStyle(.inline)
// .onChange(of: selectLang) { newValue in
//
// UserDefaults.standard.set(selectLang, forKey: "langPreference")
//
// //save lang preference when value changes
// switch selectLang {
// case tsx.fi:
// UserDefaults.standard.set(["fi"], forKey: "AppleLanguages")
// print("selected: ", selectLang)
// //Bundle.main.load()
// case tsx.sv:
// UserDefaults.standard.set(["sv"], forKey: "AppleLanguages")
// print("selected: ", selectLang)
// case tsx.en:
// UserDefaults.standard.set(["en"], forKey: "AppleLanguages")
//
// print("selected: ", selectLang)
// default:
// print("Language set to default")
// print("selected: ", selectLang)
// UserDefaults.standard.set(["fi"], forKey: "AppleLanguages")
// }
// //just to make sure value is saved
// UserDefaults.standard.synchronize()
// print(newValue)
//
// }
// .font(.system(size: CGFloat(setFontSize)))
// .accessibilityLabel(tsx.selectL)
// }
// .disabled(toggleState == false)
}

.padding(.vertical, 5)
.font(Font(uiFont: UIFont.palaceFont(ofSize: 16)))
.accessibilityLabel(tsx.selectEnable)
.onAppear {
// The moment the toggle button and the rest of the preferencess view appears

// Get the stored value for using (or not using) app prefences from AppStorage
// and restore the toggle state
toggleState = enablePreferences

print("[PreferencesView] Restoring this toggle state for view: \(toggleState)")
}
}
Text(tsx.fontSizeButton)
.font(.system(size: CGFloat(setFontSize)))
.padding(.leading, 30)
.padding(.vertical, 20)
.frame(maxWidth: .infinity, alignment: .leading)
}

// Forcing the slider to the bottom of the screen so that when texts are bigger, it stays where it is
// Shortcut button for the user to navigate to device system settings
// User can select different language for the app than the device language
// Changing language starts the app from main screen
@ViewBuilder private var languagePreferencesSection: some View {
// This is the link to E-kirjasto settings in iOS system settings
// You can also navigate to Settings -> Apps -> E-kirjasto
let appSystemSettingsURL = URL(string: UIApplication.openSettingsURLString)!

Section {
Button {
UIApplication.shared.open(appSystemSettingsURL)
} label: {
HStack {
Text(tsx.langButton)
.font(Font(uiFont: UIFont.palaceFont(ofSize: 16)))
Spacer()
Image("ArrowRight")
.padding(.leading, 10)
.foregroundColor(Color(uiColor: .lightGray))
}
}
.accessibilityLabel(tsx.selectL)
}
}

// Slider for user to select the text size for the app
// User can only make text bigger than default, not smaller
@ViewBuilder private var textSizePreferencesSection: some View {
Text(tsx.fontSizeButton)
.font(Font(uiFont: UIFont.palaceFont(ofSize: 16)))
.padding(.leading, 30)
.padding(.vertical, 20)
.frame(maxWidth: .infinity, alignment: .leading)

// Forcing the slider to the bottom of the screen
// so that when texts are bigger, it stays where it is
ZStack(alignment: .bottom) {
VStack {
HStack {
Text("A")
.font(.system(size: CGFloat(20)))
Slider(value: $fontMultiplier, in: 1.0...2.0, step: 0.25) // The multiplier is saved directly to userDefaults when the value changes

// The multiplier is saved directly to userDefaults when the value changes
Slider(value: $fontMultiplier, in: 1.0 ... 2.0, step: 0.25)

Text("A")
.font(.system(size: CGFloat(40)))
}
.onChange(of: fontMultiplier) { newValue in
print("new value: \(newValue)")
// User has changed the position of the slider
print("[PreferencesView] New value of text size slider: \(newValue)")

if newValue == 1.25 {
selectPercent = tsx.oneTwentyFive
}
Expand All @@ -157,19 +158,44 @@ struct PreferencesView: View {
selectPercent = tsx.hundred
}
setFontSize = 16.0 * newValue
print(setFontSize)
print(selectPercent)
printCurrentTextSizePrefences()
}
Text(selectPercent)
.font(.system(size: CGFloat(16)))
.font(Font(uiFont: UIFont.palaceFont(ofSize: 16)))
}
.accessibilityLabel(tsx.selectS)
}
.disabled(toggleState == false)
.padding(.bottom, 50)
.padding(.horizontal, 40)
}

func resetAppPrefences() {
print("[PreferencesView] Resetting app preferences to defaults")
resetLanguageToDefault()
resetTextSizeToDefault()
}

func resetLanguageToDefault() {
// Currently we do not reset language
}

func resetTextSizeToDefault() {
print("[PreferencesView] Set text size to default")
selectPercent = "100%"
fontMultiplier = 1.0
}

func printCurrentTextSizePrefences() {
print(
"""
[PreferencesView] Current setFontSize: \(setFontSize)
[PreferencesView] Current fontMultiplier: \(fontMultiplier)
[PreferencesView] Current selectPercent: \(selectPercent)
"""
)
}
}
//#Preview {

// #Preview {
// PreferencesView()
//}
// }
26 changes: 18 additions & 8 deletions Palace/Settings/TPPSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,15 @@ func versionCode() -> String {
but no obvious method for doing so was found.
- Returns: feedback URL with parameters as a String
*/
func feedbackURL() -> String {
func feedbackURL(appLanguage: String!) -> String {
var components = URLComponents()
components.scheme = "https"
components.host = "lib.e-kirjasto.fi"
components.path = "/palaute"

// Set the query parameters here because we want them in the final URL
components.queryItems = [
URLQueryItem(name: "lang", value: "fi"),
URLQueryItem(name: "lang", value: appLanguage),
URLQueryItem(name: "version_name", value: versionName()),
URLQueryItem(name: "version_code", value: versionCode()),
URLQueryItem(name: "device_manufacturer", value: "Apple"),
Expand All @@ -171,14 +171,24 @@ func feedbackURL() -> String {
@objc class func sharedSettings() -> TPPSettings {
return TPPSettings.shared
}

// The language the user has chosen for the application (not device language)
// - returns the short alphabetical language code as a string
// - current possible E-kirjasto app language codes: fi, sv, en
static let appLanguage = Locale.current.languageCode

// The URL origin shared with remote NatLibFi HTML pages accessed through application
// - the application language code is part of the URL string ('fi' is set as default)
// - with the application language code the user is directed to the corresponding language version of the web page
// - example URL origin: 'https://www.kansalliskirjasto.fi/sv/e-kirjasto'
static let ekirjastoURLOrigin = "https://www.kansalliskirjasto.fi/\(appLanguage ?? "fi")/e-kirjasto"

static let TPPAboutPalaceURLString = "http://thepalaceproject.org/"
static let TPPUserAgreementURLString = "https://www.kansalliskirjasto.fi/fi/e-kirjasto/e-kirjaston-kayttoehdot"
static let TPPPrivacyPolicyURLString = "https://www.kansalliskirjasto.fi/fi/e-kirjasto/e-kirjaston-tietosuoja-ja-rekisteriseloste"
// TODO: set the feedback url language parameter
static let TPPFeedbackURLString = feedbackURL()
static let TPPAccessibilityURLString = "https://www.kansalliskirjasto.fi/fi/e-kirjasto/e-kirjaston-saavutettavuusseloste"
static let TPPFAQURLString = "https://www.kansalliskirjasto.fi/fi/e-kirjasto/e-kirjaston-usein-kysytyt-kysymykset"
static let TPPUserAgreementURLString = "\(ekirjastoURLOrigin)/e-kirjaston-kayttoehdot"
static let TPPPrivacyPolicyURLString = "\(ekirjastoURLOrigin)/e-kirjaston-tietosuoja-ja-rekisteriseloste"
static let TPPFeedbackURLString = feedbackURL(appLanguage: appLanguage)
static let TPPAccessibilityURLString = "\(ekirjastoURLOrigin)/e-kirjaston-saavutettavuusseloste"
static let TPPFAQURLString = "\(ekirjastoURLOrigin)/e-kirjaston-usein-kysytyt-kysymykset"

static private let customMainFeedURLKey = "NYPLSettingsCustomMainFeedURL"
static private let accountMainFeedURLKey = "NYPLSettingsAccountMainFeedURL"
Expand Down
3 changes: 2 additions & 1 deletion Palace/Utilities/Localization/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,9 @@ struct Strings {
}

struct UserNotifications {
static let downloadReady = NSLocalizedString("Ready for Download", comment: "")
static let checkoutTitle = NSLocalizedString("Check Out", comment: "")
static let readyForDownloadTitle = NSLocalizedString("Ready for Download", comment: "The title for a notification banner informing the user that a reserved book is now available for download")
static let readyForDownloadBody = NSLocalizedString("The title you reserved %@ is available.", comment: "The body text for a notification banner informing the user that a reserved book is now available for download")
}

struct MyBooksView {
Expand Down

0 comments on commit 5b94ac2

Please sign in to comment.