Skip to content

Commit 49bb974

Browse files
authored
Merge pull request #183 from HappyKoalaDev/main
feature/i18n
2 parents 56f7b4c + 2167cae commit 49bb974

22 files changed

+698
-215
lines changed

app/src/main/java/nl/giejay/android/tv/immich/auth/AuthByPhoneFragment.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class AuthByPhoneFragment : Fragment() {
7272
binding.qr.setImageDrawable(drawable)
7373
binding.qr.visibility = View.VISIBLE
7474
binding.qrProgressBar.visibility = View.GONE
75-
binding.qrText.text = "Or enter the code $code on $authUrl"
75+
binding.qrText.text = getString(R.string.or_enter_code_on_auth_url, code, authUrl)
7676
job = ioScope.launch {
7777
pollConfig(code)
7878
}
@@ -87,7 +87,7 @@ class AuthByPhoneFragment : Fragment() {
8787
.asFlow()
8888
.onEach { delay(3_000) } // specify delay
8989
.onCompletion {
90-
showErrorMessage("Did not authenticate within the timeout, recreating QR code.")
90+
showErrorMessage(getString(R.string.auth_timeout_recreating_qr))
9191
rebootQRFlow(findNavController())
9292
}
9393
timer.collect {
@@ -120,7 +120,7 @@ class AuthByPhoneFragment : Fragment() {
120120
.build()
121121
)
122122
} else {
123-
showErrorMessage("Invalid Server URL or API key, try scanning again!")
123+
showErrorMessage(getString(R.string.invalid_server_url_or_api_key))
124124
rebootQRFlow(findNavController)
125125
}
126126
}
@@ -143,7 +143,7 @@ class AuthByPhoneFragment : Fragment() {
143143
}
144144
} catch (e: Exception) {
145145
Timber.e("Could not fetch qr", e)
146-
showErrorMessage("Could not fetch QR code: ${e.message}")
146+
showErrorMessage(getString(R.string.could_not_fetch_qr, e.message))
147147
}
148148
}
149149

app/src/main/java/nl/giejay/android/tv/immich/auth/AuthFragmentStep1.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class AuthFragmentStep1 : GuidedStepSupportFragment() {
3030
val icon: Drawable =
3131
requireContext().getDrawable(R.drawable.icon)!!
3232
return GuidanceStylist.Guidance(
33-
"Immich TV (${BuildConfig.VERSION_NAME})",
34-
"Login to your Immich server or try a demo.",
33+
getString(R.string.app_name) + " (${BuildConfig.VERSION_NAME})",
34+
getString(R.string.login_immich_description),
3535
"",
3636
icon
3737
)
@@ -41,24 +41,24 @@ class AuthFragmentStep1 : GuidedStepSupportFragment() {
4141
addCheckedAction(
4242
actions,
4343
ACTION_SIGN_IN,
44-
"Sign in by API key",
45-
"Login to your Immich instance by entering your API key.",
44+
getString(R.string.auth_sign_in_by_api_key),
45+
getString(R.string.auth_sign_in_by_api_key_desc),
4646
true,
4747
1
4848
)
4949
addCheckedAction(
5050
actions,
5151
ACTION_PHONE_SIGN_IN,
52-
"Sign in by phone",
53-
"Login to your Immich instance by phone.",
52+
getString(R.string.auth_sign_in_by_phone),
53+
getString(R.string.auth_sign_in_by_phone_desc),
5454
false,
5555
1
5656
)
5757
addCheckedAction(
5858
actions,
5959
ACTION_DEMO,
60-
"Demo mode",
61-
"Login to a demo Immich instance.",
60+
getString(R.string.auth_demo_mode),
61+
getString(R.string.auth_demo_mode_desc),
6262
false,
6363
1
6464
)
@@ -69,7 +69,7 @@ class AuthFragmentStep1 : GuidedStepSupportFragment() {
6969
savedInstanceState: Bundle?
7070
) {
7171
super.onCreateButtonActions(actions, savedInstanceState)
72-
addAction(actions, ACTION_CONTINUE, "Continue", "")
72+
addAction(actions, ACTION_CONTINUE, getString(R.string.continue_text), "")
7373
}
7474

7575
override fun onGuidedActionClicked(action: GuidedAction) {
@@ -100,4 +100,4 @@ class AuthFragmentStep1 : GuidedStepSupportFragment() {
100100
SELECTED_OPTION = action.id
101101
}
102102
}
103-
}
103+
}

app/src/main/java/nl/giejay/android/tv/immich/auth/AuthFragmentStep2.kt

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class AuthFragmentStep2 : GuidedStepSupportFragment() {
3939
override fun onCreateGuidance(savedInstanceState: Bundle?): GuidanceStylist.Guidance {
4040
val icon: Drawable = requireContext().getDrawable(R.drawable.icon)!!
4141
return GuidanceStylist.Guidance(
42-
"Immich TV",
43-
"Login to your Immich server or try a demo.",
42+
getString(R.string.app_name),
43+
getString(R.string.login_immich_description),
4444
"",
4545
icon
4646
)
@@ -50,29 +50,29 @@ class AuthFragmentStep2 : GuidedStepSupportFragment() {
5050
addEditableAction(
5151
actions,
5252
ACTION_NAME,
53-
"Server URL (http[s]://...)",
53+
getString(R.string.server_url_hint),
5454
PreferenceManager.get(HOST_NAME),
5555
InputType.TYPE_CLASS_TEXT
5656
)
5757
addEditableAction(
5858
actions,
5959
ACTION_API_KEY,
60-
"API Key",
60+
getString(R.string.api_key_text),
6161
PreferenceManager.get(API_KEY),
6262
InputType.TYPE_CLASS_TEXT
6363
)
6464
addCheckedAction(
6565
actions,
6666
ACTION_CHECK_CERTS,
67-
"Disable SSL verification",
68-
"Only use this when you have issues with self signed certificates!",
67+
getString(R.string.disable_ssl_verification),
68+
getString(R.string.disable_ssl_verification_desc),
6969
PreferenceManager.get(DISABLE_SSL_VERIFICATION)
7070
)
7171
addCheckedAction(
7272
actions,
7373
ACTION_DEBUG_MODE,
74-
"Debug mode",
75-
"Enable this if you are experiencing issues with getting the Immich data.",
74+
getString(R.string.debug_mode),
75+
getString(R.string.debug_mode_desc),
7676
PreferenceManager.get(DEBUG_MODE)
7777
)
7878
}
@@ -82,7 +82,7 @@ class AuthFragmentStep2 : GuidedStepSupportFragment() {
8282
savedInstanceState: Bundle?
8383
) {
8484
super.onCreateButtonActions(actions, savedInstanceState)
85-
addAction(actions, ACTION_CONTINUE, "Submit", "")
85+
addAction(actions, ACTION_CONTINUE, getString(R.string.submit), "")
8686
}
8787

8888
override fun onGuidedActionClicked(action: GuidedAction) {
@@ -99,16 +99,16 @@ class AuthFragmentStep2 : GuidedStepSupportFragment() {
9999
val navControl = findNavController()
100100
navControl.navigate(AuthFragmentStep2Directions.actionGlobalHomeFragment(), NavOptions.Builder().setPopUpTo(R.id.authFragment, true).build())
101101
} else if (entry.hostName.isEmpty()) {
102-
Toast.makeText(activity, "Please enter a server URL (https://...)", Toast.LENGTH_SHORT)
102+
Toast.makeText(activity, getString(R.string.enter_server_url), Toast.LENGTH_SHORT)
103103
.show()
104104
} else if (entry.apiKey.isEmpty()) {
105105
Toast.makeText(
106106
activity,
107-
"Please enter an API key, if you did enter it, try to highlight it again and press enter/OK, not back (sorry).",
107+
getString(R.string.enter_api_key),
108108
Toast.LENGTH_LONG
109109
).show()
110110
} else {
111-
Toast.makeText(activity, "Please enter a valid server URL (https://...)", Toast.LENGTH_SHORT)
111+
Toast.makeText(activity, getString(R.string.enter_valid_server_url), Toast.LENGTH_SHORT)
112112
.show()
113113
}
114114
}
@@ -120,4 +120,4 @@ class AuthFragmentStep2 : GuidedStepSupportFragment() {
120120
val position = findActionPositionById(actionId)
121121
return getActionItemView(position)?.findViewById<GuidedActionEditText>(R.id.guidedactions_item_description)?.text.toString()
122122
}
123-
}
123+
}

app/src/main/java/nl/giejay/android/tv/immich/home/HomeFragment.kt

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import androidx.leanback.widget.PresenterSelector
1616
import androidx.leanback.widget.Row
1717
import androidx.leanback.widget.RowHeaderPresenter
1818
import androidx.leanback.widget.SectionRow
19+
import nl.giejay.android.tv.immich.ImmichApplication
20+
import nl.giejay.android.tv.immich.R
1921
import nl.giejay.android.tv.immich.album.AlbumFragment
2022
import nl.giejay.android.tv.immich.assets.AllAssetFragment
2123
import nl.giejay.android.tv.immich.assets.FolderFragment
@@ -53,11 +55,11 @@ class HomeFragment : BrowseSupportFragment() {
5355
}
5456

5557
headersSupportFragment.setOnHeaderClickedListener { _, row ->
56-
if (row.headerItem.name == "Edit") {
58+
if (row.headerItem.name == getString(R.string.edit)) {
5759
immichRowPresenter.editMode = !immichRowPresenter.editMode
5860
if(immichRowPresenter.editMode){
5961
mRowsAdapter.clear()
60-
mRowsAdapter.addAll(0, rows.filter { it.headerItem.name != "Settings" })
62+
mRowsAdapter.addAll(0, rows.filter { it.headerItem.name != getString(R.string.settings) })
6163
} else {
6264
mRowsAdapter.clear();
6365
mRowsAdapter.addAll(0, rows.filter { !PreferenceManager.itemInStringSet(it.headerItem.name, HIDDEN_HOME_ITEMS) })
@@ -79,7 +81,7 @@ class HomeFragment : BrowseSupportFragment() {
7981
headersState = HEADERS_ENABLED
8082
isHeadersTransitionOnBackEnabled = true
8183
brandColor = resources.getColor(android.R.color.black)
82-
title = "Albums"
84+
title = getString(R.string.albums)
8385
// setOnSearchClickedListener {
8486
// Toast.makeText(
8587
// activity, "Search!", Toast.LENGTH_SHORT
@@ -119,21 +121,21 @@ class HomeFragment : BrowseSupportFragment() {
119121

120122
companion object {
121123
private val HEADERS: List<Header> = listOf(
122-
Header("Albums") {
124+
Header(ImmichApplication.appContext!!.getString(R.string.albums)) {
123125
AlbumFragment().apply {
124126
arguments = bundleOf("selectionMode" to false)
125127
}
126128
},
127-
Header("Photos") { AllAssetFragment() },
128-
Header("Random") { RandomAssetsFragment() },
129-
Header("People") { PeopleFragment() },
130-
Header("Recent") { RecentAssetsFragment() },
131-
Header("Seasonal") { SimilarTimeAssetsFragment() },
132-
Header("Folders") { FolderFragment() },
133-
Header("Edit") { GridFragment(hideProgressBar = true) },
134-
Header("Settings") { SettingsFragment() },
129+
Header(ImmichApplication.appContext!!.getString(R.string.photos)) { AllAssetFragment() },
130+
Header(ImmichApplication.appContext!!.getString(R.string.random)) { RandomAssetsFragment() },
131+
Header(ImmichApplication.appContext!!.getString(R.string.people)) { PeopleFragment() },
132+
Header(ImmichApplication.appContext!!.getString(R.string.recent)) { RecentAssetsFragment() },
133+
Header(ImmichApplication.appContext!!.getString(R.string.seasonal)) { SimilarTimeAssetsFragment() },
134+
Header(ImmichApplication.appContext!!.getString(R.string.folders)) { FolderFragment() },
135+
Header(ImmichApplication.appContext!!.getString(R.string.edit)) { GridFragment(hideProgressBar = true) },
136+
Header(ImmichApplication.appContext!!.getString(R.string.settings)) { SettingsFragment() },
135137
)
136138
}
137139
}
138140

139-
class Header(val name: String, var show: Boolean = false, val fragment: () -> Fragment)
141+
class Header(val name: String, var show: Boolean = false, val fragment: () -> Fragment)

app/src/main/java/nl/giejay/android/tv/immich/home/ImmichRowPresenter.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class ImmichRowPresenter : Presenter() {
2626
vh.tvTitle.text = headerItem?.name
2727

2828
if (editMode) {
29-
if (headerItem?.name == "Edit") {
30-
vh.tvTitle.text = "Done"
29+
if (headerItem?.name == viewHolder.view.context.getString(R.string.edit)) {
30+
vh.tvTitle.text = viewHolder.view.context.getString(R.string.done)
3131
} else {
3232
vh.icon.visibility = View.VISIBLE
3333
if (PreferenceManager.itemInStringSet(headerItem?.name, HIDDEN_HOME_ITEMS)) {
@@ -46,4 +46,4 @@ class ImmichRowPresenter : Presenter() {
4646
vh.tvTitle.text = null
4747
}
4848

49-
}
49+
}

app/src/main/java/nl/giejay/android/tv/immich/screensaver/ScreenSaverService.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import nl.giejay.mediaslider.util.LoadMore
4646
import nl.giejay.mediaslider.util.MediaSliderListener
4747
import nl.giejay.mediaslider.view.MediaSliderView
4848
import timber.log.Timber
49+
import nl.giejay.android.tv.immich.R
4950
import java.util.EnumSet
5051

5152
class ScreenSaverService : DreamService(), MediaSliderListener {
@@ -59,7 +60,7 @@ class ScreenSaverService : DreamService(), MediaSliderListener {
5960
override fun onDreamingStarted() {
6061
Timber.i("Starting screensaver")
6162
if (!PreferenceManager.isLoggedId()) {
62-
showErrorMessage("Could not start screensaver for Immich because of invalid Hostname/API key")
63+
showErrorMessage(getString(R.string.screensaver_not_possible))
6364
finish()
6465
return
6566
}
@@ -144,12 +145,12 @@ class ScreenSaverService : DreamService(), MediaSliderListener {
144145
}
145146
}
146147
} else {
147-
showErrorMessageMainScope("Set the Immich albums to show in the screensaver settings")
148+
showErrorMessageMainScope(getString(R.string.set_albums_screensaver_error))
148149
finish()
149150
}
150151
} catch (e: Exception) {
151152
Timber.e(e, "Could not fetch assets from Immich for Screensaver")
152-
showErrorMessageMainScope("Could not load assets from Immich")
153+
showErrorMessageMainScope(getString(R.string.could_not_load_assets))
153154
finish()
154155
}
155156
}
@@ -181,7 +182,7 @@ class ScreenSaverService : DreamService(), MediaSliderListener {
181182
private suspend fun setInitialAssets(assets: List<Asset>, loadMore: LoadMore?) = withContext(Dispatchers.Main) {
182183
if (assets.isEmpty()) {
183184
Toast.makeText(this@ScreenSaverService,
184-
"No assets to show for screensaver. Please configure a different screensaver type in the settings.",
185+
getString(R.string.no_assets_for_screensaver),
185186
Toast.LENGTH_LONG).show()
186187
} else {
187188
mediaSliderView.loadMediaSliderView(
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
package nl.giejay.android.tv.immich.screensaver
22

33
import nl.giejay.android.tv.immich.shared.prefs.EnumWithTitle
4+
import nl.giejay.android.tv.immich.ImmichApplication
5+
import nl.giejay.android.tv.immich.R
46

57
enum class ScreenSaverType : EnumWithTitle {
68
ALBUMS {
79
override fun getTitle(): String {
8-
return "Albums"
10+
return ImmichApplication.appContext!!.getString(R.string.albums)
911
}
1012
},
1113
RANDOM {
1214
override fun getTitle(): String {
13-
return "Random"
15+
return ImmichApplication.appContext!!.getString(R.string.random)
1416
}
1517
},
1618
RECENT {
1719
override fun getTitle(): String {
18-
return "Recent"
20+
return ImmichApplication.appContext!!.getString(R.string.recent)
1921
}
2022
},
2123
SIMILAR_TIME_PERIOD {
2224
override fun getTitle(): String {
23-
return "Seasonal"
25+
return ImmichApplication.appContext!!.getString(R.string.seasonal)
2426
}
2527
}
26-
}
28+
}

app/src/main/java/nl/giejay/android/tv/immich/settings/MetaDataCustomizerAdapter.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class MetaDataCustomizerAdapter(val context: Context, val metaData: MutableList<
5858
// notifyDataSetChanged()
5959
// }
6060

61-
textView.text = metaDataItem.getTitle()
61+
textView.text = metaDataItem.getTitle(context)
6262
return item
6363
}
64-
}
64+
}

app/src/main/java/nl/giejay/android/tv/immich/settings/MetaDataCustomizerFragment.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class MetaDataCustomizerFragment : Fragment() {
5757
private fun addItem(align: AlignOption, allMetaData: MutableList<MetaDataItem>) {
5858
val findFirstNotAddedMetaDataType = MetaDataType.entries.filterNot { e -> allMetaData.any { it.type == e } }
5959
if (findFirstNotAddedMetaDataType.isEmpty()) {
60-
Toast.makeText(requireContext(), "You already added every possible meta data", Toast.LENGTH_SHORT).show()
60+
Toast.makeText(requireContext(), getString(R.string.already_added_metadata), Toast.LENGTH_SHORT).show()
6161
} else {
6262
val newItem = MetaDataItem.create(findFirstNotAddedMetaDataType.first(), align, MetaDataItem.DEFAULT_PADDING, findFirstNotAddedMetaDataType.first().defaultFontSize)
6363
allMetaData.add(newItem)
@@ -101,4 +101,4 @@ class MetaDataCustomizerFragment : Fragment() {
101101
metaDataScreen)
102102
)
103103
}
104-
}
104+
}

app/src/main/java/nl/giejay/android/tv/immich/settings/MetaDataItemCustomizerFragment.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class MetaDataItemInnerCustomizerFragment : SettingsScreenFragment.SettingsInner
5050
}
5151
val filteredTypes = MetaDataType.entries.filterNot { e -> e != metaDataItem.type && allItems.any { it.type == e } }
5252
type.entryValues = filteredTypes.map { it.toString() }.toTypedArray()
53-
type.entries = filteredTypes.map { it.title }.toTypedArray()
53+
type.entries = filteredTypes.map { it.getTitle(requireContext()) }.toTypedArray()
5454
type.value = metaDataItem.type.toString()
5555

5656
val padding = findPreference<SeekBarPreference>("meta_data_item_padding")
@@ -81,4 +81,4 @@ class MetaDataItemInnerCustomizerFragment : SettingsScreenFragment.SettingsInner
8181
override fun handlePreferenceClick(preference: Preference?): Boolean {
8282
return false
8383
}
84-
}
84+
}

0 commit comments

Comments
 (0)