Compare commits
55 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9df12ca237 | ||
![]() |
bc62f7ec98 | ||
![]() |
f6551934c7 | ||
![]() |
fea7175bcc | ||
![]() |
45c99de9af | ||
![]() |
12cbb05f17 | ||
![]() |
32329da46d | ||
![]() |
bbaf17233f | ||
![]() |
05c8513249 | ||
![]() |
d1a3a4799a | ||
![]() |
ce2ce6ff74 | ||
![]() |
87104feb98 | ||
![]() |
4e509cbbfd | ||
![]() |
d7f410c66f | ||
![]() |
776faa2d62 | ||
![]() |
b6ba89065d | ||
![]() |
1b292c1c31 | ||
![]() |
879a7b68c5 | ||
![]() |
aacc153ec2 | ||
![]() |
5439dde324 | ||
![]() |
57ea6f1ec7 | ||
![]() |
fc60b81699 | ||
![]() |
11fe482992 | ||
![]() |
cc7c719ee9 | ||
![]() |
33293a4c28 | ||
![]() |
b53a0b1f92 | ||
![]() |
84ddb6b6fa | ||
![]() |
6a5efe92ba | ||
![]() |
5a9440dd17 | ||
![]() |
f313da7042 | ||
![]() |
84c76606ce | ||
![]() |
cbf3fa54f8 | ||
![]() |
a25e773f83 | ||
![]() |
1e2cc1ca2e | ||
![]() |
f92becc333 | ||
![]() |
a07aa51163 | ||
![]() |
ad107b0143 | ||
![]() |
ab4c8a8963 | ||
![]() |
a3da66a6f0 | ||
![]() |
855f620548 | ||
![]() |
305744f9d5 | ||
![]() |
5a694ea5c8 | ||
![]() |
2097ab593b | ||
![]() |
b343b78753 | ||
![]() |
38ba85abaa | ||
![]() |
00ca88b1e6 | ||
![]() |
0a021975fc | ||
![]() |
68c17d1d97 | ||
![]() |
6cf9c53541 | ||
![]() |
792dc9366b | ||
![]() |
1a2ae455c9 | ||
![]() |
084d66ac88 | ||
![]() |
7e9d057535 | ||
![]() |
12938e9122 | ||
![]() |
902aad9f55 |
3
.github/workflows/build-testing.yaml
vendored
@ -3,6 +3,9 @@ name: Build and push debug app
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
JAVA_OPTS: -Xmx12G
|
||||
|
||||
jobs:
|
||||
debug-builds:
|
||||
runs-on: ubuntu-latest
|
||||
|
3
.github/workflows/release-app-github.yaml
vendored
@ -4,6 +4,9 @@ on:
|
||||
release:
|
||||
types: [ published ]
|
||||
|
||||
env:
|
||||
JAVA_OPTS: -Xmx12G
|
||||
|
||||
jobs:
|
||||
release-app-github:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -4,6 +4,9 @@ on:
|
||||
release:
|
||||
types: [ published ]
|
||||
|
||||
env:
|
||||
JAVA_OPTS: -Xmx12G
|
||||
|
||||
jobs:
|
||||
release-app-google-play:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -16,6 +16,7 @@
|
||||
# Download NumberHub
|
||||
|
||||
[<img src="readme_content/google-play-badge.png" alt="Get it on Google Play" height="80">](https://play.google.com/store/apps/details?id=app.myzel394.numberhub)
|
||||
[<img src="readme_content/izzyondroid-badge.png" alt="Get it on IzzyOnDroid" height="80">](https://apt.izzysoft.de/fdroid/index/apk/app.myzel394.numberhub)
|
||||
[<img src="readme_content/github-badge.png" alt="Get it on GitHub" height="80">](https://github.com/Myzel394/NumberHub/releases)
|
||||
[<img src="readme_content/obtainium-badge.png" alt="Get it on Obtainium" height="80">](https://apps.obtainium.imranr.dev/redirect?r=obtainium://add/https://github.com/Myzel394/NumberHub//)
|
||||
|
||||
|
@ -56,6 +56,7 @@ android {
|
||||
"en-rGB",
|
||||
"de",
|
||||
"es",
|
||||
"fa",
|
||||
"fr",
|
||||
"hu",
|
||||
"in",
|
||||
|
1290
core/base/src/main/res/values-fa/strings.xml
Normal file
@ -18,15 +18,37 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Person's height -->
|
||||
<string name="body_mass_height">Taille</string>
|
||||
<string name="body_mass_imperial">Impérial</string>
|
||||
<string name="body_mass_metric">Métrique</string>
|
||||
<string name="body_mass_normal">Poids normal</string>
|
||||
|
||||
<!-- Will be a text followed by a number like so: "Normal weight for your height - 60" -->
|
||||
<!-- https://fr.wikipedia.org/wiki/Obésité for the terms used to qualify obese class-->
|
||||
<string name="body_mass_normal_weight">Poids normal pour votre taille</string>
|
||||
<string name="body_mass_obese_1">Obésité</string>
|
||||
<string name="body_mass_obese_2">Obésité sévère</string>
|
||||
<string name="body_mass_obese_3">Obésité morbide</string>
|
||||
<string name="body_mass_overweight">En surpoids</string>
|
||||
|
||||
<!-- Also known as Body mass index (BMI) -->
|
||||
<!-- Body Mass should be "Masse Corporelle" but is referred as "IMC" in France, which is commonly used and short for "Indice de Masse Corporelle"-->
|
||||
<string name="body_mass_title">IMC</string>
|
||||
<string name="body_mass_underweight">En sous-poids</string>
|
||||
|
||||
<!-- Person's weight -->
|
||||
<string name="body_mass_weight">Poids</string>
|
||||
<string name="calculator_clear_history_support">Toutes les expressions de l\'historique seront supprimées pour toujours. Cette action ne peux pas être annulée !</string>
|
||||
<string name="calculator_divide_by_zero_error">Impossible de diviser par 0</string>
|
||||
<string name="calculator_no_history">Pas d\'historique</string>
|
||||
<string name="calculator_no_history">Aucun historique</string>
|
||||
<string name="calculator_title">Calculatrice</string>
|
||||
<string name="cancel_label">Annuler</string>
|
||||
<string name="checked_filter_description">Filtre vérifié</string>
|
||||
<string name="clear_history_label">Vider l\'historique</string>
|
||||
<string name="clear_input_description">Effacer l\'entrée</string>
|
||||
<string name="clear_label">Clear</string>
|
||||
<string name="clear_label">Effacer</string>
|
||||
<string name="click_to_try_again_label">Cliquez pour réessayer</string>
|
||||
<string name="comma">Virgule</string>
|
||||
<string name="converter_favorite_button_description">Ajouter ou supprimer une unité des favoris</string>
|
||||
@ -65,9 +87,7 @@
|
||||
<string name="loading_label">Chargement…</string>
|
||||
<string name="navigate_up_description">Naviguer vers le haut</string>
|
||||
|
||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/9lSfdkfKShwyQFEF4nvbVaIb.jpg
|
||||
|
||||
Used in this dialog window. Should be short -->
|
||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/9lSfdkfKShwyQFEF4nvbVaIb.jpg Used in this dialog window. Should be short -->
|
||||
<string name="next_label">Suite</string>
|
||||
<string name="no_results_description">Résultat de recherche vide</string>
|
||||
<string name="no_results_label">Aucun résultat trouvé</string>
|
||||
@ -78,32 +98,34 @@ Used in this dialog window. Should be short -->
|
||||
|
||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
||||
<string name="select_time_label">Choisir le temps</string>
|
||||
<string name="settings_about_unitto">À propos d\'NumberHub</string>
|
||||
<string name="settings_about_unitto">À propos de NumberHub</string>
|
||||
<string name="settings_about_unitto_support">En savoir plus sur l\'application</string>
|
||||
<string name="settings_additional">Additional</string>
|
||||
<string name="settings_amoled_dark">AMOLED Noir</string>
|
||||
<string name="settings_additional">Paramètres supplémentaires</string>
|
||||
<string name="settings_amoled_dark">Interface AMOLED</string>
|
||||
<string name="settings_amoled_dark_support">Utiliser un fond noir pour les thèmes sombres</string>
|
||||
<string name="settings_auto">Auto</string>
|
||||
<string name="settings_back_up">Sauvegarde</string>
|
||||
<string name="settings_calculator_support">Vue historique</string>
|
||||
<string name="settings_clear_cache">Effacer le cache</string>
|
||||
<string name="settings_color_scheme">Palette de couleurs</string>
|
||||
<string name="settings_color_theme">Thème couleur</string>
|
||||
<string name="settings_color_theme">Thème de couleurs</string>
|
||||
<string name="settings_color_theme_support">Choisir un mode de thème</string>
|
||||
<string name="settings_converter_support">Groupes d\'unités, tri, formatage</string>
|
||||
<string name="settings_currency_rates_note_text">Les taux de change sont mis à jour quotidiennement. L\'application ne permet pas de suivre le marché en temps réel.</string>
|
||||
<string name="settings_currency_rates_note_title">Taux de conversion faux ?</string>
|
||||
<string name="settings_dark_mode">Sombre</string>
|
||||
<string name="settings_decimal_separator">Séparateur de décimales</string>
|
||||
<string name="settings_disable_unit_group_description">Désactiver le groupe d\'unités</string>
|
||||
<string name="settings_display">Affichage</string>
|
||||
<string name="settings_display_support">Apparence de l\'Application</string>
|
||||
<string name="settings_display_support">Apparence de l\'application</string>
|
||||
<string name="settings_dynamic_colors">Couleurs dynamiques</string>
|
||||
<string name="settings_dynamic_colors_support">Utilisez les couleurs de votre fond d\'écran</string>
|
||||
<string name="settings_enable_unit_group_description">Activer le groupe d\'unités</string>
|
||||
<string name="settings_exponential_notation">Notation exponentielle</string>
|
||||
<string name="settings_exponential_notation">Notation scientifique</string>
|
||||
<string name="settings_exponential_notation_support">Remplacer une partie du nombre par E</string>
|
||||
<string name="settings_format_time">Formatter l\'heure</string>
|
||||
<string name="settings_format_time">Formater l\'heure</string>
|
||||
<string name="settings_format_time_support">Exemple : Afficher 130 minutes comme 2h 10m</string>
|
||||
<string name="settings_formatting">Formattage</string>
|
||||
<string name="settings_formatting">Formatage</string>
|
||||
<string name="settings_formatting_preview">Aperçu (cliquez pour changer)</string>
|
||||
|
||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/Gj9ZCNPXIfKddDQgccvboVFz.jpg
|
||||
@ -112,8 +134,9 @@ https://s3.eu-west-1.amazonaws.com/po-pub/i/prtM85P6x1fMuLg1I0zbkceo.png
|
||||
Maybe this can be labeled better? Let me know. It should be something that can describe content of the Formatting screen. -->
|
||||
<string name="settings_formatting_support">Précision et format des nombres</string>
|
||||
<string name="settings_language">Langue</string>
|
||||
<string name="settings_language_support">Changer la langue de l\'app</string>
|
||||
<string name="settings_light_mode">Clair</string>
|
||||
<string name="settings_middle_zero">Zéro au milieu</string>
|
||||
<string name="settings_middle_zero">Zéro central</string>
|
||||
<string name="settings_middle_zero_support">Intervertir les boutons zéro et décimal</string>
|
||||
<string name="settings_note">Note</string>
|
||||
<string name="settings_partial_history_view">Vue partielle de l\'historique</string>
|
||||
@ -124,8 +147,9 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="settings_precision_max">%1$s (Max)</string>
|
||||
<string name="settings_precision_support">Nombre de décimales</string>
|
||||
<string name="settings_privacy_policy">Politique de confidentialité</string>
|
||||
<string name="settings_rate_this_app">Évaluer l\'application</string>
|
||||
<string name="settings_rate_this_app">Noter l\'application</string>
|
||||
<string name="settings_reorder_unit_group_description">Réorganiser le groupe d\'unités</string>
|
||||
<string name="settings_restore">Restaurer</string>
|
||||
<string name="settings_selected_color">Couleur sélectionnée</string>
|
||||
<string name="settings_selected_style">Style sélectionné</string>
|
||||
<string name="settings_separator">Séparateur</string>
|
||||
@ -141,8 +165,13 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/r1VikAn70eXQP4da2hrntTGQ.jpg -->
|
||||
<!-- Option name to use system default setting -->
|
||||
<string name="settings_system">Système</string>
|
||||
<string name="settings_system_font">Police</string>
|
||||
<string name="settings_system_font_support">Afficher avec la police système</string>
|
||||
<string name="settings_ac_button">bouton AC</string>
|
||||
<string name="settings_ac_button_support">Afficher le bouton de suppression</string>
|
||||
<string name="settings_terms_and_conditions">Termes et conditions</string>
|
||||
<string name="settings_third_party_licenses">Licences tierces</string>
|
||||
<string name="settings_thousands_separator">Séparateur de milliers</string>
|
||||
<string name="settings_title">Paramètres</string>
|
||||
<string name="settings_translate_app">Traduire cette app</string>
|
||||
<string name="settings_translate_app_support">Rejoignez le projet POEditor pour aider</string>
|
||||
@ -152,9 +181,17 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="settings_units_sorting_support">Changer l\'ordre des unités</string>
|
||||
<string name="settings_version_name">Nom de la version</string>
|
||||
<string name="settings_vibrations">Vibrations</string>
|
||||
<string name="settings_vibrations_support">Retour haptique lors du click sur les boutons du clavier</string>
|
||||
<string name="settings_vibrations_support">Retour haptique lors du clic sur les boutons du clavier</string>
|
||||
<string name="settings_view_source_code">Voir le code source</string>
|
||||
<string name="time_zone_add_title">Ajouter un fuseau horaire</string>
|
||||
|
||||
<string name="time_zone_no_results_button">Lire l\'article</string>
|
||||
|
||||
<!-- NumberHub beta text-->
|
||||
<string name="settings_numberhub_newApp">Unitto est maintenant NumberHub !</string>
|
||||
<string name="settings_numberhub_newApp_message">Unitto n\'est plus maintenu. Vous êtes l\'un des premiers utilisateurs à essayer NumberHub ! Veuillez faire passer le mot et partager l\'application avec vos amis. Merci pour votre soutien !</string>
|
||||
<string name="settings_numberhub_newApp_announcement">NumberHub sert de remplacement direct pour Unitto. Il a les mêmes fonctionnalités et plus encore. NumberHub est encore en version bêta et des changements peuvent survenir. Veuillez signaler tout problème que vous rencontrez. Merci d\'être l\'un des premiers à l\'essayer !</string>
|
||||
|
||||
<string name="time_zone_title">Fuseaux horaires</string>
|
||||
<string name="tomorrow">Demain</string>
|
||||
<string name="unit_acre">Acre</string>
|
||||
@ -258,175 +295,175 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="unit_cubic_millimeter_short">mm³</string>
|
||||
<string name="unit_currency_ada">Cardano</string>
|
||||
<string name="unit_currency_aed">Dirham des Émirats arabes unis</string>
|
||||
<string name="unit_currency_afn">Afghan afghani</string>
|
||||
<string name="unit_currency_all">Albanian lek</string>
|
||||
<string name="unit_currency_amd">Armenian dram</string>
|
||||
<string name="unit_currency_ang">Netherlands Antillean Guilder</string>
|
||||
<string name="unit_currency_aoa">Angolan kwanza</string>
|
||||
<string name="unit_currency_ars">Argentine peso</string>
|
||||
<string name="unit_currency_aud">Australian dollar</string>
|
||||
<string name="unit_currency_awg">Aruban florin</string>
|
||||
<string name="unit_currency_azn">Azerbaijani manat</string>
|
||||
<string name="unit_currency_bam">Bosnia-Herzegovina Convertible Mark</string>
|
||||
<string name="unit_currency_bbd">Bajan dollar</string>
|
||||
<string name="unit_currency_bdt">Bangladeshi taka</string>
|
||||
<string name="unit_currency_bgn">Bulgarian lev</string>
|
||||
<string name="unit_currency_bhd">Bahraini dinar</string>
|
||||
<string name="unit_currency_bif">Burundian Franc</string>
|
||||
<string name="unit_currency_bmd">Bermudan dollar</string>
|
||||
<string name="unit_currency_bnd">Brunei dollar</string>
|
||||
<string name="unit_currency_bob">Bolivian boliviano</string>
|
||||
<string name="unit_currency_brl">Brazilian real</string>
|
||||
<string name="unit_currency_bsd">Bahamian dollar</string>
|
||||
<string name="unit_currency_btn">Bhutan currency</string>
|
||||
<string name="unit_currency_bwp">Botswanan Pula</string>
|
||||
<string name="unit_currency_byn">New Belarusian Ruble</string>
|
||||
<string name="unit_currency_byr">Belarusian Ruble</string>
|
||||
<string name="unit_currency_bzd">Belize dollar</string>
|
||||
<string name="unit_currency_cad">Canadian dollar</string>
|
||||
<string name="unit_currency_cdf">Congolese franc</string>
|
||||
<string name="unit_currency_chf">Swiss franc</string>
|
||||
<string name="unit_currency_afn">Afghani</string>
|
||||
<string name="unit_currency_all">Lek</string>
|
||||
<string name="unit_currency_amd">Dram</string>
|
||||
<string name="unit_currency_ang">Florin des Antilles néerlandaises</string>
|
||||
<string name="unit_currency_aoa">Kwanza</string>
|
||||
<string name="unit_currency_ars">Peso argentin</string>
|
||||
<string name="unit_currency_aud">Dollar australien</string>
|
||||
<string name="unit_currency_awg">Florin arubais</string>
|
||||
<string name="unit_currency_azn">Manat azerbaïdjanais</string>
|
||||
<string name="unit_currency_bam">Mark convertible de Bosnie-Herzégovine</string>
|
||||
<string name="unit_currency_bbd">Dollar barbadien</string>
|
||||
<string name="unit_currency_bdt">Taka</string>
|
||||
<string name="unit_currency_bgn">Lev bulgare</string>
|
||||
<string name="unit_currency_bhd">Dinar bahreïni</string>
|
||||
<string name="unit_currency_bif">Franc burundais</string>
|
||||
<string name="unit_currency_bmd">Dollar bermudien</string>
|
||||
<string name="unit_currency_bnd">Dollar de Brunei</string>
|
||||
<string name="unit_currency_bob">Boliviano</string>
|
||||
<string name="unit_currency_brl">Réal brésilien</string>
|
||||
<string name="unit_currency_bsd">Dollar bahaméen</string>
|
||||
<string name="unit_currency_btn">Ngultrum</string>
|
||||
<string name="unit_currency_bwp">Pula</string>
|
||||
<string name="unit_currency_byn">Nouveau rouble biélorusse</string>
|
||||
<string name="unit_currency_byr">Rouble biélorusse</string>
|
||||
<string name="unit_currency_bzd">Dollar bélizien</string>
|
||||
<string name="unit_currency_cad">Dollar canadien</string>
|
||||
<string name="unit_currency_cdf">Franc congolais</string>
|
||||
<string name="unit_currency_chf">Franc suisse</string>
|
||||
<string name="unit_currency_clf">Chilean Unit of Account (UF)</string>
|
||||
<string name="unit_currency_clp">Chilean peso</string>
|
||||
<string name="unit_currency_cny">Chinese Yuan</string>
|
||||
<string name="unit_currency_cop">Colombian peso</string>
|
||||
<string name="unit_currency_crc">Costa Rican Colón</string>
|
||||
<string name="unit_currency_cuc">Cuban convertible peso</string>
|
||||
<string name="unit_currency_cup">Cuban Peso</string>
|
||||
<string name="unit_currency_cve">Cape Verdean escudo</string>
|
||||
<string name="unit_currency_czk">Czech koruna</string>
|
||||
<string name="unit_currency_clp">Peso chilien</string>
|
||||
<string name="unit_currency_cny">Yuan</string>
|
||||
<string name="unit_currency_cop">Peso colombien</string>
|
||||
<string name="unit_currency_crc">Colón costaricien</string>
|
||||
<string name="unit_currency_cuc">Peso cubain convertible</string>
|
||||
<string name="unit_currency_cup">Peso cubain</string>
|
||||
<string name="unit_currency_cve">Escudo cap-verdien</string>
|
||||
<string name="unit_currency_czk">Couronne tchèque</string>
|
||||
<string name="unit_currency_dai">Dai</string>
|
||||
<string name="unit_currency_djf">Djiboutian franc</string>
|
||||
<string name="unit_currency_dkk">Danish krone</string>
|
||||
<string name="unit_currency_dop">Dominican peso</string>
|
||||
<string name="unit_currency_dzd">Algerian dinar</string>
|
||||
<string name="unit_currency_egp">Egyptian pound</string>
|
||||
<string name="unit_currency_ern">Eritrean nakfa</string>
|
||||
<string name="unit_currency_etb">Ethiopian birr</string>
|
||||
<string name="unit_currency_djf">Franc Djibouti</string>
|
||||
<string name="unit_currency_dkk">Couronne danoise</string>
|
||||
<string name="unit_currency_dop">Peso dominicain</string>
|
||||
<string name="unit_currency_dzd">Dinar algérien</string>
|
||||
<string name="unit_currency_egp">Livre égyptienne</string>
|
||||
<string name="unit_currency_ern">Nakfa érythréen</string>
|
||||
<string name="unit_currency_etb">Birr éthiopien</string>
|
||||
<string name="unit_currency_eur">Euro</string>
|
||||
<string name="unit_currency_fjd">Fijian dollar</string>
|
||||
<string name="unit_currency_fkp">Falkland Islands pound</string>
|
||||
<string name="unit_currency_gbp">Pound sterling</string>
|
||||
<string name="unit_currency_gel">Georgian lari</string>
|
||||
<string name="unit_currency_ghs">Ghanaian cedi</string>
|
||||
<string name="unit_currency_gip">Gibraltar pound</string>
|
||||
<string name="unit_currency_gmd">Gambian dalasi</string>
|
||||
<string name="unit_currency_gnf">Guinean franc</string>
|
||||
<string name="unit_currency_gtq">Guatemalan quetzal</string>
|
||||
<string name="unit_currency_gyd">Guyanaese Dollar</string>
|
||||
<string name="unit_currency_hkd">Hong Kong dollar</string>
|
||||
<string name="unit_currency_hnl">Honduran lempira</string>
|
||||
<string name="unit_currency_hrk">Croatian kuna</string>
|
||||
<string name="unit_currency_htg">Haitian gourde</string>
|
||||
<string name="unit_currency_huf">Hungarian forint</string>
|
||||
<string name="unit_currency_idr">Indonesian rupiah</string>
|
||||
<string name="unit_currency_ils">Israeli New Shekel</string>
|
||||
<string name="unit_currency_inr">Indian rupee</string>
|
||||
<string name="unit_currency_iqd">Iraqi dinar</string>
|
||||
<string name="unit_currency_irr">Iranian rial</string>
|
||||
<string name="unit_currency_isk">Icelandic króna</string>
|
||||
<string name="unit_currency_jep">Jersey Pound</string>
|
||||
<string name="unit_currency_jmd">Jamaican dollar</string>
|
||||
<string name="unit_currency_jod">Jordanian dinar</string>
|
||||
<string name="unit_currency_jpy">Japanese yen</string>
|
||||
<string name="unit_currency_kes">Kenyan shilling</string>
|
||||
<string name="unit_currency_kgs">Kyrgystani Som</string>
|
||||
<string name="unit_currency_khr">Cambodian riel</string>
|
||||
<string name="unit_currency_kmf">Comorian franc</string>
|
||||
<string name="unit_currency_kpw">North Korean won</string>
|
||||
<string name="unit_currency_krw">South Korean won</string>
|
||||
<string name="unit_currency_kwd">Kuwaiti dinar</string>
|
||||
<string name="unit_currency_kyd">Cayman Islands dollar</string>
|
||||
<string name="unit_currency_kzt">Kazakhstani tenge</string>
|
||||
<string name="unit_currency_lak">Laotian Kip</string>
|
||||
<string name="unit_currency_lbp">Lebanese pound</string>
|
||||
<string name="unit_currency_lkr">Sri Lankan rupee</string>
|
||||
<string name="unit_currency_lrd">Liberian dollar</string>
|
||||
<string name="unit_currency_lsl">Lesotho loti</string>
|
||||
<string name="unit_currency_ltl">Lithuanian litas</string>
|
||||
<string name="unit_currency_lvl">Latvian lats</string>
|
||||
<string name="unit_currency_lyd">Libyan dinar</string>
|
||||
<string name="unit_currency_mad">Moroccan dirham</string>
|
||||
<string name="unit_currency_mdl">Moldovan leu</string>
|
||||
<string name="unit_currency_mga">Malagasy ariary</string>
|
||||
<string name="unit_currency_mkd">Macedonian denar</string>
|
||||
<string name="unit_currency_mmk">Myanmar Kyat</string>
|
||||
<string name="unit_currency_mnt">Mongolian tugrik</string>
|
||||
<string name="unit_currency_mop">Macanese pataca</string>
|
||||
<string name="unit_currency_mro">Mauritanian ouguiya</string>
|
||||
<string name="unit_currency_mur">Mauritian rupee</string>
|
||||
<string name="unit_currency_mvr">Maldivian rufiyaa</string>
|
||||
<string name="unit_currency_mwk">Malawian kwacha</string>
|
||||
<string name="unit_currency_mxn">Mexican peso</string>
|
||||
<string name="unit_currency_myr">Malaysian ringgit</string>
|
||||
<string name="unit_currency_mzn">Mozambican Metical</string>
|
||||
<string name="unit_currency_nad">Namibian dollar</string>
|
||||
<string name="unit_currency_ngn">Nigerian naira</string>
|
||||
<string name="unit_currency_nio">Nicaraguan córdoba</string>
|
||||
<string name="unit_currency_nok">Norwegian krone</string>
|
||||
<string name="unit_currency_npr">Nepalese rupee</string>
|
||||
<string name="unit_currency_nzd">New Zealand dollar</string>
|
||||
<string name="unit_currency_omr">Omani rial</string>
|
||||
<string name="unit_currency_pab">Panamanian balboa</string>
|
||||
<string name="unit_currency_pen">Sol</string>
|
||||
<string name="unit_currency_pgk">Papua New Guinean kina</string>
|
||||
<string name="unit_currency_php">Philippine peso</string>
|
||||
<string name="unit_currency_pkr">Pakistani rupee</string>
|
||||
<string name="unit_currency_pln">Poland złoty</string>
|
||||
<string name="unit_currency_pyg">Paraguayan guarani</string>
|
||||
<string name="unit_currency_qar">Qatari Rial</string>
|
||||
<string name="unit_currency_ron">Romanian leu</string>
|
||||
<string name="unit_currency_rsd">Serbian dinar</string>
|
||||
<string name="unit_currency_rub">Russian ruble</string>
|
||||
<string name="unit_currency_rwf">Rwandan Franc</string>
|
||||
<string name="unit_currency_sar">Saudi riyal</string>
|
||||
<string name="unit_currency_sbd">Solomon Islands dollar</string>
|
||||
<string name="unit_currency_scr">Seychellois rupee</string>
|
||||
<string name="unit_currency_sdg">Sudanese pound</string>
|
||||
<string name="unit_currency_sek">Swedish krona</string>
|
||||
<string name="unit_currency_sgd">Singapore dollar</string>
|
||||
<string name="unit_currency_fjd">Dollar fidjien</string>
|
||||
<string name="unit_currency_fkp">Livre des îles Malouines</string>
|
||||
<string name="unit_currency_gbp">Livre sterling</string>
|
||||
<string name="unit_currency_gel">Lari géorgien</string>
|
||||
<string name="unit_currency_ghs">Cedi ghanéen</string>
|
||||
<string name="unit_currency_gip">Livre de Gibraltar</string>
|
||||
<string name="unit_currency_gmd">Dalasi gambien</string>
|
||||
<string name="unit_currency_gnf">Franc guinéen</string>
|
||||
<string name="unit_currency_gtq">Quetzal guatémaltèque</string>
|
||||
<string name="unit_currency_gyd">Dollar guyanien</string>
|
||||
<string name="unit_currency_hkd">Dollar de Hong Kong</string>
|
||||
<string name="unit_currency_hnl">Lempira hondurien</string>
|
||||
<string name="unit_currency_hrk">Kuna croate</string>
|
||||
<string name="unit_currency_htg">Gourde haïtienne</string>
|
||||
<string name="unit_currency_huf">Forint hongrois</string>
|
||||
<string name="unit_currency_idr">Roupie indonésienne</string>
|
||||
<string name="unit_currency_ils">Shekel israélien</string>
|
||||
<string name="unit_currency_inr">Roupie indienne</string>
|
||||
<string name="unit_currency_iqd">Dinar irakien</string>
|
||||
<string name="unit_currency_irr">Rial iranien</string>
|
||||
<string name="unit_currency_isk">Couronne islandaise</string>
|
||||
<string name="unit_currency_jep">Livre de Jersey</string>
|
||||
<string name="unit_currency_jmd">Dollar jamaïcain</string>
|
||||
<string name="unit_currency_jod">Dinar jordanien</string>
|
||||
<string name="unit_currency_jpy">Yen japonais</string>
|
||||
<string name="unit_currency_kes">Shilling kényan</string>
|
||||
<string name="unit_currency_kgs">Som kirghize</string>
|
||||
<string name="unit_currency_khr">Riel cambodgien</string>
|
||||
<string name="unit_currency_kmf">Franc comorien</string>
|
||||
<string name="unit_currency_kpw">Won nord-coréen</string>
|
||||
<string name="unit_currency_krw">Won sud-coréen</string>
|
||||
<string name="unit_currency_kwd">Dinar koweïtien</string>
|
||||
<string name="unit_currency_kyd">Dollar des îles Caïmans</string>
|
||||
<string name="unit_currency_kzt">Tenge kazakh</string>
|
||||
<string name="unit_currency_lak">Kip laotien</string>
|
||||
<string name="unit_currency_lbp">Livre libanaise</string>
|
||||
<string name="unit_currency_lkr">Roupie srilankaise</string>
|
||||
<string name="unit_currency_lrd">Dollar libérien</string>
|
||||
<string name="unit_currency_lsl">Loti lesothan</string>
|
||||
<string name="unit_currency_ltl">Litas lituanien</string>
|
||||
<string name="unit_currency_lvl">Lats letton</string>
|
||||
<string name="unit_currency_lyd">Dinar libyen</string>
|
||||
<string name="unit_currency_mad">Dirham marocain</string>
|
||||
<string name="unit_currency_mdl">Leu moldave</string>
|
||||
<string name="unit_currency_mga">Ariary malgache</string>
|
||||
<string name="unit_currency_mkd">Denar macédonien</string>
|
||||
<string name="unit_currency_mmk">Kyat birman</string>
|
||||
<string name="unit_currency_mnt">Tugrik mongol</string>
|
||||
<string name="unit_currency_mop">Pataca macanaise</string>
|
||||
<string name="unit_currency_mro">Ouguiya mauritanien</string>
|
||||
<string name="unit_currency_mur">Roupie mauricienne</string>
|
||||
<string name="unit_currency_mvr">Rufiyaa maldivienne</string>
|
||||
<string name="unit_currency_mwk">Kwacha malawien</string>
|
||||
<string name="unit_currency_mxn">Peso mexicain</string>
|
||||
<string name="unit_currency_myr">Ringgit malaisien</string>
|
||||
<string name="unit_currency_mzn">Metical mozambicain</string>
|
||||
<string name="unit_currency_nad">Dollar namibien</string>
|
||||
<string name="unit_currency_ngn">Naira nigérian</string>
|
||||
<string name="unit_currency_nio">Córdoba nicaraguayen</string>
|
||||
<string name="unit_currency_nok">Couronne norvégienne</string>
|
||||
<string name="unit_currency_npr">Roupie népalaise</string>
|
||||
<string name="unit_currency_nzd">Dollar néo-zélandais</string>
|
||||
<string name="unit_currency_omr">Rial omanais</string>
|
||||
<string name="unit_currency_pab">Balboa panaméen</string>
|
||||
<string name="unit_currency_pen">Sol péruvien</string>
|
||||
<string name="unit_currency_pgk">Kina papouasien</string>
|
||||
<string name="unit_currency_php">Peso philippin</string>
|
||||
<string name="unit_currency_pkr">Roupie pakistanaise</string>
|
||||
<string name="unit_currency_pln">Złoty polonais</string>
|
||||
<string name="unit_currency_pyg">Guaraní paraguayen</string>
|
||||
<string name="unit_currency_qar">Riyal qatari</string>
|
||||
<string name="unit_currency_ron">Leu roumain</string>
|
||||
<string name="unit_currency_rsd">Dinar serbe</string>
|
||||
<string name="unit_currency_rub">Rouble russe</string>
|
||||
<string name="unit_currency_rwf">Franc rwandais</string>
|
||||
<string name="unit_currency_sar">Riyal saoudien</string>
|
||||
<string name="unit_currency_sbd">Dollar des îles Salomon</string>
|
||||
<string name="unit_currency_scr">Roupie seychelloise</string>
|
||||
<string name="unit_currency_sdg">Livre soudanaise</string>
|
||||
<string name="unit_currency_sek">Couronne suédoise</string>
|
||||
<string name="unit_currency_sgd">Dollar de Singapour</string>
|
||||
<string name="unit_currency_shib">Shiba Inu</string>
|
||||
<string name="unit_currency_shp">Saint Helena pound</string>
|
||||
<string name="unit_currency_sll">Sierra Leonean leone</string>
|
||||
<string name="unit_currency_sos">Somali shilling</string>
|
||||
<string name="unit_currency_srd">Surinamese dollar</string>
|
||||
<string name="unit_currency_std">São Tomé and Príncipe Dobra (pre-2018)</string>
|
||||
<string name="unit_currency_svc">Salvadoran Colón</string>
|
||||
<string name="unit_currency_syp">Syrian pound</string>
|
||||
<string name="unit_currency_szl">Swazi lilangeni</string>
|
||||
<string name="unit_currency_thb">Thai baht</string>
|
||||
<string name="unit_currency_shp">Livre de Sainte-Hélène</string>
|
||||
<string name="unit_currency_sll">Leone sierra-léonais</string>
|
||||
<string name="unit_currency_sos">Shilling somalien</string>
|
||||
<string name="unit_currency_srd">Dollar surinamais</string>
|
||||
<string name="unit_currency_std">Dobra santoméen (avant 2018)</string>
|
||||
<string name="unit_currency_svc">Colón salvadorien</string>
|
||||
<string name="unit_currency_syp">Livre syrienne</string>
|
||||
<string name="unit_currency_szl">Lilangeni swazi</string>
|
||||
<string name="unit_currency_thb">Baht thaïlandais</string>
|
||||
<string name="unit_currency_theta">Theta</string>
|
||||
<string name="unit_currency_tjs">Tajikistani somoni</string>
|
||||
<string name="unit_currency_tmt">Turkmenistani manat</string>
|
||||
<string name="unit_currency_tnd">Tunisian dinar</string>
|
||||
<string name="unit_currency_top">Tongan Paʻanga</string>
|
||||
<string name="unit_currency_try">Turkish lira</string>
|
||||
<string name="unit_currency_ttd">Trinidad & Tobago Dollar</string>
|
||||
<string name="unit_currency_twd">New Taiwan dollar</string>
|
||||
<string name="unit_currency_tzs">Tanzanian shilling</string>
|
||||
<string name="unit_currency_uah">Ukrainian hryvnia</string>
|
||||
<string name="unit_currency_ugx">Ugandan shilling</string>
|
||||
<string name="unit_currency_tjs">Somoni tadjik</string>
|
||||
<string name="unit_currency_tmt">Manat turkmène</string>
|
||||
<string name="unit_currency_tnd">Dinar tunisien</string>
|
||||
<string name="unit_currency_top">Paʻanga tongan</string>
|
||||
<string name="unit_currency_try">Livre turque</string>
|
||||
<string name="unit_currency_ttd">Dollar de Trinité-et-Tobago</string>
|
||||
<string name="unit_currency_twd">Nouveau dollar taïwanais</string>
|
||||
<string name="unit_currency_tzs">Shilling tanzanien</string>
|
||||
<string name="unit_currency_uah">Hryvnia ukrainienne</string>
|
||||
<string name="unit_currency_ugx">Shilling ougandais</string>
|
||||
<string name="unit_currency_uni">Universe</string>
|
||||
<string name="unit_currency_usd">United States dollar</string>
|
||||
<string name="unit_currency_usd">Dollar américain</string>
|
||||
<string name="unit_currency_usdc">USD Coin</string>
|
||||
<string name="unit_currency_uyu">Uruguayan peso</string>
|
||||
<string name="unit_currency_uzs">Uzbekistani som</string>
|
||||
<string name="unit_currency_vef">Sovereign Bolivar</string>
|
||||
<string name="unit_currency_vnd">Vietnamese dong</string>
|
||||
<string name="unit_currency_vuv">Vanuatu vatu</string>
|
||||
<string name="unit_currency_uyu">Peso uruguayen</string>
|
||||
<string name="unit_currency_uzs">Som ouzbek</string>
|
||||
<string name="unit_currency_vef">Bolivar souverain</string>
|
||||
<string name="unit_currency_vnd">Dong vietnamien</string>
|
||||
<string name="unit_currency_vuv">Vatu vanuatu</string>
|
||||
<string name="unit_currency_wbtc">Wrapped Bitcoin</string>
|
||||
<string name="unit_currency_wst">Samoan tala</string>
|
||||
<string name="unit_currency_xaf">Central African CFA franc</string>
|
||||
<string name="unit_currency_xag">Silver Ounce</string>
|
||||
<string name="unit_currency_xcd">East Caribbean dollar</string>
|
||||
<string name="unit_currency_xdr">Special Drawing Rights</string>
|
||||
<string name="unit_currency_xof">West African CFA franc</string>
|
||||
<string name="unit_currency_xpf">CFP franc</string>
|
||||
<string name="unit_currency_yer">Yemeni rial</string>
|
||||
<string name="unit_currency_zar">South African rand</string>
|
||||
<string name="unit_currency_zmk">Zambian kwacha</string>
|
||||
<string name="unit_currency_zmw">Zambian Kwacha</string>
|
||||
<string name="unit_currency_zwl">Zimbabwean Dollar</string>
|
||||
<string name="unit_currency_wst">Tālā</string>
|
||||
<string name="unit_currency_xaf">Franc CFA d\'Afrique centrale</string>
|
||||
<string name="unit_currency_xag">Once d\'argent</string>
|
||||
<string name="unit_currency_xcd">Dollar des Caraïbes orientales</string>
|
||||
<string name="unit_currency_xdr">Droits de tirage spéciaux</string>
|
||||
<string name="unit_currency_xof">Franc CFA d\'Afrique de l\'Ouest</string>
|
||||
<string name="unit_currency_xpf">Franc CFP</string>
|
||||
<string name="unit_currency_yer">Rial yéménite</string>
|
||||
<string name="unit_currency_zar">Rand sud-africain</string>
|
||||
<string name="unit_currency_zmk">Kwacha zambien</string>
|
||||
<string name="unit_currency_zmw">Kwacha zambien</string>
|
||||
<string name="unit_currency_zwl">Dollar zimbabwéen</string>
|
||||
<string name="unit_day">Jour</string>
|
||||
<string name="unit_day_short">j</string>
|
||||
<string name="unit_decimal">Décimal</string>
|
||||
@ -459,7 +496,7 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="unit_earth_surface_gravity">Gravité de surface de la Terre</string>
|
||||
<string name="unit_earth_surface_gravity_short">G Terre</string>
|
||||
<string name="unit_earths_orbital_speed">Vitesse orbitale de la Terre</string>
|
||||
<string name="unit_electron_cross_section">Electron cross section</string>
|
||||
<string name="unit_electron_cross_section">Section efficace de l\'électron</string>
|
||||
<string name="unit_electron_cross_section_short">ecs</string>
|
||||
<string name="unit_electron_mass_rest">Masse électronique</string>
|
||||
<string name="unit_electron_mass_rest_short">me</string>
|
||||
@ -548,7 +585,7 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="unit_group_data_transfer">Transfert de données</string>
|
||||
<string name="unit_group_electrostatic_capacitance">Capacité</string>
|
||||
<string name="unit_group_energy">Énergie</string>
|
||||
<string name="unit_group_flow_rate">Flux</string>
|
||||
<string name="unit_group_flow_rate">Mesure de débit</string>
|
||||
<string name="unit_group_flux">Flux</string>
|
||||
<string name="unit_group_force">Force</string>
|
||||
<string name="unit_group_length">Longueur</string>
|
||||
@ -560,7 +597,7 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="unit_group_pressure">Pression</string>
|
||||
<string name="unit_group_speed">Vélocité</string>
|
||||
<string name="unit_group_temperature">Température</string>
|
||||
<string name="unit_group_time">Time</string>
|
||||
<string name="unit_group_time">Temps</string>
|
||||
<string name="unit_group_torque">Couple</string>
|
||||
<string name="unit_group_volume">Volume</string>
|
||||
<string name="unit_hectare">Hectare</string>
|
||||
@ -577,18 +614,18 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="unit_hour_short">h</string>
|
||||
<string name="unit_imperial_cup">Tasse impériale</string>
|
||||
<string name="unit_imperial_cup_short">cup</string>
|
||||
<string name="unit_imperial_fluid_ounce">Imperial fluid ounce</string>
|
||||
<string name="unit_imperial_fluid_ounce">Once liquide impériale</string>
|
||||
<string name="unit_imperial_fluid_ounce_short">fl oz</string>
|
||||
<string name="unit_imperial_gallon">Gallon imperial</string>
|
||||
<string name="unit_imperial_gallon">Gallon impérial</string>
|
||||
<string name="unit_imperial_gallon_short">gal</string>
|
||||
<string name="unit_imperial_pint">Pinte impériale</string>
|
||||
<string name="unit_imperial_pint_short">pt</string>
|
||||
<string name="unit_imperial_quart">Quart impérial</string>
|
||||
<string name="unit_imperial_quart_short">qt</string>
|
||||
<string name="unit_imperial_tablespoon">Imperial tablespoon</string>
|
||||
<string name="unit_imperial_tablespoon_short">tablespoon</string>
|
||||
<string name="unit_imperial_teaspoon">Imperial teaspoon</string>
|
||||
<string name="unit_imperial_teaspoon_short">teaspoon</string>
|
||||
<string name="unit_imperial_tablespoon">Cuillère à soupe impériale</string>
|
||||
<string name="unit_imperial_tablespoon_short">cuillère à soupe</string>
|
||||
<string name="unit_imperial_teaspoon">Cuillère à café impériale</string>
|
||||
<string name="unit_imperial_teaspoon_short">cuillère à café</string>
|
||||
<string name="unit_imperial_ton">Tonne impériale</string>
|
||||
<string name="unit_imperial_ton_short">t</string>
|
||||
<string name="unit_inch">Pouce</string>
|
||||
@ -790,7 +827,7 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="unit_milliliter_per_second_short">mL/s</string>
|
||||
<string name="unit_milliliter_short">mL</string>
|
||||
<string name="unit_millimeter">Millimètre</string>
|
||||
<string name="unit_millimeter_of_mercury">Millimeter of mercury</string>
|
||||
<string name="unit_millimeter_of_mercury">Millimètre de mercure</string>
|
||||
<string name="unit_millimeter_of_mercury_short">mm Hg</string>
|
||||
<string name="unit_millimeter_per_hour">Millimètre/heure</string>
|
||||
<string name="unit_millimeter_per_hour_short">mm/h</string>
|
||||
@ -1023,7 +1060,7 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="unit_uranus_mass_short">M Uranus</string>
|
||||
<string name="unit_uranus_surface_gravity">Gravité de surface d\'Uranus</string>
|
||||
<string name="unit_uranus_surface_gravity_short">G Uranus</string>
|
||||
<string name="unit_us_fluid_ounce">US fluid ounce</string>
|
||||
<string name="unit_us_fluid_ounce">Once liquide américaine</string>
|
||||
<string name="unit_us_fluid_ounce_short">fl oz</string>
|
||||
<string name="unit_us_legal_cup">Tasse américaine</string>
|
||||
<string name="unit_us_legal_cup_short">cup</string>
|
||||
@ -1034,9 +1071,9 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="unit_us_liquid_quart">Quarts américain</string>
|
||||
<string name="unit_us_liquid_quart_short">qt</string>
|
||||
<string name="unit_us_tablespoon">Cuillère à soupe américaine</string>
|
||||
<string name="unit_us_tablespoon_short">tablespoon</string>
|
||||
<string name="unit_us_tablespoon_short">cuillère à soupe</string>
|
||||
<string name="unit_us_teaspoon">Cuillère à café américaine</string>
|
||||
<string name="unit_us_teaspoon_short">teaspoon</string>
|
||||
<string name="unit_us_teaspoon_short">cuillère à café</string>
|
||||
<string name="unit_velocity_of_light_in_vacuum">Vitesse de la lumière dans le vide</string>
|
||||
<string name="unit_venus_equatorial_radius">Radius équatorial de Vénus</string>
|
||||
<string name="unit_venus_equatorial_radius_short">R Vénus</string>
|
||||
|
@ -25,7 +25,6 @@ import androidx.compose.foundation.layout.FlowRowScope
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
/**
|
||||
@ -51,8 +50,8 @@ fun KeypadFlow(
|
||||
@IntRange(0, 100) verticalPadding: Int = 10,
|
||||
content: @Composable FlowRowScope.(width: Float, height: Float) -> Unit,
|
||||
) {
|
||||
val height: Float = remember { (1f - verticalPadding / 100f) / rows }
|
||||
val width: Float = remember { (1f - horizontalPadding / 100f) / columns }
|
||||
val height: Float = (1f - verticalPadding / 100f) / rows
|
||||
val width: Float = (1f - horizontalPadding / 100f) / columns
|
||||
|
||||
FlowRow(
|
||||
modifier = modifier,
|
||||
|
@ -102,17 +102,232 @@ class UnitsRepositoryImpl @Inject constructor(
|
||||
|
||||
suspend fun getPairId(id: String): String = withContext(Dispatchers.IO) {
|
||||
val basedUnitPair = getUnitStats(id).pairedUnitId
|
||||
if (basedUnitPair != null) return@withContext basedUnitPair
|
||||
if (basedUnitPair != null) {
|
||||
return@withContext basedUnitPair
|
||||
}
|
||||
|
||||
val inMemoryUnit = inMemory.first { it.id == id }
|
||||
val collection = inMemory.filter { it.group == inMemoryUnit.group }
|
||||
|
||||
val pair = collection
|
||||
return@withContext when (inMemoryUnit.id) {
|
||||
// === === === Length === === ===
|
||||
UnitID.nanometer -> UnitID.micrometer
|
||||
UnitID.micrometer -> UnitID.millimeter
|
||||
UnitID.millimeter -> UnitID.centimeter
|
||||
|
||||
UnitID.centimeter -> UnitID.inch
|
||||
UnitID.inch -> UnitID.centimeter
|
||||
UnitID.decimeter -> UnitID.centimeter
|
||||
UnitID.foot -> UnitID.meter
|
||||
UnitID.yard -> UnitID.meter
|
||||
UnitID.meter -> UnitID.foot
|
||||
|
||||
UnitID.kilometer -> UnitID.mile
|
||||
UnitID.mile -> UnitID.kilometer
|
||||
UnitID.nautical_mile -> UnitID.kilometer
|
||||
|
||||
UnitID.mercury_equatorial_radius -> UnitID.kilometer
|
||||
UnitID.mars_equatorial_radius -> UnitID.kilometer
|
||||
UnitID.venus_equatorial_radius -> UnitID.kilometer
|
||||
UnitID.earth_equatorial_radius -> UnitID.kilometer
|
||||
UnitID.neptune_equatorial_radius -> UnitID.kilometer
|
||||
UnitID.uranus_equatorial_radius -> UnitID.kilometer
|
||||
UnitID.saturn_equatorial_radius -> UnitID.kilometer
|
||||
UnitID.jupiter_equatorial_radius -> UnitID.kilometer
|
||||
UnitID.sun_equatorial_radius -> UnitID.kilometer
|
||||
|
||||
UnitID.light_year -> UnitID.kilometer
|
||||
|
||||
UnitID.parsec -> UnitID.light_year
|
||||
UnitID.kiloparsec -> UnitID.parsec
|
||||
UnitID.megaparsec -> UnitID.kiloparsec
|
||||
|
||||
|
||||
// === === === Mass === === ===
|
||||
UnitID.electron_mass_rest -> UnitID.atomic_mass_unit
|
||||
UnitID.atomic_mass_unit -> UnitID.electron_mass_rest
|
||||
|
||||
UnitID.microgram -> UnitID.milligram
|
||||
UnitID.milligram -> UnitID.gram
|
||||
UnitID.grain -> UnitID.gram
|
||||
UnitID.carat -> UnitID.gram
|
||||
|
||||
UnitID.gram -> UnitID.carat
|
||||
UnitID.ounce -> UnitID.gram
|
||||
UnitID.pound -> UnitID.kilogram
|
||||
UnitID.kilogram -> UnitID.pound
|
||||
|
||||
UnitID.metric_ton -> UnitID.kilogram
|
||||
UnitID.imperial_ton -> UnitID.pound
|
||||
|
||||
UnitID.mercury_mass -> UnitID.kilogram
|
||||
UnitID.mars_mass -> UnitID.kilogram
|
||||
UnitID.venus_mass -> UnitID.kilogram
|
||||
UnitID.earth_mass -> UnitID.kilogram
|
||||
UnitID.uranus_mass -> UnitID.kilogram
|
||||
UnitID.neptune_mass -> UnitID.kilogram
|
||||
UnitID.saturn_mass -> UnitID.kilogram
|
||||
UnitID.jupiter_mass -> UnitID.kilogram
|
||||
UnitID.sun_mass -> UnitID.kilogram
|
||||
|
||||
|
||||
// === === === Speed === === ===
|
||||
UnitID.millimeter_per_hour -> UnitID.millimeter_per_second
|
||||
UnitID.millimeter_per_second -> UnitID.millimeter_per_hour
|
||||
UnitID.millimeter_per_minute -> UnitID.millimeter_per_second
|
||||
UnitID.centimeter_per_hour -> UnitID.centimeter_per_second
|
||||
UnitID.centimeter_per_second -> UnitID.centimeter_per_hour
|
||||
UnitID.centimeter_per_minute -> UnitID.centimeter_per_second
|
||||
UnitID.meter_per_hour -> UnitID.meter_per_second
|
||||
UnitID.meter_per_second -> UnitID.meter_per_hour
|
||||
UnitID.meter_per_minute -> UnitID.meter_per_second
|
||||
|
||||
UnitID.kilometer_per_hour -> UnitID.mile_per_hour
|
||||
UnitID.kilometer_per_second -> UnitID.mile_per_second
|
||||
UnitID.kilometer_per_minute -> UnitID.kilometer_per_second
|
||||
UnitID.mile_per_hour -> UnitID.kilometer_per_hour
|
||||
UnitID.mile_per_second -> UnitID.kilometer_per_second
|
||||
UnitID.mile_per_minute -> UnitID.mile_per_second
|
||||
|
||||
UnitID.foot_per_hour -> UnitID.foot_per_second
|
||||
UnitID.foot_per_second -> UnitID.foot_per_hour
|
||||
UnitID.foot_per_minute -> UnitID.foot_per_second
|
||||
UnitID.yard_per_hour -> UnitID.yard_per_second
|
||||
UnitID.yard_per_second -> UnitID.yard_per_hour
|
||||
UnitID.yard_per_minute -> UnitID.yard_per_second
|
||||
|
||||
UnitID.knot -> UnitID.kilometer_per_hour
|
||||
UnitID.mach -> UnitID.kilometer_per_hour
|
||||
UnitID.velocity_of_light_in_vacuum -> UnitID.kilometer_per_hour
|
||||
UnitID.earths_orbital_speed -> UnitID.kilometer_per_hour
|
||||
|
||||
UnitID.cosmic_velocity_first -> UnitID.kilometer_per_hour
|
||||
UnitID.cosmic_velocity_second -> UnitID.kilometer_per_hour
|
||||
UnitID.cosmic_velocity_third -> UnitID.kilometer_per_hour
|
||||
|
||||
|
||||
// === === === Temperature === === ===
|
||||
UnitID.celsius -> UnitID.fahrenheit
|
||||
UnitID.fahrenheit -> UnitID.celsius
|
||||
UnitID.kelvin -> UnitID.celsius
|
||||
|
||||
|
||||
// === === === Area === === ===
|
||||
UnitID.square_micrometer -> UnitID.square_millimeter
|
||||
UnitID.square_millimeter -> UnitID.square_centimeter
|
||||
UnitID.square_centimeter -> UnitID.square_meter
|
||||
UnitID.square_decimeter -> UnitID.square_meter
|
||||
UnitID.square_meter -> UnitID.square_kilometer
|
||||
|
||||
UnitID.square_kilometer -> UnitID.square_meter
|
||||
|
||||
UnitID.square_inch -> UnitID.square_foot
|
||||
UnitID.square_foot -> UnitID.square_inch
|
||||
UnitID.square_yard -> UnitID.square_meter
|
||||
UnitID.square_mile -> UnitID.square_kilometer
|
||||
|
||||
UnitID.acre -> UnitID.square_meter
|
||||
UnitID.hectare -> UnitID.square_meter
|
||||
UnitID.cent -> UnitID.square_meter
|
||||
|
||||
|
||||
// === === === Time === === ===
|
||||
UnitID.attosecond -> UnitID.nanosecond
|
||||
UnitID.nanosecond -> UnitID.microsecond
|
||||
UnitID.microsecond -> UnitID.millisecond
|
||||
UnitID.millisecond -> UnitID.second
|
||||
|
||||
UnitID.jiffy -> UnitID.millisecond
|
||||
|
||||
UnitID.second -> UnitID.millisecond
|
||||
UnitID.minute -> UnitID.second
|
||||
UnitID.hour -> UnitID.minute
|
||||
UnitID.day -> UnitID.hour
|
||||
UnitID.week -> UnitID.day
|
||||
|
||||
|
||||
// === === === Data === === ===
|
||||
// TODO: Add tibibyte, exibyte
|
||||
UnitID.bit -> UnitID.byte
|
||||
UnitID.byte -> UnitID.kilobyte
|
||||
UnitID.kilobyte -> UnitID.megabyte
|
||||
UnitID.megabyte -> UnitID.gigabyte
|
||||
UnitID.gigabyte -> UnitID.terabyte
|
||||
UnitID.terabyte -> UnitID.petabyte
|
||||
UnitID.petabyte -> UnitID.exabyte
|
||||
|
||||
UnitID.kilobit -> UnitID.kilobyte
|
||||
UnitID.megabit -> UnitID.megabyte
|
||||
UnitID.gigabit -> UnitID.gigabyte
|
||||
UnitID.terabit -> UnitID.terabyte
|
||||
UnitID.petabit -> UnitID.petabyte
|
||||
UnitID.exabit -> UnitID.exabyte
|
||||
|
||||
UnitID.kibibit -> UnitID.kilobyte
|
||||
UnitID.mebibit -> UnitID.megabyte
|
||||
UnitID.gibibit -> UnitID.gigabyte
|
||||
|
||||
UnitID.kibibyte -> UnitID.kilobyte
|
||||
UnitID.mebibyte -> UnitID.megabyte
|
||||
UnitID.gibibyte -> UnitID.gigabyte
|
||||
|
||||
|
||||
// === === === Acceleration === === ===
|
||||
UnitID.millimeter_per_square_second -> UnitID.centimeter_per_square_second
|
||||
UnitID.centimeter_per_square_second -> UnitID.meter_per_square_second
|
||||
UnitID.decimeter_per_square_second -> UnitID.meter_per_square_second
|
||||
UnitID.meter_per_square_second -> UnitID.kilometer_per_square_second
|
||||
|
||||
UnitID.mercury_surface_gravity -> UnitID.meter_per_square_second
|
||||
UnitID.mars_surface_gravity -> UnitID.meter_per_square_second
|
||||
UnitID.venus_surface_gravity -> UnitID.meter_per_square_second
|
||||
UnitID.uranus_surface_gravity -> UnitID.meter_per_square_second
|
||||
UnitID.earth_surface_gravity -> UnitID.meter_per_square_second
|
||||
UnitID.saturn_surface_gravity -> UnitID.meter_per_square_second
|
||||
UnitID.neptune_surface_gravity -> UnitID.meter_per_square_second
|
||||
UnitID.jupiter_surface_gravity -> UnitID.meter_per_square_second
|
||||
UnitID.sun_surface_gravity -> UnitID.meter_per_square_second
|
||||
|
||||
|
||||
// === === === Power === === ===
|
||||
UnitID.attowatt -> UnitID.watt
|
||||
UnitID.watt -> UnitID.kilowatt
|
||||
UnitID.kilowatt -> UnitID.watt
|
||||
UnitID.megawatt -> UnitID.kilowatt
|
||||
|
||||
|
||||
// === === === Angle === === ===
|
||||
UnitID.degree -> UnitID.radian
|
||||
UnitID.radian -> UnitID.degree
|
||||
|
||||
|
||||
// === === === Data Transfer === === ===
|
||||
UnitID.bit_per_second -> UnitID.byte_per_second
|
||||
UnitID.kilobit_per_second -> UnitID.kilobyte_per_second
|
||||
UnitID.megabit_per_second -> UnitID.megabyte_per_second
|
||||
UnitID.gigabit_per_second -> UnitID.gigabyte_per_second
|
||||
UnitID.terabit_per_second -> UnitID.terabyte_per_second
|
||||
UnitID.petabit_per_second -> UnitID.petabyte_per_second
|
||||
UnitID.exabit_per_second -> UnitID.exabyte_per_second
|
||||
|
||||
UnitID.byte_per_second -> UnitID.kilobyte_per_second
|
||||
UnitID.kilobyte_per_second -> UnitID.megabyte_per_second
|
||||
UnitID.megabyte_per_second -> UnitID.gigabyte_per_second
|
||||
UnitID.gigabyte_per_second -> UnitID.megabyte_per_second
|
||||
UnitID.terabyte_per_second -> UnitID.gigabyte_per_second
|
||||
UnitID.petabyte_per_second -> UnitID.terabyte_per_second
|
||||
|
||||
|
||||
// === === === Fuel === === ===
|
||||
UnitID.kilometer_per_liter -> UnitID.mile_us_per_liter
|
||||
UnitID.mile_us_per_liter -> UnitID.kilometer_per_liter
|
||||
|
||||
else ->
|
||||
(collection
|
||||
.map { getById(it.id) to getUnitStats(it.id) }
|
||||
.sortedByDescending { it.second.frequency }
|
||||
.firstOrNull { it.second.isFavorite }?.first ?: collection.first()
|
||||
|
||||
return@withContext pair.id
|
||||
.firstOrNull { it.second.isFavorite }?.first ?: collection.first()).id
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun incrementCounter(id: String) = withContext(Dispatchers.IO) {
|
||||
|
@ -27,19 +27,100 @@ import java.math.BigDecimal
|
||||
|
||||
internal val areaCollection: List<BasicUnit> by lazy {
|
||||
listOf(
|
||||
NormalUnit(UnitID.cent, BigDecimal("6083246572000000000000000000000000"), UnitGroup.AREA, R.string.unit_cent, R.string.unit_cent_short),
|
||||
NormalUnit(UnitID.acre, BigDecimal("60832465720000000000000000000000"), UnitGroup.AREA, R.string.unit_acre, R.string.unit_acre_short),
|
||||
NormalUnit(UnitID.hectare, BigDecimal("150320296400000000000000000000000"), UnitGroup.AREA, R.string.unit_hectare, R.string.unit_hectare_short ),
|
||||
NormalUnit(UnitID.square_foot, BigDecimal("1396521251000000000000000000"), UnitGroup.AREA, R.string.unit_square_foot, R.string.unit_square_foot_short),
|
||||
NormalUnit(UnitID.square_mile, BigDecimal("38932778060000000000000000000000000"), UnitGroup.AREA, R.string.unit_square_mile, R.string.unit_square_mile_short),
|
||||
NormalUnit(UnitID.square_yard, BigDecimal("12568691260000000000000000000"), UnitGroup.AREA, R.string.unit_square_yard, R.string.unit_square_yard_short),
|
||||
NormalUnit(UnitID.square_inch, BigDecimal("9698064247000000000000000"), UnitGroup.AREA, R.string.unit_square_inch, R.string.unit_square_inch_short),
|
||||
NormalUnit(UnitID.square_micrometer, BigDecimal("15032029640000000"), UnitGroup.AREA, R.string.unit_square_micrometer, R.string.unit_square_micrometer_short),
|
||||
NormalUnit(UnitID.square_millimeter, BigDecimal("15032029640000000000000"), UnitGroup.AREA, R.string.unit_square_millimeter, R.string.unit_square_millimeter_short),
|
||||
NormalUnit(UnitID.square_centimeter, BigDecimal("1503202964000000000000000"), UnitGroup.AREA, R.string.unit_square_centimeter, R.string.unit_square_centimeter_short),
|
||||
NormalUnit(UnitID.square_decimeter, BigDecimal("150320296400000000000000000"), UnitGroup.AREA, R.string.unit_square_decimeter, R.string.unit_square_decimeter_short),
|
||||
NormalUnit(UnitID.square_meter, BigDecimal("15032029640000000000000000000"), UnitGroup.AREA, R.string.unit_square_meter, R.string.unit_square_meter_short),
|
||||
NormalUnit(UnitID.square_kilometer, BigDecimal("15032029640000000000000000000000000"), UnitGroup.AREA, R.string.unit_square_kilometer, R.string.unit_square_kilometer_short),
|
||||
// https://www.gowebtool.com/unit-conversion/area/convert.php?from=electron_cross_section&to=acre
|
||||
NormalUnit(
|
||||
UnitID.acre,
|
||||
BigDecimal("60832465720659000000000000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_acre,
|
||||
R.string.unit_acre_short,
|
||||
),
|
||||
// https://www.gowebtool.com/unit-conversion/area/convert.php?from=electron_cross_section&to=cent
|
||||
NormalUnit(
|
||||
UnitID.cent,
|
||||
BigDecimal("608324656845820000000000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_cent,
|
||||
R.string.unit_cent_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.hectare,
|
||||
BigDecimal("150320296474920000000000000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_hectare,
|
||||
R.string.unit_hectare_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.square_foot,
|
||||
BigDecimal("1396521251622100000000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_foot,
|
||||
R.string.unit_square_foot_short,
|
||||
),
|
||||
// https://www.gowebtool.com/unit-conversion/area/convert.php?from=electron_cross_section&to=square_mile_survey_us_statute
|
||||
NormalUnit(
|
||||
UnitID.square_mile,
|
||||
BigDecimal("38932778061222000000000000000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_mile,
|
||||
R.string.unit_square_mile_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.square_yard,
|
||||
BigDecimal("12568691264599000000000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_yard,
|
||||
R.string.unit_square_yard_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.square_inch,
|
||||
BigDecimal("9698064247375700000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_inch,
|
||||
R.string.unit_square_inch_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.square_micrometer,
|
||||
BigDecimal("15032029647492000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_micrometer,
|
||||
R.string.unit_square_micrometer_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.square_millimeter,
|
||||
BigDecimal("15032029647492000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_millimeter,
|
||||
R.string.unit_square_millimeter_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.square_centimeter,
|
||||
BigDecimal("1503202964749200000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_centimeter,
|
||||
R.string.unit_square_centimeter_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.square_decimeter,
|
||||
BigDecimal("150320296474920000000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_decimeter,
|
||||
R.string.unit_square_decimeter_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.square_meter,
|
||||
BigDecimal("15032029647492000000000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_meter,
|
||||
R.string.unit_square_meter_short,
|
||||
),
|
||||
NormalUnit(
|
||||
UnitID.square_kilometer,
|
||||
BigDecimal("15032029647492000000000000000000000"),
|
||||
UnitGroup.AREA,
|
||||
R.string.unit_square_kilometer,
|
||||
R.string.unit_square_kilometer_short,
|
||||
),
|
||||
NormalUnit(UnitID.electron_cross_section, BigDecimal("1"), UnitGroup.AREA, R.string.unit_electron_cross_section, R.string.unit_electron_cross_section_short),
|
||||
)
|
||||
}
|
||||
|
@ -119,12 +119,21 @@ class AllUnitsTest {
|
||||
|
||||
@Test
|
||||
fun testArea() = testWithUnits {
|
||||
cent.checkWith(acre, "75.9", "7590")
|
||||
cent.checkWith(acre, "75.9", "0.759")
|
||||
cent.checkWith(square_meter, "1", "40.46856")
|
||||
acre.checkWith(square_kilometer, "75.9", "0.30716")
|
||||
hectare.checkWith(square_foot, "75.9", "8169808.00585")
|
||||
acre.checkWith(square_yard, "1", "4840")
|
||||
acre.checkWith(square_meter, "1", "4046.85642")
|
||||
acre.checkWith(cent, "1", "100")
|
||||
hectare.checkWith(acre, "1", "2.47105");
|
||||
hectare.checkWith(square_foot, "1", "107639.10417")
|
||||
hectare.checkWith(square_foot, "75.9", "8169808.00628")
|
||||
square_foot.checkWith(square_decimeter, "75.9", "705.13407")
|
||||
square_mile.checkWith(square_foot, "75.9", "2115970560.8762")
|
||||
square_mile.checkWith(square_foot, "1", "27878400")
|
||||
// Probably floating point error
|
||||
square_mile.checkWith(square_foot, "75.9", "2115970560.00002")
|
||||
square_yard.checkWith(square_foot, "75.9", "683.1")
|
||||
square_yard.checkWith(square_foot, "1", "9")
|
||||
square_inch.checkWith(square_foot, "75.9", "0.52708")
|
||||
square_micrometer.checkWith(square_millimeter, "75.9", "0.00008")
|
||||
square_millimeter.checkWith(square_centimeter, "75.9", "0.759")
|
||||
@ -133,6 +142,7 @@ class AllUnitsTest {
|
||||
square_meter.checkWith(acre, "75.9", "0.01876")
|
||||
square_kilometer.checkWith(hectare, "75.9", "7590")
|
||||
electron_cross_section.checkWith(square_micrometer, "75.9", "0.000000000000005")
|
||||
square_decimeter.checkWith(acre, "123.456", "0.00031")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -26,9 +26,19 @@ import kotlin.math.asin
|
||||
import kotlin.math.atan
|
||||
import kotlin.math.pow
|
||||
|
||||
// Dirty hack to avoid -0.000000000001
|
||||
val PI_THRESHOLD = BigDecimal("0.000000000000001")
|
||||
|
||||
internal fun BigDecimal.sin(radianMode: Boolean): BigDecimal {
|
||||
val angle: Double = if (radianMode) this.toDouble() else Math.toRadians(this.toDouble())
|
||||
return kotlin.math.sin(angle).toBigDecimal()
|
||||
|
||||
val result = kotlin.math.sin(angle).toBigDecimal()
|
||||
|
||||
if (result.abs() < PI_THRESHOLD) {
|
||||
return BigDecimal.ZERO
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
internal fun BigDecimal.arsin(radianMode: Boolean): BigDecimal {
|
||||
@ -38,7 +48,14 @@ internal fun BigDecimal.arsin(radianMode: Boolean): BigDecimal {
|
||||
|
||||
internal fun BigDecimal.cos(radianMode: Boolean): BigDecimal {
|
||||
val angle: Double = if (radianMode) this.toDouble() else Math.toRadians(this.toDouble())
|
||||
return kotlin.math.cos(angle).toBigDecimal()
|
||||
|
||||
val result = kotlin.math.cos(angle).toBigDecimal()
|
||||
|
||||
if (result.abs() < PI_THRESHOLD) {
|
||||
return BigDecimal.ZERO
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
internal fun BigDecimal.arcos(radianMode: Boolean): BigDecimal {
|
||||
|
@ -93,10 +93,14 @@ class Expression(
|
||||
}
|
||||
|
||||
moveIfMatched(Token.Operator.divide) -> {
|
||||
val divisor = parseFactor()
|
||||
// Adding those `setScale` calls have been added in
|
||||
// 36a931c7d175b5cad52ff3abceb7784b0bb82aac to fix #18
|
||||
// I'm not sure if this is the correct way to fix it, but it
|
||||
// seems to be working
|
||||
val divisor = parseFactor().setScale(MAX_PRECISION)
|
||||
if (divisor.compareTo(BigDecimal.ZERO) == 0) throw ExpressionException.DivideByZero()
|
||||
|
||||
expression = expression.divide(divisor, roundingMode)
|
||||
expression = expression.setScale(MAX_PRECISION).divide(divisor, roundingMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,7 +170,8 @@ class Expression(
|
||||
|
||||
// sin
|
||||
if (moveIfMatched(Token.Func.sin)) {
|
||||
expr = parseFuncParentheses().sin(radianMode)
|
||||
val x = parseFuncParentheses()
|
||||
expr = x.sin(radianMode)
|
||||
}
|
||||
|
||||
// cos
|
||||
@ -211,7 +216,13 @@ class Expression(
|
||||
|
||||
// Power
|
||||
if (moveIfMatched(Token.Operator.power)) {
|
||||
expr = expr.pow(parseFactor())
|
||||
val factor = parseFactor()
|
||||
|
||||
if (factor.compareTo(BigDecimal.ZERO) == 0 && expr.compareTo(BigDecimal.ZERO) == 0) {
|
||||
throw ExpressionException.BadExpression()
|
||||
}
|
||||
|
||||
expr = expr.pow(factor)
|
||||
}
|
||||
|
||||
// Modulo
|
||||
|
@ -57,4 +57,7 @@ class ExpressionComplexTest {
|
||||
|
||||
@Test
|
||||
fun expression12() = assertExpr("2×(3+4)×(5−2)÷6", "7")
|
||||
|
||||
@Test
|
||||
fun shouldDivideRootAndDivideInCorrectOrder() = assertExpr("(√9)÷6", "0.5")
|
||||
}
|
||||
|
@ -111,4 +111,55 @@ class ExpressionSimpleTest {
|
||||
|
||||
@Test
|
||||
fun expression29() = assertExpr("0!", "1")
|
||||
|
||||
@Test
|
||||
fun factorial() = assertExpr("5!", "120")
|
||||
|
||||
@Test
|
||||
fun singleNumber() = assertExpr("42", "42")
|
||||
|
||||
@Test(expected = NumberFormatException::class)
|
||||
fun divisionByZero() = assertExpr("1÷0", "")
|
||||
|
||||
@Test(expected = NumberFormatException::class)
|
||||
fun invalidExpressionMissingOperand() = assertExpr("42+", "")
|
||||
|
||||
@Test
|
||||
fun largeNumbers() = assertExpr("9999999999*9999999999", "99999999980000000001")
|
||||
|
||||
@Test
|
||||
fun highPrecision() = assertExpr("1÷3", "0.3333333333")
|
||||
|
||||
@Test
|
||||
fun deeplyNestedParentheses() = assertExpr("((((((42))))))", "42")
|
||||
|
||||
@Test
|
||||
fun constantsAndFunctions() = assertExpr("π+e", "${Math.PI + Math.E}")
|
||||
|
||||
@Test(expected = NumberFormatException::class)
|
||||
fun edgeMathematicalCases() = assertExpr("0^0", "")
|
||||
|
||||
@Test
|
||||
fun zeroExponent() = assertExpr("5^0", "1")
|
||||
|
||||
@Test
|
||||
fun negativeExponent() = assertExpr("5^(−2)", "0.04")
|
||||
|
||||
@Test
|
||||
fun trigonometricLimits() = assertExpr("sin(0)", "0")
|
||||
|
||||
@Test
|
||||
fun sinAtPi() = assertExpr("sin(π)", "0")
|
||||
|
||||
@Test
|
||||
fun sinAtHalfPi() = assertExpr("sin(π÷2)", "1")
|
||||
|
||||
@Test
|
||||
fun cosAtPi() = assertExpr("cos(π)", "-1")
|
||||
|
||||
@Test
|
||||
fun cosAtHalfPi() = assertExpr("cos(π÷2)", "0")
|
||||
|
||||
@Test
|
||||
fun cosAtPiOverThree() = assertExpr("cos(π÷3)", "0.5")
|
||||
}
|
||||
|
@ -37,6 +37,16 @@ sealed interface BasicUnit {
|
||||
|
||||
interface NumberBase : BasicUnit {
|
||||
fun convert(unitTo: NumberBase, value: String): String
|
||||
|
||||
companion object {
|
||||
val Hexadecimal = NumberBaseUnit(
|
||||
"hexadecimal",
|
||||
BigDecimal(16),
|
||||
UnitGroup.NUMBER_BASE,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
interface Default : BasicUnit {
|
||||
|
@ -120,7 +120,7 @@ internal fun Preferences.getUnitConverterFormatTime(): Boolean {
|
||||
|
||||
internal fun Preferences.getUnitConverterSorting(): UnitsListSorting {
|
||||
return this[PrefsKeys.UNIT_CONVERTER_SORTING]
|
||||
?.let { UnitsListSorting.valueOf(it) } ?: UnitsListSorting.USAGE
|
||||
?.let { UnitsListSorting.valueOf(it) } ?: UnitsListSorting.SCALE_ASC
|
||||
}
|
||||
|
||||
internal fun Preferences.getShownUnitGroups(): List<UnitGroup> {
|
||||
|
@ -1,33 +1,28 @@
|
||||
Calculator, converter and more.
|
||||
Calculator, converter and so much more!
|
||||
|
||||
Look for <b>Calculator</b> on your home screen after installing the app.
|
||||
NumberHub will be installed as "Calculator" on your home screen.
|
||||
|
||||
• Deep customization: themes, number formatter and etc.
|
||||
• No ads, in-app purchases or asking for donations
|
||||
• Open source
|
||||
* No ads or in-app purchases
|
||||
* Open source
|
||||
|
||||
<b>Calculator</b>
|
||||
Calculator
|
||||
|
||||
• Copy, paste, save and share expression results
|
||||
• Trigonometric functions
|
||||
• Fractional output
|
||||
* Copy, paste, save and share expression results
|
||||
* Trigonometric functions
|
||||
* Fractional output
|
||||
|
||||
<b>Unit converter</b>
|
||||
**Unit converter**
|
||||
|
||||
• 570 units
|
||||
• Built-in currency converter
|
||||
• Favorite units
|
||||
• Organize unit groups
|
||||
• Smart search algorithm
|
||||
Over 500 units! Convert miles to kilometers, Dollar to Euro, Bytes to Gigabytes and so much more!
|
||||
|
||||
<b>Date calculator</b>
|
||||
• Add and subtract dates
|
||||
• Calculate difference
|
||||
• Create events in calendar
|
||||
**Date calculator**
|
||||
|
||||
Add and subtract dates with ease
|
||||
|
||||
**Time converter**
|
||||
|
||||
Convert time zones
|
||||
|
||||
<b>Time converter</b>
|
||||
• Add to favorites
|
||||
• Add labels to time zones
|
||||
|
||||
The app uses https://github.com/fawazahmed0/currency-api by https://github.com/fawazahmed0
|
||||
Requests are send to cdn.jsdelivr.net.
|
||||
Requests are sent to cdn.jsdelivr.net.
|
||||
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 527 KiB |
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 492 KiB |
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 829 KiB |
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 420 KiB |
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 1010 KiB |
@ -1 +1 @@
|
||||
Your Hub for ✖️ Math / 💲 Currency rates / 📆 Date calculations / ⌚ Time zones...
|
||||
Your Hub for Math / Currency rates / Date calculations / Time zones...
|
||||
|
@ -1 +1 @@
|
||||
Unitto — calculator and unit converter
|
||||
NumberHub
|
@ -22,6 +22,7 @@ import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.SizeTransform
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.expandHorizontally
|
||||
@ -31,6 +32,11 @@ import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.AnchoredDraggableState
|
||||
import androidx.compose.foundation.gestures.DraggableAnchors
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.anchoredDraggable
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@ -40,6 +46,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.SwapHoriz
|
||||
@ -64,6 +71,7 @@ import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.focus.onFocusEvent
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
@ -94,11 +102,14 @@ import app.myzel394.numberhub.data.common.isExpression
|
||||
import app.myzel394.numberhub.data.converter.ConverterResult
|
||||
import app.myzel394.numberhub.data.converter.UnitID
|
||||
import app.myzel394.numberhub.data.model.converter.UnitGroup
|
||||
import app.myzel394.numberhub.feature.converter.components.BaseCalculationSummary
|
||||
import app.myzel394.numberhub.feature.converter.components.DefaultKeyboard
|
||||
import app.myzel394.numberhub.feature.converter.components.NumberBaseKeyboard
|
||||
import app.myzel394.numberhub.feature.converter.components.UnitSelectionButton
|
||||
import app.myzel394.numberhub.feature.converter.components.ValueOneSummary
|
||||
import java.math.BigDecimal
|
||||
import java.util.Locale
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
@Composable
|
||||
internal fun ConverterRoute(
|
||||
@ -203,10 +214,30 @@ private fun NumberBase(
|
||||
convert()
|
||||
}
|
||||
|
||||
val density = LocalDensity.current
|
||||
val dragState = remember {
|
||||
AnchoredDraggableState(
|
||||
initialValue = DragState.CLOSED,
|
||||
anchors = DraggableAnchors {
|
||||
DragState.CLOSED at 0f
|
||||
DragState.OPEN at with(density) { -60.dp.toPx() }
|
||||
},
|
||||
positionalThreshold = { 0f },
|
||||
velocityThreshold = { 0f },
|
||||
animationSpec = tween(easing = LinearEasing, durationMillis = 50),
|
||||
)
|
||||
}
|
||||
|
||||
PortraitLandscape(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
content1 = { contentModifier ->
|
||||
ColumnWithConstraints(modifier = contentModifier) {
|
||||
ColumnWithConstraints(
|
||||
modifier = contentModifier
|
||||
.anchoredDraggable(
|
||||
state = dragState,
|
||||
orientation = Orientation.Vertical,
|
||||
),
|
||||
) {
|
||||
val textFieldModifier = Modifier.weight(2f)
|
||||
|
||||
NumberBaseTextField(
|
||||
@ -224,6 +255,22 @@ private fun NumberBase(
|
||||
)
|
||||
AnimatedUnitShortName(stringResource(uiState.unitTo.shortName))
|
||||
|
||||
if (uiState.result is ConverterResult.NumberBase) {
|
||||
BaseCalculationSummary(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.horizontalScroll(rememberScrollState())
|
||||
.then(with(density) { Modifier.height(dragState.offset.absoluteValue.toDp()) }),
|
||||
basis = uiState.unitTo,
|
||||
result = uiState.result,
|
||||
onResultChange = { newValue ->
|
||||
val valueConverted = uiState.unitTo.convert(uiState.unitFrom, newValue)
|
||||
|
||||
updateInput1(TextFieldValue(valueConverted))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(it.maxHeight * 0.03f))
|
||||
|
||||
UnitSelectionButtons(
|
||||
@ -250,6 +297,7 @@ private fun NumberBase(
|
||||
addDigit = { updateInput1(uiState.input.addTokens(it)) },
|
||||
deleteDigit = { updateInput1(uiState.input.deleteTokens()) },
|
||||
clearInput = { updateInput1(TextFieldValue()) },
|
||||
basis = uiState.unitFrom,
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -284,6 +332,20 @@ private fun Default(
|
||||
}
|
||||
var focusedOnInput1 by rememberSaveable { mutableStateOf(true) }
|
||||
|
||||
val density = LocalDensity.current
|
||||
val dragState = remember {
|
||||
AnchoredDraggableState(
|
||||
initialValue = DragState.CLOSED,
|
||||
anchors = DraggableAnchors {
|
||||
DragState.CLOSED at 0f
|
||||
DragState.OPEN at with(density) { -60.dp.toPx() }
|
||||
},
|
||||
positionalThreshold = { 0f },
|
||||
velocityThreshold = { 0f },
|
||||
animationSpec = tween(easing = LinearEasing, durationMillis = 50),
|
||||
)
|
||||
}
|
||||
|
||||
LaunchedEffect(connection) {
|
||||
if ((connection == ConnectionState.Available) and (uiState.result is ConverterResult.Error)) {
|
||||
val unitFrom = uiState.unitFrom
|
||||
@ -304,7 +366,13 @@ private fun Default(
|
||||
PortraitLandscape(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
content1 = { contentModifier ->
|
||||
ColumnWithConstraints(modifier = contentModifier) { boxWithConstraintsScope ->
|
||||
ColumnWithConstraints(
|
||||
modifier = contentModifier
|
||||
.anchoredDraggable(
|
||||
state = dragState,
|
||||
orientation = Orientation.Vertical,
|
||||
),
|
||||
) { boxWithConstraintsScope ->
|
||||
val textFieldModifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(2f)
|
||||
@ -425,6 +493,18 @@ private fun Default(
|
||||
),
|
||||
)
|
||||
|
||||
if (uiState.result is ConverterResult.Default && uiState.unitTo.factor > BigDecimal.ZERO) {
|
||||
ValueOneSummary(
|
||||
modifier = with(density) {
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.height(dragState.offset.absoluteValue.toDp())
|
||||
.horizontalScroll(rememberScrollState())
|
||||
},
|
||||
uiState = uiState,
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(boxWithConstraintsScope.maxHeight * 0.03f))
|
||||
|
||||
UnitSelectionButtons(
|
||||
|
@ -0,0 +1,3 @@
|
||||
package app.myzel394.numberhub.feature.converter
|
||||
|
||||
internal enum class DragState { CLOSED, OPEN }
|
@ -156,7 +156,7 @@ private fun UnitFromSelectorScreenPreview() {
|
||||
selectedUnitGroup = UnitGroup.SPEED,
|
||||
shownUnitGroups = UnitGroup.entries,
|
||||
showFavoritesOnly = false,
|
||||
sorting = UnitsListSorting.USAGE,
|
||||
sorting = UnitsListSorting.SCALE_ASC,
|
||||
),
|
||||
onQueryChange = {},
|
||||
toggleFavoritesOnly = {},
|
||||
|
@ -155,7 +155,7 @@ private fun UnitToSelectorPreview() {
|
||||
query = TextFieldValue("test"),
|
||||
units = units,
|
||||
showFavoritesOnly = false,
|
||||
sorting = UnitsListSorting.USAGE,
|
||||
sorting = UnitsListSorting.SCALE_ASC,
|
||||
input = "100",
|
||||
scale = 3,
|
||||
outputFormat = OutputFormat.PLAIN,
|
||||
|
@ -0,0 +1,86 @@
|
||||
package app.myzel394.numberhub.feature.converter.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.myzel394.numberhub.data.converter.ConverterResult
|
||||
import app.myzel394.numberhub.data.model.converter.unit.BasicUnit
|
||||
|
||||
@Composable
|
||||
internal fun BaseCalculationSummary(
|
||||
modifier: Modifier = Modifier,
|
||||
basis: BasicUnit.NumberBase,
|
||||
result: ConverterResult.NumberBase,
|
||||
onResultChange: (String) -> Unit,
|
||||
) {
|
||||
val fontStyle = MaterialTheme.typography.headlineSmall
|
||||
|
||||
Row(
|
||||
modifier,
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
for (index in 0..<result.value.length) {
|
||||
val character = result.value[index]
|
||||
val digit = character.digitToInt(16);
|
||||
val base = basis.factor.toInt()
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clip(MaterialTheme.shapes.small)
|
||||
.clickable {
|
||||
val newCurrentValue = (digit + 1) % base
|
||||
val newResultText = result.value.substring(
|
||||
0,
|
||||
index,
|
||||
) + newCurrentValue.toString(16) + result.value.substring(index + 1)
|
||||
|
||||
onResultChange(newResultText)
|
||||
}
|
||||
.padding(vertical = 2.dp, horizontal = 6.dp),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = "$digit",
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
Text(
|
||||
text = " · $base",
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Text(
|
||||
text = "${result.value.length - index - 1}",
|
||||
modifier = Modifier.offset(
|
||||
y = -(MaterialTheme.typography.bodySmall.fontSize.div(
|
||||
2,
|
||||
)).value.dp,
|
||||
),
|
||||
style = fontStyle.copy(
|
||||
fontSize = MaterialTheme.typography.bodySmall.fontSize,
|
||||
),
|
||||
color = MaterialTheme.colorScheme.tertiary,
|
||||
)
|
||||
}
|
||||
|
||||
if (index < result.value.length - 1) {
|
||||
Text(
|
||||
text = " + ",
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,18 +18,33 @@
|
||||
|
||||
package app.myzel394.numberhub.feature.converter.components
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedContentTransitionScope
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.myzel394.numberhub.core.base.R
|
||||
import app.myzel394.numberhub.core.base.Token
|
||||
import app.myzel394.numberhub.core.ui.LocalWindowSize
|
||||
import app.myzel394.numberhub.core.ui.WindowHeightSizeClass
|
||||
import app.myzel394.numberhub.core.ui.WindowWidthSizeClass
|
||||
import app.myzel394.numberhub.core.ui.common.ColumnWithConstraints
|
||||
import app.myzel394.numberhub.core.ui.common.KeyboardButtonFilled
|
||||
import app.myzel394.numberhub.core.ui.common.KeyboardButtonLight
|
||||
import app.myzel394.numberhub.core.ui.common.KeyboardButtonTertiary
|
||||
@ -65,6 +80,9 @@ import app.myzel394.numberhub.core.ui.common.icons.iconpack.Plus
|
||||
import app.myzel394.numberhub.core.ui.common.icons.iconpack.Power
|
||||
import app.myzel394.numberhub.core.ui.common.icons.iconpack.RightBracket
|
||||
import app.myzel394.numberhub.core.ui.common.icons.iconpack.Root
|
||||
import app.myzel394.numberhub.data.model.converter.unit.BasicUnit
|
||||
import app.myzel394.numberhub.feature.converter.createSortedArray
|
||||
import kotlin.math.ceil
|
||||
|
||||
@Composable
|
||||
internal fun DefaultKeyboard(
|
||||
@ -79,92 +97,401 @@ internal fun DefaultKeyboard(
|
||||
) {
|
||||
val fractionalIcon = remember(fractional) { if (fractional == Token.PERIOD) IconPack.Dot else IconPack.Comma }
|
||||
val fractionalIconDescription = remember(fractional) { if (fractional == Token.PERIOD) R.string.keyboard_dot else R.string.comma }
|
||||
val contentHeight: Float = if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonToken.CONTENT_HEIGHT_SHORT else KeyboardButtonToken.CONTENT_HEIGHT_TALL
|
||||
val contentHeight: Float =
|
||||
if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonToken.CONTENT_HEIGHT_SHORT else KeyboardButtonToken.CONTENT_HEIGHT_TALL
|
||||
|
||||
KeypadFlow(
|
||||
modifier = modifier,
|
||||
rows = 5,
|
||||
columns = 4,
|
||||
) { width, height ->
|
||||
val bModifier = Modifier.fillMaxWidth(width).fillMaxHeight(height)
|
||||
val bModifier = Modifier
|
||||
.fillMaxWidth(width)
|
||||
.fillMaxHeight(height)
|
||||
|
||||
if (acButton) {
|
||||
KeyboardButtonTertiary(bModifier, IconPack.Clear, stringResource(R.string.delete_label), contentHeight) { clearInput() }
|
||||
KeyboardButtonFilled(bModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), contentHeight) { addBracket() }
|
||||
KeyboardButtonTertiary(
|
||||
bModifier,
|
||||
IconPack.Clear,
|
||||
stringResource(R.string.delete_label),
|
||||
contentHeight,
|
||||
) { clearInput() }
|
||||
KeyboardButtonFilled(
|
||||
bModifier,
|
||||
IconPack.Brackets,
|
||||
stringResource(R.string.keyboard_brackets),
|
||||
contentHeight,
|
||||
) { addBracket() }
|
||||
} else {
|
||||
KeyboardButtonFilled(bModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), contentHeight) { addDigit(Token.Operator.leftBracket) }
|
||||
KeyboardButtonFilled(bModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), contentHeight) { addDigit(Token.Operator.rightBracket) }
|
||||
KeyboardButtonFilled(
|
||||
bModifier,
|
||||
IconPack.LeftBracket,
|
||||
stringResource(R.string.keyboard_left_bracket),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Operator.leftBracket) }
|
||||
KeyboardButtonFilled(
|
||||
bModifier,
|
||||
IconPack.RightBracket,
|
||||
stringResource(R.string.keyboard_right_bracket),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Operator.rightBracket) }
|
||||
}
|
||||
KeyboardButtonFilled(bModifier, IconPack.Power, stringResource(R.string.keyboard_power), contentHeight) { addDigit(Token.Operator.power) }
|
||||
KeyboardButtonFilled(bModifier, IconPack.Root, stringResource(R.string.keyboard_root), contentHeight) { addDigit(Token.Operator.sqrt) }
|
||||
KeyboardButtonFilled(
|
||||
bModifier,
|
||||
IconPack.Power,
|
||||
stringResource(R.string.keyboard_power),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Operator.power) }
|
||||
KeyboardButtonFilled(
|
||||
bModifier,
|
||||
IconPack.Root,
|
||||
stringResource(R.string.keyboard_root),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Operator.sqrt) }
|
||||
|
||||
KeyboardButtonLight(bModifier, IconPack.Key7, Token.Digit._7, contentHeight) { addDigit(Token.Digit._7) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key8, Token.Digit._8, contentHeight) { addDigit(Token.Digit._8) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key9, Token.Digit._9, contentHeight) { addDigit(Token.Digit._9) }
|
||||
KeyboardButtonFilled(bModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), contentHeight) { addDigit(Token.Operator.divide) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key7,
|
||||
Token.Digit._7,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._7) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key8,
|
||||
Token.Digit._8,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._8) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key9,
|
||||
Token.Digit._9,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._9) }
|
||||
KeyboardButtonFilled(
|
||||
bModifier,
|
||||
IconPack.Divide,
|
||||
stringResource(R.string.keyboard_divide),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Operator.divide) }
|
||||
|
||||
KeyboardButtonLight(bModifier, IconPack.Key4, Token.Digit._4, contentHeight) { addDigit(Token.Digit._4) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key5, Token.Digit._5, contentHeight) { addDigit(Token.Digit._5) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key6, Token.Digit._6, contentHeight) { addDigit(Token.Digit._6) }
|
||||
KeyboardButtonFilled(bModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), contentHeight) { addDigit(Token.Operator.multiply) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key4,
|
||||
Token.Digit._4,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._4) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key5,
|
||||
Token.Digit._5,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._5) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key6,
|
||||
Token.Digit._6,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._6) }
|
||||
KeyboardButtonFilled(
|
||||
bModifier,
|
||||
IconPack.Multiply,
|
||||
stringResource(R.string.keyboard_multiply),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Operator.multiply) }
|
||||
|
||||
KeyboardButtonLight(bModifier, IconPack.Key1, Token.Digit._1, contentHeight) { addDigit(Token.Digit._1) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key2, Token.Digit._2, contentHeight) { addDigit(Token.Digit._2) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key3, Token.Digit._3, contentHeight) { addDigit(Token.Digit._3) }
|
||||
KeyboardButtonFilled(bModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), contentHeight) { addDigit(Token.Operator.minus) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key1,
|
||||
Token.Digit._1,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._1) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key2,
|
||||
Token.Digit._2,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._2) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key3,
|
||||
Token.Digit._3,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._3) }
|
||||
KeyboardButtonFilled(
|
||||
bModifier,
|
||||
IconPack.Minus,
|
||||
stringResource(R.string.keyboard_minus),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Operator.minus) }
|
||||
|
||||
if (middleZero) {
|
||||
KeyboardButtonLight(bModifier, fractionalIcon, stringResource(fractionalIconDescription), contentHeight) { addDigit(Token.Digit.dot) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key0, Token.Digit._0, contentHeight) { addDigit(Token.Digit._0) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
fractionalIcon,
|
||||
stringResource(fractionalIconDescription),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit.dot) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key0,
|
||||
Token.Digit._0,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._0) }
|
||||
} else {
|
||||
KeyboardButtonLight(bModifier, IconPack.Key0, Token.Digit._0, contentHeight) { addDigit(Token.Digit._0) }
|
||||
KeyboardButtonLight(bModifier, fractionalIcon, stringResource(fractionalIconDescription), contentHeight) { addDigit(Token.Digit.dot) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Key0,
|
||||
Token.Digit._0,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._0) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
fractionalIcon,
|
||||
stringResource(fractionalIconDescription),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit.dot) }
|
||||
}
|
||||
KeyboardButtonLight(bModifier, IconPack.Backspace, stringResource(R.string.delete_label), contentHeight, onLongClick = clearInput) { deleteDigit() }
|
||||
KeyboardButtonFilled(bModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), contentHeight) { addDigit(Token.Operator.plus) }
|
||||
KeyboardButtonLight(
|
||||
bModifier,
|
||||
IconPack.Backspace,
|
||||
stringResource(R.string.delete_label),
|
||||
contentHeight,
|
||||
onLongClick = clearInput,
|
||||
) { deleteDigit() }
|
||||
KeyboardButtonFilled(
|
||||
bModifier,
|
||||
IconPack.Plus,
|
||||
stringResource(R.string.keyboard_plus),
|
||||
contentHeight,
|
||||
) { addDigit(Token.Operator.plus) }
|
||||
}
|
||||
}
|
||||
|
||||
val AVAILABLE_NUMBERS = mapOf<String, ImageVector>(
|
||||
Token.Digit._0 to IconPack.Key0,
|
||||
Token.Digit._1 to IconPack.Key1,
|
||||
Token.Digit._2 to IconPack.Key2,
|
||||
Token.Digit._3 to IconPack.Key3,
|
||||
Token.Digit._4 to IconPack.Key4,
|
||||
Token.Digit._5 to IconPack.Key5,
|
||||
Token.Digit._6 to IconPack.Key6,
|
||||
Token.Digit._7 to IconPack.Key7,
|
||||
Token.Digit._8 to IconPack.Key8,
|
||||
Token.Digit._9 to IconPack.Key9,
|
||||
Token.Letter._A to IconPack.KeyA,
|
||||
Token.Letter._B to IconPack.KeyB,
|
||||
Token.Letter._C to IconPack.KeyC,
|
||||
Token.Letter._D to IconPack.KeyD,
|
||||
Token.Letter._E to IconPack.KeyE,
|
||||
Token.Letter._F to IconPack.KeyF,
|
||||
)
|
||||
|
||||
@Composable
|
||||
internal fun NumberBaseKeyboard(
|
||||
modifier: Modifier,
|
||||
addDigit: (String) -> Unit,
|
||||
clearInput: () -> Unit,
|
||||
deleteDigit: () -> Unit,
|
||||
basis: BasicUnit.NumberBase,
|
||||
) {
|
||||
val contentHeight: Float = if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonToken.CONTENT_HEIGHT_SHORT else KeyboardButtonToken.CONTENT_HEIGHT_TALL
|
||||
val isUsingColumn =
|
||||
(LocalWindowSize.current.widthSizeClass > WindowWidthSizeClass.Expanded) or (LocalWindowSize.current.heightSizeClass > WindowHeightSizeClass.Compact)
|
||||
|
||||
KeypadFlow(
|
||||
var direction by remember {
|
||||
mutableStateOf(AnimatedContentTransitionScope.SlideDirection.Right)
|
||||
}
|
||||
|
||||
LaunchedEffect(isUsingColumn) {
|
||||
direction = if (isUsingColumn) {
|
||||
AnimatedContentTransitionScope.SlideDirection.Right
|
||||
} else {
|
||||
AnimatedContentTransitionScope.SlideDirection.Up
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(basis) {
|
||||
direction = when (direction) {
|
||||
AnimatedContentTransitionScope.SlideDirection.Up -> AnimatedContentTransitionScope.SlideDirection.Down
|
||||
AnimatedContentTransitionScope.SlideDirection.Down -> AnimatedContentTransitionScope.SlideDirection.Up
|
||||
AnimatedContentTransitionScope.SlideDirection.Left -> AnimatedContentTransitionScope.SlideDirection.Right
|
||||
AnimatedContentTransitionScope.SlideDirection.Right -> AnimatedContentTransitionScope.SlideDirection.Left
|
||||
else -> direction
|
||||
}
|
||||
}
|
||||
|
||||
ColumnWithConstraints(modifier) { constraints ->
|
||||
AnimatedContent(
|
||||
transitionSpec = {
|
||||
slideIntoContainer(animationSpec = tween(600), towards = direction).togetherWith(
|
||||
slideOutOfContainer(animationSpec = tween(600), towards = direction),
|
||||
)
|
||||
},
|
||||
targetState = basis.factor.toInt(),
|
||||
label = "ConverterKeyboard-FlowRow",
|
||||
) { amount ->
|
||||
val columns: Int = when {
|
||||
amount == 5 -> 2
|
||||
amount == 3 -> 2
|
||||
amount == 7 -> 2
|
||||
amount == 10 -> 3
|
||||
amount < 10 -> if (amount.and(1) == 0) 2 else if (amount % 3 == 0) 3 else amount % 3
|
||||
else -> 3
|
||||
}
|
||||
val rows = when {
|
||||
amount == 5 -> 3
|
||||
amount == 3 -> 2
|
||||
amount == 7 -> 4
|
||||
amount == 10 -> 4
|
||||
amount < 10 -> ceil(amount.toDouble() / columns.toDouble()).toInt() + 1
|
||||
amount == 11 -> 5
|
||||
amount == 12 -> 5
|
||||
amount == 13 -> 5
|
||||
else -> 6
|
||||
}
|
||||
val horizontalSpacing = 8.dp
|
||||
val verticalSpacing = 12.dp
|
||||
val height: Float = (1f - (verticalSpacing * (rows - 1) / constraints.maxHeight)) / rows
|
||||
|
||||
FlowRow(
|
||||
modifier = modifier,
|
||||
rows = 6,
|
||||
columns = 3,
|
||||
) { width, height ->
|
||||
val bModifier = Modifier.fillMaxWidth(width).fillMaxHeight(height)
|
||||
val wideButtonModifier = Modifier.fillMaxHeight(height).fillMaxWidth(width * 2)
|
||||
maxItemsInEachRow = columns,
|
||||
horizontalArrangement = Arrangement.spacedBy(horizontalSpacing),
|
||||
verticalArrangement = Arrangement.spacedBy(verticalSpacing),
|
||||
) {
|
||||
val bModifier = Modifier
|
||||
.fillMaxHeight(height)
|
||||
.fillMaxWidth()
|
||||
|
||||
KeyboardButtonFilled(bModifier, IconPack.KeyA, Token.Letter._A, contentHeight) { addDigit(Token.Letter._A) }
|
||||
KeyboardButtonFilled(bModifier, IconPack.KeyB, Token.Letter._B, contentHeight) { addDigit(Token.Letter._B) }
|
||||
KeyboardButtonFilled(bModifier, IconPack.KeyC, Token.Letter._C, contentHeight) { addDigit(Token.Letter._C) }
|
||||
when {
|
||||
amount in arrayOf(3, 5, 7) -> {
|
||||
for (int in createSortedArray(1..<amount, columns)) {
|
||||
val key = AVAILABLE_NUMBERS.keys.elementAt(int)
|
||||
val icon = AVAILABLE_NUMBERS[key]!!
|
||||
KeyboardButtonLight(
|
||||
bModifier.weight(1f),
|
||||
icon,
|
||||
key,
|
||||
contentHeight,
|
||||
) { addDigit(key) }
|
||||
}
|
||||
|
||||
KeyboardButtonFilled(bModifier, IconPack.KeyD, Token.Letter._D, contentHeight) { addDigit(Token.Letter._D) }
|
||||
KeyboardButtonFilled(bModifier, IconPack.KeyE, Token.Letter._E, contentHeight) { addDigit(Token.Letter._E) }
|
||||
KeyboardButtonFilled(bModifier, IconPack.KeyF, Token.Letter._F, contentHeight) { addDigit(Token.Letter._F) }
|
||||
KeyboardButtonLight(
|
||||
bModifier.weight(1f),
|
||||
IconPack.Key0,
|
||||
Token.Digit._0,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._0) }
|
||||
KeyboardButtonTertiary(
|
||||
bModifier.weight(1f),
|
||||
IconPack.Backspace,
|
||||
stringResource(R.string.delete_label),
|
||||
contentHeight,
|
||||
clearInput,
|
||||
) { deleteDigit() }
|
||||
}
|
||||
|
||||
KeyboardButtonLight(bModifier, IconPack.Key7, Token.Digit._7, contentHeight) { addDigit(Token.Digit._7) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key8, Token.Digit._8, contentHeight) { addDigit(Token.Digit._8) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key9, Token.Digit._9, contentHeight) { addDigit(Token.Digit._9) }
|
||||
amount < 10 -> {
|
||||
for (int in createSortedArray(0..<amount.coerceAtMost(10), columns)) {
|
||||
val key = AVAILABLE_NUMBERS.keys.elementAt(int)
|
||||
val icon = AVAILABLE_NUMBERS[key]!!
|
||||
KeyboardButtonLight(
|
||||
bModifier.weight(1f),
|
||||
icon,
|
||||
key,
|
||||
contentHeight,
|
||||
) { addDigit(key) }
|
||||
}
|
||||
|
||||
KeyboardButtonLight(bModifier, IconPack.Key4, Token.Digit._4, contentHeight) { addDigit(Token.Digit._4) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key5, Token.Digit._5, contentHeight) { addDigit(Token.Digit._5) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key6, Token.Digit._6, contentHeight) { addDigit(Token.Digit._6) }
|
||||
KeyboardButtonTertiary(
|
||||
bModifier,
|
||||
IconPack.Backspace,
|
||||
stringResource(R.string.delete_label),
|
||||
contentHeight,
|
||||
clearInput,
|
||||
) { deleteDigit() }
|
||||
}
|
||||
|
||||
KeyboardButtonLight(bModifier, IconPack.Key1, Token.Digit._1, contentHeight) { addDigit(Token.Digit._1) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key2, Token.Digit._2, contentHeight) { addDigit(Token.Digit._2) }
|
||||
KeyboardButtonLight(bModifier, IconPack.Key3, Token.Digit._3, contentHeight) { addDigit(Token.Digit._3) }
|
||||
amount == 10 -> {
|
||||
for (int in createSortedArray(1..9, columns)) {
|
||||
val key = AVAILABLE_NUMBERS.keys.elementAt(int)
|
||||
val icon = AVAILABLE_NUMBERS[key]!!
|
||||
KeyboardButtonLight(
|
||||
bModifier.weight(1f),
|
||||
icon,
|
||||
key,
|
||||
contentHeight,
|
||||
) { addDigit(key) }
|
||||
}
|
||||
|
||||
// TODO Should be a separate o use custom widthFillFactors and heightFillFactors
|
||||
KeyboardButtonLight(bModifier, IconPack.Key0, Token.Digit._0, contentHeight) { addDigit(Token.Digit._0) }
|
||||
KeyboardButtonLight(wideButtonModifier, IconPack.Backspace, stringResource(R.string.delete_label), contentHeight, clearInput) { deleteDigit() }
|
||||
KeyboardButtonLight(
|
||||
bModifier.weight(1f),
|
||||
IconPack.Key0,
|
||||
Token.Digit._0,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._0) }
|
||||
KeyboardButtonTertiary(
|
||||
bModifier.weight(2f),
|
||||
IconPack.Backspace,
|
||||
stringResource(R.string.delete_label),
|
||||
contentHeight,
|
||||
clearInput,
|
||||
) { deleteDigit() }
|
||||
}
|
||||
|
||||
else -> {
|
||||
val rowsAmount = ceil((amount - 10) / 3f).toInt()
|
||||
|
||||
for (row in (rowsAmount - 1) downTo 0) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(horizontalSpacing),
|
||||
) {
|
||||
val rowStart = 10 + (row) * columns
|
||||
val rowEnd = (rowStart + 3).coerceAtMost(amount.coerceAtMost(16))
|
||||
|
||||
for (index in createSortedArray(rowStart..<rowEnd, columns)) {
|
||||
val key = AVAILABLE_NUMBERS.keys.elementAt(index)
|
||||
val icon = AVAILABLE_NUMBERS[key]!!
|
||||
KeyboardButtonFilled(
|
||||
bModifier.weight(1f),
|
||||
icon,
|
||||
key,
|
||||
contentHeight,
|
||||
) { addDigit(key) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int in createSortedArray(1..9, columns)) {
|
||||
val key = AVAILABLE_NUMBERS.keys.elementAt(int)
|
||||
val icon = AVAILABLE_NUMBERS[key]!!
|
||||
KeyboardButtonLight(
|
||||
bModifier.weight(1f),
|
||||
icon,
|
||||
key,
|
||||
contentHeight,
|
||||
) { addDigit(key) }
|
||||
}
|
||||
|
||||
KeyboardButtonLight(
|
||||
bModifier.weight(1f),
|
||||
IconPack.Key0,
|
||||
Token.Digit._0,
|
||||
contentHeight,
|
||||
) { addDigit(Token.Digit._0) }
|
||||
|
||||
KeyboardButtonTertiary(
|
||||
bModifier.weight(2f),
|
||||
IconPack.Backspace,
|
||||
stringResource(R.string.delete_label),
|
||||
contentHeight,
|
||||
clearInput,
|
||||
) { deleteDigit() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,5 +518,6 @@ private fun PreviewConverterKeyboardNumberBase() {
|
||||
addDigit = {},
|
||||
clearInput = {},
|
||||
deleteDigit = {},
|
||||
basis = BasicUnit.NumberBase.Hexadecimal,
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
package app.myzel394.numberhub.feature.converter.components
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import app.myzel394.numberhub.data.common.format
|
||||
import app.myzel394.numberhub.feature.converter.UnitConverterUIState
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Composable
|
||||
internal fun ValueOneSummary(
|
||||
modifier: Modifier = Modifier,
|
||||
uiState: UnitConverterUIState.Default,
|
||||
) {
|
||||
val unitFromLabel = LocalContext.current.getString(uiState.unitFrom.displayName)
|
||||
val unitToLabel = LocalContext.current.getString(uiState.unitTo.displayName)
|
||||
val value = uiState.unitFrom.convert(uiState.unitTo, BigDecimal(1))
|
||||
.format(uiState.scale, uiState.outputFormat)
|
||||
|
||||
val fontStyle = MaterialTheme.typography.headlineSmall
|
||||
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.End,
|
||||
) {
|
||||
Text(
|
||||
1.toString(),
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
|
||||
Text(
|
||||
" ",
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
Text(
|
||||
unitFromLabel,
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.tertiary,
|
||||
)
|
||||
|
||||
Text(
|
||||
" = ",
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
Text(
|
||||
value,
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
|
||||
Text(
|
||||
" ",
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
|
||||
Text(
|
||||
unitToLabel,
|
||||
style = fontStyle,
|
||||
color = MaterialTheme.colorScheme.tertiary,
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package app.myzel394.numberhub.feature.converter
|
||||
|
||||
import kotlin.math.ceil
|
||||
|
||||
// So here's the problem. If we just go down from 3 downto 0 with columns 2, this results in:
|
||||
// [3, 2]
|
||||
// [1, 0]
|
||||
// While this is correct, the ordering is incorrect. It should be
|
||||
// [2, 3]
|
||||
// [0, 1]
|
||||
// TODO: Add support for rtl languages
|
||||
internal fun createSortedArray(range: IntRange, columns: Int): List<Int> {
|
||||
val result = mutableListOf<Int>()
|
||||
val rows = ceil(range.count().toDouble() / columns.toDouble()).toInt()
|
||||
for (row in rows downTo 0) {
|
||||
for (column in 0 until columns) {
|
||||
val index = row * columns + column + range.first
|
||||
if (index <= range.last) {
|
||||
result.add(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
@ -112,7 +112,7 @@ internal fun ZonedDateTime.minus(
|
||||
)
|
||||
}
|
||||
|
||||
private val yearInSeconds by lazy { BigDecimal("31104000") }
|
||||
private val yearInSeconds by lazy { BigDecimal("31536000") }
|
||||
private val monthsInSeconds by lazy { BigDecimal("2592000") }
|
||||
private val dayInSeconds by lazy { BigDecimal("86400") }
|
||||
private val hourInSeconds by lazy { BigDecimal("3600") }
|
||||
|
@ -139,7 +139,7 @@ private fun PreviewConverterSettingsScreen() {
|
||||
precision = 3,
|
||||
outputFormat = OutputFormat.PLAIN,
|
||||
unitConverterFormatTime = false,
|
||||
unitConverterSorting = UnitsListSorting.USAGE,
|
||||
unitConverterSorting = UnitsListSorting.SCALE_ASC,
|
||||
shownUnitGroups = UnitGroup.entries,
|
||||
unitConverterFavoritesOnly = false,
|
||||
enableToolsExperiment = false,
|
||||
|
@ -1,31 +1,31 @@
|
||||
[versions]
|
||||
versionCode = "4"
|
||||
versionName = "NumberHub"
|
||||
versionCode = "22"
|
||||
versionName = "0.2.2"
|
||||
|
||||
androidxBrowserBrowser = "1.8.0"
|
||||
androidGradlePlugin = "8.3.2"
|
||||
androidxActivityActivityCompose = "1.9.0"
|
||||
androidxAppCompatAppCompat = "1.6.1"
|
||||
androidxCompose = "1.6.7"
|
||||
androidxActivityActivityCompose = "1.9.3"
|
||||
androidxAppCompatAppCompat = "1.7.0"
|
||||
androidxCompose = "1.6.8"
|
||||
androidxComposeCompiler = "1.5.9"
|
||||
androidxComposeMaterial3 = "1.2.1"
|
||||
androidxCoreCoreKts = "1.13.1"
|
||||
androidxGlanceGlance = "1.0.0"
|
||||
androidxGlanceGlance = "1.1.1"
|
||||
androidxDatastoreDatastorePreferences = "1.1.1"
|
||||
androidxEspresso = "3.5.1"
|
||||
androidxEspresso = "3.6.1"
|
||||
androidxHiltHiltNavigationCompose = "1.2.0"
|
||||
androidxMacroBenchmark = "1.2.4"
|
||||
androidxLifecycleLifecycleRuntimeCompose = "2.7.0"
|
||||
androidxMacroBenchmark = "1.3.3"
|
||||
androidxLifecycleLifecycleRuntimeCompose = "2.8.6"
|
||||
androidxNavigationNavigationCompose = "2.7.7"
|
||||
androidxProfileinstallerProfileinstaller = "1.3.1"
|
||||
androidxProfileinstallerProfileinstaller = "1.4.1"
|
||||
androidxRoom = "2.6.1"
|
||||
androidxTest = "1.5.0"
|
||||
androidxTestExtJunitKtx = "1.1.5"
|
||||
androidxTestRunner = "1.5.2"
|
||||
androidxTest = "1.6.1"
|
||||
androidxTestExtJunitKtx = "1.2.1"
|
||||
androidxTestRunner = "1.6.2"
|
||||
androidxUiAutomator = "2.3.0"
|
||||
androidxWindowWindow = "1.2.0"
|
||||
androidxWorkWorkRuntimeKtx = "2.9.0"
|
||||
comAndroidToolsDesugarJdkLibs = "2.0.4"
|
||||
androidxWindowWindow = "1.3.0"
|
||||
androidxWorkWorkRuntimeKtx = "2.9.1"
|
||||
comAndroidToolsDesugarJdkLibs = "2.1.2"
|
||||
comGithubSadellieThemmo = "1.3.0"
|
||||
comGoogleDagger = "2.49"
|
||||
comSquareupMoshiMoshiKotlin = "1.15.0"
|
||||
|
BIN
readme_content/izzyondroid-badge.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
readme_content/showcase.png
Normal file
After Width: | Height: | Size: 65 KiB |