diff --git a/CHANGELOG.md b/CHANGELOG.md index 31ccd0d..16586f0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. +## v1.4.6 +- Added random password generator. +- Fixed estimated time to crack not translating. +- Added Swedish and Turkish(by [mdksec](https://github.com/mdksec)) translations. + + + ## v1.4.3 - Added support for Android 14. - Added Spanish translations. @@ -25,7 +32,7 @@ All notable changes to this project will be documented in this file. - Select file support for Android 13 and above. - Adaptive app icon. - Included themed icons for Android 13 and above. -- Improved Italian(by [gdonisi](https://github.com/gdonisi)) and French(by [Amiralgaby](https://github.com/Amiralgaby)) translations. +- Improved Italian (by [gdonisi](https://github.com/gdonisi)) and French (by [Amiralgaby](https://github.com/Amiralgaby)) translations. diff --git a/README.md b/README.md index 0619c25..98213e0 100755 --- a/README.md +++ b/README.md @@ -39,7 +39,6 @@ Using this app you can determine whether the passwords are most commonly used on - Fully open source - Material design - Completely offline -- Works on Android 6.0 and above devices - Supports both light and dark theme - No ads - No collection of personal data @@ -53,6 +52,8 @@ Using this app you can determine whether the passwords are most commonly used on + + ## Download diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 12ecf26..1ac8306 100755 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -30,8 +30,8 @@ android { applicationId = "com.iyps" minSdk = 23 targetSdk = 34 - versionCode = 144 - versionName = "1.4.4" + versionCode = 146 + versionName = "1.4.6" } buildTypes { diff --git a/app/src/main/java/com/iyps/activities/MainActivity.kt b/app/src/main/java/com/iyps/activities/MainActivity.kt index 3a4655b..3e36c7a 100755 --- a/app/src/main/java/com/iyps/activities/MainActivity.kt +++ b/app/src/main/java/com/iyps/activities/MainActivity.kt @@ -81,11 +81,17 @@ class MainActivity : AppCompatActivity() { val actionsMap = mapOf(Pair(R.id.fileFragment, R.id.nav_password) to R.id.action_fileFragment_to_passwordFragment, + Pair(R.id.generateFragment, R.id.nav_password) to R.id.action_generateFragment_to_passwordFragment, Pair(R.id.settingsFragment, R.id.nav_password) to R.id.action_settingsFragment_to_passwordFragment, Pair(R.id.passwordFragment, R.id.nav_file) to R.id.action_passwordFragment_to_fileFragment, + Pair(R.id.generateFragment, R.id.nav_file) to R.id.action_generateFragment_to_fileFragment, Pair(R.id.settingsFragment, R.id.nav_file) to R.id.action_settingsFragment_to_fileFragment, + Pair(R.id.passwordFragment, R.id.nav_generate) to R.id.action_passwordFragment_to_generateFragment, + Pair(R.id.fileFragment, R.id.nav_generate) to R.id.action_fileFragment_to_generateFragment, + Pair(R.id.settingsFragment, R.id.nav_generate) to R.id.action_settingsFragment_to_generateFragment, Pair(R.id.passwordFragment, R.id.nav_settings) to R.id.action_passwordFragment_to_settingsFragment, - Pair(R.id.fileFragment, R.id.nav_settings) to R.id.action_fileFragment_to_settingsFragment) + Pair(R.id.fileFragment, R.id.nav_settings) to R.id.action_fileFragment_to_settingsFragment, + Pair(R.id.generateFragment, R.id.nav_settings) to R.id.action_generateFragment_to_settingsFragment) val action = actionsMap[Pair(currentFragment.id, clickedItem)] ?: 0 diff --git a/app/src/main/java/com/iyps/fragments/details/DetailsFragment.kt b/app/src/main/java/com/iyps/fragments/details/DetailsFragment.kt index d2bf4a6..5321f49 100755 --- a/app/src/main/java/com/iyps/fragments/details/DetailsFragment.kt +++ b/app/src/main/java/com/iyps/fragments/details/DetailsFragment.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 StellarSand + * Copyright (c) 2022-present StellarSand * * This file is part of IYPS. * @@ -55,12 +55,19 @@ class DetailsFragment : Fragment() { return fragmentBinding.root } + @SuppressLint("SetTextI18n") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val zxcvbn = (requireContext().applicationContext as ApplicationManager).zxcvbn passwordString = (requireActivity() as DetailsActivity).passwordLine /*########################################################################################*/ + + fragmentBinding.lengthSubtitle.text = "\u2022 ${getString(R.string.length)}" + fragmentBinding.uppercaseText.text = "\u2022 ${getString(R.string.uppercase)}" + fragmentBinding.lowercaseSubtitle.text = "\u2022 ${getString(R.string.lowercase)}" + fragmentBinding.numbersSubtitle.text = "\u2022 ${getString(R.string.numbers)}" + fragmentBinding.specialCharsSubtitle.text = "\u2022 ${getString(R.string.special_char)}" fragmentBinding.passwordText.apply { setText(passwordString) @@ -125,7 +132,6 @@ class DetailsFragment : Fragment() { fragmentBinding.orderMagnSubtitle.text = strength.guessesLog10.formatToTwoDecimalPlaces() // Entropy - @SuppressLint("SetTextI18n") fragmentBinding.entropySubtitle.text = "${log2(guesses).formatToTwoDecimalPlaces()} ${getString(R.string.bits)}" @@ -135,8 +141,8 @@ class DetailsFragment : Fragment() { // Statistics val statsList = getStatisticsCounts(passwordString) fragmentBinding.lengthText.text = statsList[0].toString() - fragmentBinding.upperCaseText.text = statsList[1].toString() - fragmentBinding.lowerCaseText.text = statsList[2].toString() + fragmentBinding.uppercaseText.text = statsList[1].toString() + fragmentBinding.lowercaseText.text = statsList[2].toString() fragmentBinding.numbersText.text = statsList[3].toString() fragmentBinding.specialCharsText.text = statsList[4].toString() } diff --git a/app/src/main/java/com/iyps/fragments/main/GenerateFragment.kt b/app/src/main/java/com/iyps/fragments/main/GenerateFragment.kt new file mode 100644 index 0000000..fa860a1 --- /dev/null +++ b/app/src/main/java/com/iyps/fragments/main/GenerateFragment.kt @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2022-present StellarSand + * + * This file is part of IYPS. + * + * IYPS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * IYPS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IYPS. If not, see . + */ + +package com.iyps.fragments.main + +import android.annotation.SuppressLint +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context.CLIPBOARD_SERVICE +import android.content.Intent +import android.content.res.ColorStateList +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.google.android.material.materialswitch.MaterialSwitch +import com.google.android.material.slider.Slider +import com.google.android.material.slider.Slider.OnSliderTouchListener +import com.google.android.material.snackbar.BaseTransientBottomBar +import com.google.android.material.snackbar.Snackbar +import com.iyps.R +import com.iyps.activities.DetailsActivity +import com.iyps.activities.MainActivity +import com.iyps.databinding.FragmentGenerateBinding +import com.iyps.preferences.PreferenceManager +import com.iyps.preferences.PreferenceManager.Companion.AMB_CHARS +import com.iyps.preferences.PreferenceManager.Companion.LOWERCASE +import com.iyps.preferences.PreferenceManager.Companion.NUMBERS +import com.iyps.preferences.PreferenceManager.Companion.PASS_LENGTH +import com.iyps.preferences.PreferenceManager.Companion.SPACES +import com.iyps.preferences.PreferenceManager.Companion.SPEC_CHARS +import com.iyps.preferences.PreferenceManager.Companion.UPPERCASE +import java.security.SecureRandom + +class GenerateFragment : Fragment() { + + private var _binding: FragmentGenerateBinding? = null + private val fragmentBinding get() = _binding!! + private lateinit var preferenceManager: PreferenceManager + private lateinit var uppercaseSwitch: MaterialSwitch + private lateinit var lowercaseSwitch: MaterialSwitch + private lateinit var numbersSwitch: MaterialSwitch + private lateinit var specialCharsSwitch: MaterialSwitch + private lateinit var avoidAmbCharsSwitch: MaterialSwitch + private lateinit var includeSpaceSwitch: MaterialSwitch + private lateinit var primarySwitchesList: List + private lateinit var primarySwitchesPrefMap: Map + + companion object { + val uppercaseChars = ('A'..'Z').joinToString("") + val lowercaseChars = ('a'..'z').joinToString("") + val numbers = ('0'..'9').joinToString("") + const val specialChars = "!@#$%^&*-_=+<.>" + const val ambChars = "IiLlOo05S8B|" + } + + override fun onCreateView(inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?): View { + // Inflate the layout for this fragment + _binding = FragmentGenerateBinding.inflate(inflater, container, false) + return fragmentBinding.root + } + + @SuppressLint("SetTextI18n") + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + + val mainActivity = requireActivity() as MainActivity + preferenceManager = PreferenceManager(requireContext()) + uppercaseSwitch = fragmentBinding.uppercaseSwitch + lowercaseSwitch = fragmentBinding.lowercaseSwitch + numbersSwitch = fragmentBinding.numbersSwitch + specialCharsSwitch = fragmentBinding.specialCharsSwitch + avoidAmbCharsSwitch = fragmentBinding.avoidAmbCharsSwitch + includeSpaceSwitch = fragmentBinding.includeSpacesSwitch + + primarySwitchesList = listOf(uppercaseSwitch, + lowercaseSwitch, + numbersSwitch, + specialCharsSwitch) + + primarySwitchesPrefMap = mapOf(uppercaseSwitch to UPPERCASE, + lowercaseSwitch to LOWERCASE, + numbersSwitch to NUMBERS, + specialCharsSwitch to SPEC_CHARS) + + // Password length slider + fragmentBinding.passwordLengthSlider.apply { + value = preferenceManager.getFloat(PASS_LENGTH) + fragmentBinding.lengthText.text = "${getString(R.string.length)}: ${value.toInt()}" + setSliderThumbColor(this, value) + + addOnSliderTouchListener(object : OnSliderTouchListener { + override fun onStartTrackingTouch(slider: Slider) {} + + override fun onStopTrackingTouch(slider: Slider) { + generatePassword() + } + + }) + + addOnChangeListener { slider, value, _ -> + fragmentBinding.lengthText.text = "${getString(R.string.length)}: ${slider.value.toInt()}" + setSliderThumbColor(slider, value) + } + } + + // Switches + // At least one switch must be enabled at all times (excluding ambiguous chars switch) + primarySwitchesList.forEach { switch -> + primarySwitchesPrefMap[switch]?.let { preferenceKey -> + switch.isChecked = preferenceManager.getBoolean(preferenceKey) + } + switch.setOnCheckedChangeListener { _, _ -> + val otherSwitches = primarySwitchesList.filter { it != switch } + val otherSwitchesChecked = otherSwitches.any { it.isChecked } + if (otherSwitchesChecked) { + generatePassword() + } + else { + switch.isChecked = true + } + } + } + avoidAmbCharsSwitch.apply { + isChecked = preferenceManager.getBoolean(AMB_CHARS) + setOnCheckedChangeListener { _, _ -> + generatePassword() + } + } + includeSpaceSwitch.apply { + isChecked = preferenceManager.getBooleanDefValFalse(SPACES) + setOnCheckedChangeListener { _, _ -> + generatePassword() + } + } + + generatePassword() + + // Details + fragmentBinding.detailsBtn.setOnClickListener { + startActivity(Intent(requireActivity(), DetailsActivity::class.java) + .putExtra("PwdLine", fragmentBinding.generatedPasswordTextView.text)) + } + + // Copy + fragmentBinding.copyPasswordBtn.setOnClickListener { + val clipData = ClipData.newPlainText("Generated password", + fragmentBinding.generatedPasswordTextView.text) + + (requireContext().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager) + .setPrimaryClip(clipData) + + Snackbar.make(mainActivity.activityBinding.mainCoordLayout, + getString(R.string.copied_to_clipboard), + BaseTransientBottomBar.LENGTH_SHORT) + .setAnchorView(mainActivity.activityBinding.mainBottomNav) + .show() + } + + // Regenerate + fragmentBinding.regenerateBtn.setOnClickListener { + generatePassword() + } + + // Share + fragmentBinding.shareBtn.setOnClickListener { + startActivity(Intent.createChooser(Intent(Intent.ACTION_SEND) + .setType("text/plain") + .putExtra(Intent.EXTRA_TEXT, fragmentBinding.generatedPasswordTextView.text), + getString(R.string.share))) + } + + } + + private fun setSliderThumbColor(slider: Slider, value: Float) { + val sliderThumbColor = + if (value == 5f) { + requireContext().getColor(R.color.color_primary) + } + else { + requireContext().getColor(R.color.color_onPrimary) + } + + slider.thumbTintList = ColorStateList.valueOf(sliderThumbColor) + } + + private fun generatePassword() { + val allChars = buildString { + if (uppercaseSwitch.isChecked) { + append(if (avoidAmbCharsSwitch.isChecked) uppercaseChars.filterNot { it in ambChars } + else uppercaseChars) + } + if (lowercaseSwitch.isChecked) { + append(if (avoidAmbCharsSwitch.isChecked) lowercaseChars.filterNot { it in ambChars } + else lowercaseChars) + } + if (numbersSwitch.isChecked) { + append(if (avoidAmbCharsSwitch.isChecked) numbers.filterNot { it in ambChars } + else numbers) + } + if (specialCharsSwitch.isChecked) { + append(if (avoidAmbCharsSwitch.isChecked) specialChars.filterNot { it in ambChars } + else specialChars) + } + } + + val password = buildString { + val length = fragmentBinding.passwordLengthSlider.value.toInt() + val spacesToInsert = + if (includeSpaceSwitch.isChecked) SecureRandom().nextInt(length) + else 0 + + for (i in 0 until length) { + if (includeSpaceSwitch.isChecked + && i > 0 // Avoid space at beginning + && i < length - 1 // Avoid space at end + && i < spacesToInsert) { + append(' ') + } + else { + val randomIndex = SecureRandom().nextInt(allChars.length) + append(allChars[randomIndex]) + } + } + } + + fragmentBinding.generatedPasswordTextView.text = password + } + + override fun onPause() { + super.onPause() + preferenceManager.setFloat(PASS_LENGTH, fragmentBinding.passwordLengthSlider.value) + primarySwitchesList.forEach { switch -> + primarySwitchesPrefMap[switch]?.let { preferenceKey -> + preferenceManager.setBoolean(preferenceKey, switch.isChecked) + } + } + preferenceManager.setBoolean(AMB_CHARS, fragmentBinding.avoidAmbCharsSwitch.isChecked) + preferenceManager.setBoolean(SPACES, fragmentBinding.includeSpacesSwitch.isChecked) + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/iyps/fragments/main/PasswordFragment.kt b/app/src/main/java/com/iyps/fragments/main/PasswordFragment.kt index 91163bd..db4a74e 100755 --- a/app/src/main/java/com/iyps/fragments/main/PasswordFragment.kt +++ b/app/src/main/java/com/iyps/fragments/main/PasswordFragment.kt @@ -65,12 +65,19 @@ class PasswordFragment : Fragment() { return fragmentBinding.root } + @SuppressLint("SetTextI18n") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val zxcvbn = (requireContext().applicationContext as ApplicationManager).zxcvbn clipboardManager = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager /*########################################################################################*/ + + fragmentBinding.lengthSubtitle.text = "\u2022 ${getString(R.string.length)}" + fragmentBinding.uppercaseSubtitle.text = "\u2022 ${getString(R.string.uppercase)}" + fragmentBinding.lowercaseSubtitle.text = "\u2022 ${getString(R.string.lowercase)}" + fragmentBinding.numbersSubtitle.text = "\u2022 ${getString(R.string.numbers)}" + fragmentBinding.specialCharsSubtitle.text = "\u2022 ${getString(R.string.special_char)}" fragmentBinding.passwordText.apply { @@ -156,7 +163,6 @@ class PasswordFragment : Fragment() { fragmentBinding.orderMagnSubtitle.text = strength.guessesLog10.formatToTwoDecimalPlaces() // Entropy - @SuppressLint("SetTextI18n") fragmentBinding.entropySubtitle.text = "${log2(guesses).formatToTwoDecimalPlaces()} ${getString(R.string.bits)}" @@ -167,8 +173,8 @@ class PasswordFragment : Fragment() { // Statistics val statsList = getStatisticsCounts(charSequence) fragmentBinding.lengthText.text = statsList[0].toString() - fragmentBinding.upperCaseText.text = statsList[1].toString() - fragmentBinding.lowerCaseText.text = statsList[2].toString() + fragmentBinding.uppercaseText.text = statsList[1].toString() + fragmentBinding.lowercaseText.text = statsList[2].toString() fragmentBinding.numbersText.text = statsList[3].toString() fragmentBinding.specialCharsText.text = statsList[4].toString() @@ -211,8 +217,8 @@ class PasswordFragment : Fragment() { fragmentBinding.entropySubtitle.text = notApplicableString fragmentBinding.matchSequenceSubtitle.text = notApplicableString fragmentBinding.lengthText.text = zeroString - fragmentBinding.upperCaseText.text = zeroString - fragmentBinding.lowerCaseText.text = zeroString + fragmentBinding.uppercaseText.text = zeroString + fragmentBinding.lowercaseText.text = zeroString fragmentBinding.numbersText.text = zeroString fragmentBinding.specialCharsText.text = zeroString diff --git a/app/src/main/java/com/iyps/preferences/PreferenceManager.kt b/app/src/main/java/com/iyps/preferences/PreferenceManager.kt index 219900e..2b79cec 100755 --- a/app/src/main/java/com/iyps/preferences/PreferenceManager.kt +++ b/app/src/main/java/com/iyps/preferences/PreferenceManager.kt @@ -28,6 +28,13 @@ class PreferenceManager(context: Context) { const val THEME_PREF = "theme" const val BLOCK_SS = "block_ss" const val INCOG_KEYBOARD = "incog_keyboard" + const val PASS_LENGTH = "pass_length" + const val UPPERCASE = "uppercase" + const val LOWERCASE = "lowercase" + const val NUMBERS = "numbers" + const val SPEC_CHARS = "spec_chars" + const val AMB_CHARS = "amb_chars" + const val SPACES = "spaces" } private val sharedPreferences = @@ -43,10 +50,24 @@ class PreferenceManager(context: Context) { editor.apply() } + fun getFloat(key: String): Float { + return sharedPreferences.getFloat(key, 20f) + } + + fun setFloat(key: String, float: Float) { + val editor = sharedPreferences.edit() + editor.putFloat(key, float) + editor.apply() + } + fun getBoolean(key: String): Boolean { return sharedPreferences.getBoolean(key, true) } + fun getBooleanDefValFalse(key: String): Boolean { + return sharedPreferences.getBoolean(key, false) + } + fun setBoolean(key: String, boolean: Boolean) { val editor = sharedPreferences.edit() editor.putBoolean(key, boolean) diff --git a/app/src/main/res/drawable/ic_copy.xml b/app/src/main/res/drawable/ic_copy.xml new file mode 100644 index 0000000..6845106 --- /dev/null +++ b/app/src/main/res/drawable/ic_copy.xml @@ -0,0 +1,33 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_customize.xml b/app/src/main/res/drawable/ic_customize.xml new file mode 100644 index 0000000..fd7f490 --- /dev/null +++ b/app/src/main/res/drawable/ic_customize.xml @@ -0,0 +1,32 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_details.xml b/app/src/main/res/drawable/ic_details.xml new file mode 100644 index 0000000..5199054 --- /dev/null +++ b/app/src/main/res/drawable/ic_details.xml @@ -0,0 +1,32 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_generate.xml b/app/src/main/res/drawable/ic_generate.xml new file mode 100644 index 0000000..635ac6f --- /dev/null +++ b/app/src/main/res/drawable/ic_generate.xml @@ -0,0 +1,32 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_regenerate.xml b/app/src/main/res/drawable/ic_regenerate.xml new file mode 100644 index 0000000..00b8341 --- /dev/null +++ b/app/src/main/res/drawable/ic_regenerate.xml @@ -0,0 +1,32 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_share.xml b/app/src/main/res/drawable/ic_share.xml new file mode 100644 index 0000000..7802e00 --- /dev/null +++ b/app/src/main/res/drawable/ic_share.xml @@ -0,0 +1,32 @@ + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index da38751..91a96f5 100755 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -46,7 +46,6 @@ app:itemActiveIndicatorStyle="@style/NavIndicatorStyle" app:itemIconTint="@color/color_text_title" app:itemTextAppearanceActive="@style/NavTextActive" - app:itemTextAppearanceInactive="@style/NavTextInactive" app:menu="@menu/menu_bottom_nav"/> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_generate.xml b/app/src/main/res/layout/fragment_generate.xml new file mode 100644 index 0000000..cd3fa40 --- /dev/null +++ b/app/src/main/res/layout/fragment_generate.xml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_password.xml b/app/src/main/res/layout/fragment_password.xml index ce9b68e..9a144a6 100755 --- a/app/src/main/res/layout/fragment_password.xml +++ b/app/src/main/res/layout/fragment_password.xml @@ -23,10 +23,10 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" - tools:ignore="ContentDescription" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" + tools:ignore="ContentDescription" tools:context=".fragments.main.PasswordFragment"> + app:layout_constraintTop_toBottomOf="@id/uppercase_subtitle" /> + app:layout_constraintTop_toBottomOf="@id/uppercase_subtitle" /> + app:layout_constraintTop_toBottomOf="@id/lowercase_subtitle" /> + app:layout_constraintTop_toBottomOf="@id/lowercase_subtitle" /> + + Passwort Datei + Erzeugen Sie Einstellungen @@ -83,11 +84,11 @@ \u2022 %1$s mal verschoben \u2022 Regex name Statistik - \u2022 L\u00E4nge - \u2022 Gro\u00DFbuchstaben - \u2022 Kleinbuchstaben - \u2022 Zahlen - \u2022 Spezielle charaktere + L\u00E4nge + Gro\u00DFbuchstaben + Kleinbuchstaben + Zahlen + Spezielle charaktere @@ -98,6 +99,16 @@ + + Kopieren + Regenerieren Sie + Teilen Sie + Anpassen + Vermeiden Sie zweideutige Zeichen + R\u00E4ume einbeziehen + + + Thema Datenschutz @@ -131,5 +142,6 @@ Es ist kein browser auf diesem ger\u00E4t installiert + In die Zwischenablage kopiert \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 2638685..2f398d1 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -36,6 +36,7 @@ Contrase\u00F1a Archivo + Genere Ajustes @@ -84,11 +85,11 @@ \u2022 Desplazado %1$s veces \u2022 Nombre Regex Estad\u00EDsticas - \u2022 Longitud - \u2022 May\u00FAsculas - \u2022 Min\u00FAsculas - \u2022 N\u00FAmeros - \u2022 Caracteres especiales + Longitud + May\u00FAsculas + Min\u00FAsculas + N\u00FAmeros + Caracteres especiales @@ -98,6 +99,16 @@ + + Copia + Regenere + Compartir + Personalice + Evite los caracteres ambiguos + Incluir espacios + + + Tem\u00E1tica Privacidad @@ -131,5 +142,6 @@ No hay navegadores instalados en este dispositivo + Copiado al portapapeles \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 77625c6..6639f4a 100755 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -36,6 +36,7 @@ Mot de passe Dossier + G\u00E9n\u00E9rer Param\u00E8tres @@ -84,11 +85,11 @@ \u2022 D\u00E9cal\u00E9 %1$s fois \u2022 Nom de l\'expression rationnelle Statistiques - \u2022 Longueur - \u2022 Majuscules - \u2022 Minuscules - \u2022 Chiffres - \u2022 Caract\u00E8res sp\u00E9ciaux + Longueur + Majuscules + Minuscules + Chiffres + Caract\u00E8res sp\u00E9ciaux @@ -99,6 +100,16 @@ + + Copie + R\u00E9g\u00E9n\u00E9rer + Partager + Personnaliser + \u00C9viter les caract\u00E8res ambigus + Inclure les espaces + + + Th\u00E8me Vie priv\u00E9e @@ -132,5 +143,6 @@ Aucun navigateur n\'est install\u00E9 sur cet appareil + Copi\u00E9 dans le presse-papiers \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 20922df..ccf2193 100755 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -32,6 +32,7 @@ Password File + Generare Impostazioni @@ -80,11 +81,11 @@ \u2022 Spostato %1$s volte \u2022 Nome Regex Statistiche - \u2022 Lunghezza - \u2022 Maiuscole - \u2022 Minuscole - \u2022 Numeri - \u2022 Caratteri speciali + Lunghezza + Maiuscole + Minuscole + Numeri + Caratteri speciali @@ -95,6 +96,16 @@ + + Copia + Rigenerare + Condividi + Personalizzare + Evitare i caratteri ambigui + Includere spazi + + + Tema Privacy @@ -128,5 +139,6 @@ Nessun browser installato sul dispositivo + Copiato negli appunti \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 7346802..c684fc7 100755 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -26,6 +26,7 @@ パスワード ファイル + 生成する 設定 @@ -74,11 +75,11 @@ \u2022 %1$s回シフト \u2022 正規表現名 統計情報 - \u2022 長さ - \u2022 大文字 - \u2022 小文字 - \u2022 数字 - \u2022 特殊文字 + 長さ + 大文字 + 小文字 + 数字 + 特殊文字 @@ -89,6 +90,16 @@ + + コピー + 再生 + シェア + カスタマイズ + 曖昧な文字は避ける + スペースを含む + + + テーマ プライバシー @@ -122,5 +133,6 @@ このデバイスにブラウザがインストールされていません + クリップボードにコピー \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 4f63393..d673b87 100755 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -1,7 +1,7 @@ Wachtwoord Bestand + Genereren Instellingen @@ -79,11 +80,11 @@ \u2022 Verschoven %1$s keer \u2022 Regex naam Statistieken - \u2022 Lengte - \u2022 Hoofdletters - \u2022 Kleineletters - \u2022 Cijfers - \u2022 Speciale tekens + Lengte + Hoofdletters + Kleineletters + Cijfers + Speciale tekens @@ -94,6 +95,16 @@ + + Kopie + Regenereer + Deel + Pas aan + Vermijd dubbelzinnige tekens + Ruimtes opnemen + + + Thema Privacy @@ -127,5 +138,6 @@ Geen browsers ge\u00EFnstalleerd op dit apparaat + Gekopieerd naar klembord \ No newline at end of file diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 766c0c6..1813396 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -34,6 +34,7 @@ L\u00F6senord Fil + Generera Inst\u00E4llningar @@ -82,11 +83,11 @@ \u2022 F\u00F6rskjuten %1$s g\u00E5nger \u2022 Regex namn Statistik - \u2022 L\u00E4ngd - \u2022 Stora bokst\u00E4ver - \u2022 L\u00E4gre fall - \u2022 Siffror - \u2022 S\u00E4rskilda tecken + L\u00E4ngd + Stora bokst\u00E4ver + L\u00E4gre fall + Siffror + S\u00E4rskilda tecken @@ -96,6 +97,16 @@ + + Kopia + Regenerera + Andel + Anpassa + Undvik tvetydiga tecken + Inkludera utrymmen + + + Tema Integritet @@ -129,5 +140,6 @@ Inga webbl\u00E4sare installerade p\u00E5 den h\u00E4r enheten + Kopierad till urklipp \ No newline at end of file diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 9852602..f6aab53 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -44,6 +44,7 @@ \u015Eifre Dosya + Olu\u015Fturmak Ayarlar @@ -92,11 +93,11 @@ \u2022 %1$s kez kayd\u0131r\u0131lm\u0131\u015F \u2022 Regex ad\u0131 \u0130statistikler - \u2022 Uzunluk - \u2022 B\u00FCy\u00FCk harf - \u2022 K\u00FC\u00E7\u00FCk harf - \u2022 Say\u0131lar - \u2022 \u00D6zel karakterler + Uzunluk + B\u00FCy\u00FCk harf + K\u00FC\u00E7\u00FCk harf + Say\u0131lar + \u00D6zel karakterler @@ -106,6 +107,16 @@ + + Anla\u015F\u0131ld\u0131 + Yenilenme + Payla\u015F + \u00D6zelle\u015Ftirme + Belirsiz karakterlerden ka\u00E7\u0131n\u0131n + Bo\u015Fluklar\u0131 dahil edin + + + Tema Gizlilik @@ -139,5 +150,6 @@ Bu cihazda y\u00FCkl\u00FC taray\u0131c\u0131 yok + Panoya kopyaland\u0131 \ No newline at end of file diff --git a/app/src/main/res/values-v27/themes.xml b/app/src/main/res/values-v27/themes.xml index 0071b77..1779173 100755 --- a/app/src/main/res/values-v27/themes.xml +++ b/app/src/main/res/values-v27/themes.xml @@ -1,6 +1,7 @@ + 75dp - 50dp - 35dp + 32dp 30dp 25dp 22dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0701d07..037131d 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,6 +31,7 @@ Password File + Generate Settings @@ -79,11 +80,11 @@ \u2022 Shifted %1$s times \u2022 Regex name Statistics - \u2022 Length - \u2022 Upper case - \u2022 Lower case - \u2022 Numbers - \u2022 Special characters + Length + Uppercase + Lowercase + Numbers + Special characters @@ -93,6 +94,16 @@ + + Copy + Regenerate + Share + Customize + Avoid ambiguous characters + Include spaces + + + Theme Privacy @@ -126,5 +137,6 @@ No browsers installed on this device + Copied to clipboard \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 1b27bcc..32fc22a 100755 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,7 +1,7 @@ diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 0b6374b..13a5050 100755 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,6 +1,7 @@ + + https://github.com/StellarSand/IYPS/graphs/contributors diff --git a/fastlane/metadata/android/de-DE/changelogs/146.txt b/fastlane/metadata/android/de-DE/changelogs/146.txt new file mode 100644 index 0000000..c04f11a --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/146.txt @@ -0,0 +1,3 @@ +- Zufallsgenerator für Passwörter hinzugefügt. +- Die geschätzte Zeit bis zum Knacken wurde nicht übersetzt. +- Schwedische und türkische Übersetzungen hinzugefügt. \ No newline at end of file diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt index a2dcf3e..1efc601 100755 --- a/fastlane/metadata/android/de-DE/full_description.txt +++ b/fastlane/metadata/android/de-DE/full_description.txt @@ -7,5 +7,4 @@ Merkmale: - Völlig offline - Unterstützt sowohl das licht als auch das dunkle thema - Keine werbung -- Keine sammlung personenbezogener daten -- Unterstützte Sprachen: Englisch, Niederländisch, Französisch, Deutsch, Italienisch, Japanisch, Spanisch, Schwedisch, Türkisch +- Keine sammlung personenbezogener daten \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/146.txt b/fastlane/metadata/android/en-US/changelogs/146.txt new file mode 100644 index 0000000..8fbe4e8 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/146.txt @@ -0,0 +1,3 @@ +- Added random password generator. +- Fixed estimated time to crack not translating. +- Added Swedish and Turkish translations. \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index b5861d2..9640443 100755 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -7,5 +7,4 @@ Features: - Completely offline - Supports both light and dark theme - No ads -- No collection of personal data -- Supported languages: English, Dutch, French, German, Italian, Japanese, Spanish, Swedish, Turkish +- No collection of personal data \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png index 9e94bd1..c92cafd 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png index a7ca483..445bcaa 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png index 8cc8a6e..119008e 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png index 9c4b866..98bb00a 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png new file mode 100644 index 0000000..c540ad7 Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png new file mode 100644 index 0000000..e43583a Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/es-ES/changelogs/146.txt b/fastlane/metadata/android/es-ES/changelogs/146.txt new file mode 100644 index 0000000..c3bd707 --- /dev/null +++ b/fastlane/metadata/android/es-ES/changelogs/146.txt @@ -0,0 +1,3 @@ +- Añadido generador de contraseñas aleatorias. +- Corregido el tiempo estimado para crackear que no se traducía. +- Añadidas traducciones al sueco y al turco. \ No newline at end of file diff --git a/fastlane/metadata/android/es-ES/full_description.txt b/fastlane/metadata/android/es-ES/full_description.txt index 2872bf1..fb75642 100755 --- a/fastlane/metadata/android/es-ES/full_description.txt +++ b/fastlane/metadata/android/es-ES/full_description.txt @@ -7,5 +7,4 @@ Características: - Completamente offline - Soporta temas claros y oscuros - Sin anuncios -- No recopila datos personales -- Idiomas soportados: Inglés, Holandés, Francés, Alemán, Italiano, Japonés, Español, Sueco, Turco \ No newline at end of file +- No recopila datos personales \ No newline at end of file diff --git a/fastlane/metadata/android/fr-FR/changelogs/146.txt b/fastlane/metadata/android/fr-FR/changelogs/146.txt new file mode 100644 index 0000000..8c93eb7 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/146.txt @@ -0,0 +1,3 @@ +- Ajout d'un générateur de mot de passe aléatoire. +- Correction de l'erreur de traduction de l'estimation du temps de craquage. +- Ajout de traductions en suédois et en turc. \ No newline at end of file diff --git a/fastlane/metadata/android/fr-FR/full_description.txt b/fastlane/metadata/android/fr-FR/full_description.txt index d5c4d26..4535347 100755 --- a/fastlane/metadata/android/fr-FR/full_description.txt +++ b/fastlane/metadata/android/fr-FR/full_description.txt @@ -7,5 +7,4 @@ Caractéristiques: - Complètement hors ligne - Soutient le thème léger et sombre - Pas de pubs -- Pas de collection de données personnelles -- Langues prises en charge: Anglais, Néerlandais, Français, Allemand, Italien, Japonais, Espagnol, Suédois, Turc +- Pas de collection de données personnelles \ No newline at end of file diff --git a/fastlane/metadata/android/it-IT/changelogs/146.txt b/fastlane/metadata/android/it-IT/changelogs/146.txt new file mode 100644 index 0000000..50df558 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/146.txt @@ -0,0 +1,3 @@ +- Aggiunto generatore di password casuali. +- Corretto il tempo stimato per il cracking che non viene tradotto. +- Aggiunte le traduzioni in svedese e turco. \ No newline at end of file diff --git a/fastlane/metadata/android/it-IT/full_description.txt b/fastlane/metadata/android/it-IT/full_description.txt index d2224f0..ce72c7e 100755 --- a/fastlane/metadata/android/it-IT/full_description.txt +++ b/fastlane/metadata/android/it-IT/full_description.txt @@ -7,5 +7,4 @@ Caratteristiche: - Completamente offline - Supporta sia tema chiaro che scuro - Nessuna pubblicità -- Nessuna raccolta di dati personali -- Lingue supportate: Inglese, Olandese, Francese, Tedesco, Italiano, Giapponese, Spagnolo, Svedese, Turco \ No newline at end of file +- Nessuna raccolta di dati personali \ No newline at end of file diff --git a/fastlane/metadata/android/ja-JP/changelogs/146.txt b/fastlane/metadata/android/ja-JP/changelogs/146.txt new file mode 100644 index 0000000..b52487e --- /dev/null +++ b/fastlane/metadata/android/ja-JP/changelogs/146.txt @@ -0,0 +1,3 @@ +- ランダムパスワードジェネレータを追加しました。 +- 翻訳されていないクラックへの推定時間を修正しました。 +- スウェーデン語とトルコ語の翻訳を追加しました。 \ No newline at end of file diff --git a/fastlane/metadata/android/ja-JP/full_description.txt b/fastlane/metadata/android/ja-JP/full_description.txt index d0faff9..4e03be6 100755 --- a/fastlane/metadata/android/ja-JP/full_description.txt +++ b/fastlane/metadata/android/ja-JP/full_description.txt @@ -7,5 +7,4 @@ - 完全にオフライン - 光と暗いテーマの両方をサポートしています - 広告なし -- 個人データの収集はありません -- 対応言語 英語、オランダ語、フランス語、ドイツ語、イタリア語、日本語、スペイン語、スウェーデン語、トルコ語 +- 個人データの収集はありません \ No newline at end of file diff --git a/fastlane/metadata/android/nl-NL/changelogs/146.txt b/fastlane/metadata/android/nl-NL/changelogs/146.txt new file mode 100644 index 0000000..63ec4a1 --- /dev/null +++ b/fastlane/metadata/android/nl-NL/changelogs/146.txt @@ -0,0 +1,3 @@ +- Generator voor willekeurige wachtwoorden toegevoegd. +- Geschatte tijd om te kraken niet vertaald. +- Zweedse en Turkse vertalingen toegevoegd. \ No newline at end of file diff --git a/fastlane/metadata/android/nl-NL/full_description.txt b/fastlane/metadata/android/nl-NL/full_description.txt index 22c791f..406c87a 100755 --- a/fastlane/metadata/android/nl-NL/full_description.txt +++ b/fastlane/metadata/android/nl-NL/full_description.txt @@ -7,5 +7,4 @@ Kenmerken: - Volledig offline - Ondersteunt zowel licht als donker thema - Geen advertenties -- Geen verzameling persoonlijke gegevens -- Ondersteunde talen: Engels, Nederlands, Frans, Duits, Italiaans, Japans, Spaans, Zweeds, Turks +- Geen verzameling persoonlijke gegevens \ No newline at end of file diff --git a/fastlane/metadata/android/sv-SV/changelogs/146.txt b/fastlane/metadata/android/sv-SV/changelogs/146.txt new file mode 100644 index 0000000..1bdcf01 --- /dev/null +++ b/fastlane/metadata/android/sv-SV/changelogs/146.txt @@ -0,0 +1,3 @@ +- Lagt till slumpmässig lösenordsgenerator. +- Fast beräknad tid till crack översattes inte. +- Svenska och turkiska översättningar har lagts till. \ No newline at end of file diff --git a/fastlane/metadata/android/sv-SV/full_description.txt b/fastlane/metadata/android/sv-SV/full_description.txt index dc184d4..3184354 100755 --- a/fastlane/metadata/android/sv-SV/full_description.txt +++ b/fastlane/metadata/android/sv-SV/full_description.txt @@ -7,5 +7,4 @@ Funktioner: - Helt offline - Stödjer både ljust och mörkt tema - Inga annonser -- Ingen insamling av personuppgifter -- Språk som stöds: Engelska, Franska, Italienska, Japanska, Spanska, Svenska, Holländska, Tyska, Turkiska +- Ingen insamling av personuppgifter \ No newline at end of file diff --git a/fastlane/metadata/android/tr-TR/changelogs/146.txt b/fastlane/metadata/android/tr-TR/changelogs/146.txt new file mode 100644 index 0000000..10ecb57 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/146.txt @@ -0,0 +1,3 @@ +- Rastgele şifre üreticisi eklendi. +- Tahmini kırma süresinin çevrilmemesi düzeltildi. +- İsveççe ve Türkçe çeviriler eklendi. \ No newline at end of file diff --git a/fastlane/metadata/android/tr-TR/full_description.txt b/fastlane/metadata/android/tr-TR/full_description.txt index 4709bce..3811b3d 100755 --- a/fastlane/metadata/android/tr-TR/full_description.txt +++ b/fastlane/metadata/android/tr-TR/full_description.txt @@ -7,5 +7,4 @@ Gücü, tahmini kırılma süresini gösteren ve daha iyi şifreler oluşturmaya - Tamamen çevrimdışı - Hem açık hem de koyu temayı destekler - Reklam yok -- Kişisel veri toplama yok -- Desteklenen diller: İngilizce, Hollandaca, Fransızca, Almanca, İtalyanca, Japonca, İspanyolca, İsveççe, Türkçe \ No newline at end of file +- Kişisel veri toplama yok \ No newline at end of file