Compare commits
97 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 | ||
![]() |
445dc3eb31 | ||
![]() |
e9229ea12a | ||
![]() |
f7a7c2f69b | ||
![]() |
389ce92132 | ||
![]() |
1c8c26a917 | ||
![]() |
4ea4eaafc5 | ||
![]() |
06840e7b50 | ||
![]() |
1994a783fb | ||
![]() |
aa2976a2ec | ||
![]() |
3e70ef7ae6 | ||
![]() |
8572ce5f63 | ||
![]() |
6a820be441 | ||
![]() |
98b6a4ceb4 | ||
![]() |
24161fb076 | ||
![]() |
6a289a8d7f | ||
![]() |
31a5ae457c | ||
![]() |
86b21832c5 | ||
![]() |
8e67b59ab9 | ||
![]() |
2f1d3a3084 | ||
![]() |
0e1fa3ed8d | ||
![]() |
5730fe5f38 | ||
![]() |
98965ec7b0 | ||
![]() |
f3e31da67c | ||
![]() |
b13876dcdd | ||
![]() |
cacee0a190 | ||
![]() |
f7ec54039b | ||
![]() |
3554a99a5e | ||
![]() |
d208af4f45 | ||
![]() |
dffa2d4e92 | ||
![]() |
acc5d36d17 | ||
![]() |
d683da2ddc | ||
![]() |
b469dd03ac | ||
![]() |
20694480d1 | ||
![]() |
4d96934858 | ||
![]() |
eaa3492709 | ||
![]() |
3f6fa9172c | ||
![]() |
e6115a0b07 | ||
![]() |
b8a302d815 | ||
![]() |
ee12fc493e | ||
![]() |
0318871fe4 | ||
![]() |
456d787768 | ||
![]() |
5d36c0a851 |
4
.github/actions/prepare-keystore/action.yml
vendored
@ -20,12 +20,12 @@ runs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Write Keystore file 🗄️
|
- name: Write Keystore file 🗄️
|
||||||
shell: bash
|
shell: bash
|
||||||
run: echo "${{ inputs.keyStoreBase64 }}" | base64 -d > ~/key.jks
|
run: echo "${{ inputs.keyStoreBase64 }}" | base64 -d > /home/runner/key.jks
|
||||||
|
|
||||||
- name: Write Keystore properties 🗝️
|
- name: Write Keystore properties 🗝️
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
echo "storeFile=~/key.jks" > key.properties
|
echo "storeFile=/home/runner/key.jks" > key.properties
|
||||||
echo "storePassword=${{ inputs.signingStorePassword }}" >> key.properties
|
echo "storePassword=${{ inputs.signingStorePassword }}" >> key.properties
|
||||||
echo "keyPassword=${{ inputs.signingKeyPassword }}" >> key.properties
|
echo "keyPassword=${{ inputs.signingKeyPassword }}" >> key.properties
|
||||||
echo "keyAlias=${{ inputs.signingKeyAlias }}" >> key.properties
|
echo "keyAlias=${{ inputs.signingKeyAlias }}" >> key.properties
|
||||||
|
13
.github/workflows/build-testing.yaml
vendored
@ -3,6 +3,9 @@ name: Build and push debug app
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
|
env:
|
||||||
|
JAVA_OPTS: -Xmx12G
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
debug-builds:
|
debug-builds:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -18,6 +21,14 @@ jobs:
|
|||||||
java-version: 21
|
java-version: 21
|
||||||
cache: "gradle"
|
cache: "gradle"
|
||||||
|
|
||||||
|
- name: Write debug key
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "storeFile=~/.android/debug.keystore" > key.properties
|
||||||
|
echo "storePassword=android" >> key.properties
|
||||||
|
echo "keyPassword=android" >> key.properties
|
||||||
|
echo "keyAlias=androiddebugkey" >> key.properties
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: ./gradlew test
|
run: ./gradlew test
|
||||||
|
|
||||||
@ -28,4 +39,4 @@ jobs:
|
|||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: numberhub-app-debug-apks
|
name: numberhub-app-debug-apks
|
||||||
path: app/build/outputs/apk/fdroid/debug/app-*-debug.apk
|
path: app/build/outputs/apk/*/debug/app-*-debug.apk
|
||||||
|
19
.github/workflows/release-app-github.yaml
vendored
@ -1,9 +1,12 @@
|
|||||||
name: Build and publish app
|
name: Build and publish app (F-Droid variant)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types: [ published ]
|
types: [ published ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
JAVA_OPTS: -Xmx12G
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release-app-github:
|
release-app-github:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -32,8 +35,8 @@ jobs:
|
|||||||
- name: Build APKs 📱
|
- name: Build APKs 📱
|
||||||
run: ./gradlew assembleRelease
|
run: ./gradlew assembleRelease
|
||||||
|
|
||||||
- name: Build AABs 📱
|
- name: Rename APK
|
||||||
run: ./gradlew bundleRelease
|
run: mv app/build/outputs/apk/fdroid/release/app-fdroid-release.apk NumberHub.apk
|
||||||
|
|
||||||
- name: Upload APKs 🚀
|
- name: Upload APKs 🚀
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
@ -41,7 +44,13 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
with:
|
with:
|
||||||
files: app/build/outputs/apk/fdroid/release/*.apk
|
files: NumberHub.apk
|
||||||
|
|
||||||
|
- name: Build AABs 📱
|
||||||
|
run: ./gradlew bundleRelease
|
||||||
|
|
||||||
|
- name: Rename APK
|
||||||
|
run: mv app/build/outputs/bundle/fdroidRelease/app-fdroid-release.aab NumberHub.aab
|
||||||
|
|
||||||
- name: Upload APKs bundles 🚀
|
- name: Upload APKs bundles 🚀
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
@ -49,4 +58,4 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
with:
|
with:
|
||||||
files: app/build/outputs/bundle/fdroidRelease/*.aab
|
files: NumberHub.aab
|
49
.github/workflows/release-app-google-play.yaml
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
name: Build and publish app to Google Play (Google Play variant)
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [ published ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
JAVA_OPTS: -Xmx12G
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release-app-google-play:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: gradle/wrapper-validation-action@v2
|
||||||
|
|
||||||
|
- name: Write KeyStore 🗝️
|
||||||
|
uses: ./.github/actions/prepare-keystore
|
||||||
|
with:
|
||||||
|
signingStorePassword: ${{ secrets.SIGNING_STORE_PASSWORD }}
|
||||||
|
signingKeyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
||||||
|
signingKeyAlias: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||||
|
keyStoreBase64: ${{ secrets.KEYSTORE }}
|
||||||
|
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
|
java-version: 21
|
||||||
|
cache: 'gradle'
|
||||||
|
|
||||||
|
- name: Build Bundles 📱
|
||||||
|
run: ./gradlew bundleRelease
|
||||||
|
|
||||||
|
- name: Rename APK
|
||||||
|
run: mv app/build/outputs/bundle/playStoreRelease/app-playStore-release.aab NumberHub.aab
|
||||||
|
|
||||||
|
- name: Upload Bundles 🚀
|
||||||
|
uses: r0adkll/upload-google-play@v1
|
||||||
|
with:
|
||||||
|
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_STORE_SERVICE_ACCOUNT }}
|
||||||
|
packageName: app.myzel394.numberhub
|
||||||
|
releaseFiles: NumberHub.aab
|
||||||
|
track: production
|
||||||
|
status: inProgress
|
||||||
|
userFraction: 0.5
|
1
.gitignore
vendored
@ -57,6 +57,7 @@ captures/
|
|||||||
*.jks
|
*.jks
|
||||||
*.keystore
|
*.keystore
|
||||||
keystore.config
|
keystore.config
|
||||||
|
key.properties
|
||||||
|
|
||||||
# External native build folder generated in Android Studio 2.2 and later
|
# External native build folder generated in Android Studio 2.2 and later
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
|
58
HELP.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# Help
|
||||||
|
|
||||||
|
## ⌚ Add more time zones?
|
||||||
|
|
||||||
|
This is not planned.
|
||||||
|
|
||||||
|
Each time zone has its' own set of rules:
|
||||||
|
- Offset from GMT
|
||||||
|
- Daylight saving time offset
|
||||||
|
- Date when daylight saving time is used
|
||||||
|
|
||||||
|
This data always changes.
|
||||||
|
There are 3 solutions:
|
||||||
|
|
||||||
|
### 1. Paid API service
|
||||||
|
|
||||||
|
**✅Pros:**
|
||||||
|
- Almost all time zones and cities
|
||||||
|
- Always up-to-date
|
||||||
|
|
||||||
|
**❌Cons:**
|
||||||
|
- Extra money costs
|
||||||
|
- Needs Internet, can go down, needs a caching mechanism
|
||||||
|
- The API might change and we'd need to keep it up-to-date
|
||||||
|
- Needs to be translated
|
||||||
|
|
||||||
|
### 2. Create my own API service
|
||||||
|
Pros and cons are same, except being a bit cheaper (you still need to pay).
|
||||||
|
|
||||||
|
### 3. Android's time zone provider (this is what NumberHub uses)
|
||||||
|
|
||||||
|
read more: https://source.android.com/docs/core/permissions/timezone-rules
|
||||||
|
|
||||||
|
**✅Pros:**
|
||||||
|
- Almost all time zones
|
||||||
|
- Completely for free
|
||||||
|
- No extra translations (automatically provided by the system)
|
||||||
|
- No sudden API changes
|
||||||
|
- Works offline, never goes down
|
||||||
|
|
||||||
|
**❌Cons:**
|
||||||
|
- Less cities
|
||||||
|
- Less frequent updates
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## 👩⚕️ Body Mass Index
|
||||||
|
|
||||||
|
Please note that the values displayed in the app are intended for entertainment purposes only. They can not replace professional medical advice.
|
||||||
|
|
||||||
|
Please don't use the Body Mass calculator if you are:
|
||||||
|
- Under 21 years old
|
||||||
|
- Pregnant
|
||||||
|
- Diagnosed with an eating disorder
|
||||||
|
|
||||||
|
Please contact your care provider for more information.
|
||||||
|
|
||||||
|
## 💵 Wrong Currency Rates?
|
||||||
|
Currency rates are updated daily. There's no real-time market monitoring on NumberHub.
|
45
PRIVACY.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
**Privacy Policy**
|
||||||
|
|
||||||
|
This privacy policy applies to the NumberHub app (hereby referred to as "Application") for mobile devices that was created by Myzel394 (hereby referred to as "Service Provider") as an Open Source service. This service is intended for use "AS IS".
|
||||||
|
|
||||||
|
**Third Party Access**
|
||||||
|
|
||||||
|
The service uses external services to fetch data for the user. The Service Provider does not have control over the data that is fetched from these services.
|
||||||
|
|
||||||
|
The Service Provider may disclose User Provided and Automatically Collected Information:
|
||||||
|
|
||||||
|
* as required by law, such as to comply with a subpoena, or similar legal process;
|
||||||
|
* when they believe in good faith that disclosure is necessary to protect their rights, protect your safety or the safety of others, investigate fraud, or respond to a government request;
|
||||||
|
* with their trusted services providers who work on their behalf, do not have an independent use of the information we disclose to them, and have agreed to adhere to the rules set forth in this privacy statement.
|
||||||
|
|
||||||
|
**Opt-Out Rights**
|
||||||
|
|
||||||
|
You can stop all collection of information by the Application easily by uninstalling it. You may use the standard uninstall processes as may be available as part of your mobile device or via the mobile application marketplace or network.
|
||||||
|
|
||||||
|
**Children**
|
||||||
|
|
||||||
|
The Service Provider does not use the Application to knowingly solicit data from or market to children under the age of 13.
|
||||||
|
|
||||||
|
The Service Provider does not knowingly collect personally identifiable information from children. The Service Provider encourages all children to never submit any personally identifiable information through the Application and/or Services. The Service Provider encourage parents and legal guardians to monitor their children's Internet usage and to help enforce this Policy by instructing their children never to provide personally identifiable information through the Application and/or Services without their permission. If you have reason to believe that a child has provided personally identifiable information to the Service Provider through the Application and/or Services, please contact the Service Provider (google-play.29k1a@aleeas.com) so that they will be able to take the necessary actions. You must also be at least 16 years of age to consent to the processing of your personally identifiable information in your country (in some countries we may allow your parent or guardian to do so on your behalf).
|
||||||
|
|
||||||
|
**Security**
|
||||||
|
|
||||||
|
The Service Provider is concerned about safeguarding the confidentiality of your information. The Service Provider provides physical, electronic, and procedural safeguards to protect information the Service Provider processes and maintains.
|
||||||
|
|
||||||
|
**Changes**
|
||||||
|
|
||||||
|
This Privacy Policy may be updated from time to time for any reason. The Service Provider will notify you of any changes to the Privacy Policy by updating this page with the new Privacy Policy. You are advised to consult this Privacy Policy regularly for any changes, as continued use is deemed approval of all changes.
|
||||||
|
|
||||||
|
This privacy policy is effective as of 2024-05-15
|
||||||
|
|
||||||
|
**Your Consent**
|
||||||
|
|
||||||
|
By using the Application, you are consenting to the processing of your information as set forth in this Privacy Policy now and as amended by us.
|
||||||
|
|
||||||
|
**Contact Us**
|
||||||
|
|
||||||
|
If you have any questions regarding privacy while using the Application, or have questions about the practices, please contact the Service Provider via email at google-play.29k1a@aleeas.com.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
This privacy policy page was generated by [App Privacy Policy Generator](https://app-privacy-policy-generator.nisrulz.com/)
|
47
README.md
@ -1,5 +1,11 @@
|
|||||||
|
# NumberHub
|
||||||
|
➗ Your Hub for ✖️ Math / 💲 Currency rates / 📆 Date calculations / ⌚ Time zones
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This app was originally created by [sadellie](https://github.com/sadellie).
|
||||||
|
Unfortunately, it has been archived on March 1st, 2024 (https://github.com/sadellie/unitto) without any notice or explanation. Since there has been no activity from sadellie on GitHub since then, I guess they are not actively working on projects anymore. I will maintain this app, but I do not plan to add new features. I don't have enough time to do that, but you are welcome to contribute. I will review and merge your pull requests.
|
||||||
|
|
||||||
<p align="middle">
|
<p align="middle">
|
||||||
<img src="./fastlane/metadata/android/en-US/images/featureGraphic.png" width="97%" />
|
|
||||||
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/slide1.png" width="19%" />
|
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/slide1.png" width="19%" />
|
||||||
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/slide2.png" width="19%" />
|
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/slide2.png" width="19%" />
|
||||||
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/slide3.png" width="19%" />
|
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/slide3.png" width="19%" />
|
||||||
@ -7,14 +13,35 @@
|
|||||||
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/slide5.png" width="19%" />
|
<img src="./fastlane/metadata/android/en-US/images/phoneScreenshots/slide5.png" width="19%" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Notice
|
# Download NumberHub
|
||||||
|
|
||||||
This app was originally created by [sadellie](https://github.com/sadellie).
|
[<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)
|
||||||
Unfortunately, it has been archived on March 1st, 2024 (https://github.com/sadellie/unitto)
|
[<img src="readme_content/izzyondroid-badge.png" alt="Get it on IzzyOnDroid" height="80">](https://apt.izzysoft.de/fdroid/index/apk/app.myzel394.numberhub)
|
||||||
without any notice or explanation.
|
[<img src="readme_content/github-badge.png" alt="Get it on GitHub" height="80">](https://github.com/Myzel394/NumberHub/releases)
|
||||||
Since there has been no activity from sadellie on GitHub since then, I guess
|
[<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//)
|
||||||
they are not actively working on projects anymore.
|
|
||||||
|
|
||||||
I will maintain this app, but I do not plan to add new features.
|
# Support NumberHub
|
||||||
I don't have enough time to do that, but you are welcome to contribute.
|
|
||||||
I will review and merge your pull requests.
|
You can support NumberHub in various ways:
|
||||||
|
|
||||||
|
## Contribute to the project
|
||||||
|
|
||||||
|
Add a new feature or fix bugs.
|
||||||
|
|
||||||
|
## Add translations
|
||||||
|
|
||||||
|
To add a translation, update the strings in `core/base/src/main/res/LANG/strings.xml` and open a PR
|
||||||
|
|
||||||
|
## Donate
|
||||||
|
|
||||||
|
It might sound crazy, but if you would just donate 1$, it would totally mean to world to me, since
|
||||||
|
it's a really small amount and if everyone did that, I can totally focus on NumberHub
|
||||||
|
and my other open source projects. :)
|
||||||
|
|
||||||
|
You can donate via [GitHub Sponsors](https://github.com/sponsors/Myzel394)
|
||||||
|
or via [crypto currencies](https://github.com/Myzel394/contact-me?tab=readme-ov-file#donations).
|
||||||
|
|
||||||
|
## Help
|
||||||
|
For help with the app see [HELP](HELP.md)
|
||||||
|
|
||||||
|
For details about the permissions used in the app see [SECURITY](SECURITY.md)
|
||||||
|
38
SECURITY.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Permissions
|
||||||
|
|
||||||
|
The following permissions are used in the NumberHub app
|
||||||
|
|
||||||
|
### `com.sadellie.numberhub.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION`
|
||||||
|
|
||||||
|
Read (boring): https://developer.android.com/about/versions/14/behavior-changes-14#runtime-receivers-exported
|
||||||
|
|
||||||
|
### `android.permission.INTERNET`
|
||||||
|
|
||||||
|
Used in **Unit Converter** to update currency rates. Requests are made only when you select a currency unit.
|
||||||
|
|
||||||
|
### `android.permission.ACCESS_NETWORK_STATE`
|
||||||
|
|
||||||
|
Used in Unit Converter as a callback. Retries to update currency rates if there was an error (no network, for example) and the Internet connection is back.
|
||||||
|
|
||||||
|
### `android.permission.WAKE_LOCK`
|
||||||
|
|
||||||
|
Not used explicitly. Added automatically by Widget feature.
|
||||||
|
|
||||||
|
### `android.permission.RECEIVE_BOOT_COMPLETED`
|
||||||
|
|
||||||
|
Not used explicitly. Added automatically by Widget feature.
|
||||||
|
|
||||||
|
### `android.permission.FOREGROUND_SERVICE`
|
||||||
|
|
||||||
|
Not used explicitly. Added automatically by Widget feature.
|
||||||
|
|
||||||
|
# F-Droid Anti-Features
|
||||||
|
|
||||||
|
These may appear on F-Droid app page
|
||||||
|
|
||||||
|
### Non-free network service
|
||||||
|
|
||||||
|
Non-free means that you can't host the given service on your machine.
|
||||||
|
|
||||||
|
The app uses [Free Currency Rates API by fawazahmed0](https://github.com/fawazahmed0/exchange-api). Requests are send to `cdn.jsdelivr.net`.
|
||||||
|
|
@ -1,3 +1,5 @@
|
|||||||
|
import java.util.Properties
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unitto is a calculator for Android
|
* Unitto is a calculator for Android
|
||||||
* Copyright (c) 2023-2024 Elshan Agaev
|
* Copyright (c) 2023-2024 Elshan Agaev
|
||||||
@ -31,6 +33,18 @@ android {
|
|||||||
namespace = "app.myzel394.numberhub"
|
namespace = "app.myzel394.numberhub"
|
||||||
compileSdk = 34
|
compileSdk = 34
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
create("release") {
|
||||||
|
val properties = Properties().apply {
|
||||||
|
load(rootProject.file("key.properties").reader())
|
||||||
|
}
|
||||||
|
storeFile = File(properties.getProperty("storeFile"))
|
||||||
|
storePassword = properties.getProperty("storePassword")
|
||||||
|
keyPassword = properties.getProperty("keyPassword")
|
||||||
|
keyAlias = properties.getProperty("keyAlias")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "app.myzel394.numberhub"
|
applicationId = "app.myzel394.numberhub"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
@ -42,6 +56,7 @@ android {
|
|||||||
"en-rGB",
|
"en-rGB",
|
||||||
"de",
|
"de",
|
||||||
"es",
|
"es",
|
||||||
|
"fa",
|
||||||
"fr",
|
"fr",
|
||||||
"hu",
|
"hu",
|
||||||
"in",
|
"in",
|
||||||
@ -72,11 +87,21 @@ android {
|
|||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
"proguard-rules.pro"
|
"proguard-rules.pro"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
signingConfig = signingConfigs.getByName("release")
|
||||||
}
|
}
|
||||||
create("benchmark") {
|
create("benchmark") {
|
||||||
initWith(buildTypes.getByName("release"))
|
initWith(getByName("debug"))
|
||||||
matchingFallbacks.add("release")
|
|
||||||
signingConfig = signingConfigs.getByName("debug")
|
signingConfig = signingConfigs.getByName("debug")
|
||||||
|
isDebuggable = false
|
||||||
|
isMinifyEnabled = true
|
||||||
|
isShrinkResources = true
|
||||||
|
applicationIdSuffix = ""
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro"
|
||||||
|
)
|
||||||
|
matchingFallbacks.add("release")
|
||||||
// Only use benchmark proguard rules
|
// Only use benchmark proguard rules
|
||||||
proguardFiles("benchmark-rules.pro")
|
proguardFiles("benchmark-rules.pro")
|
||||||
isMinifyEnabled = true
|
isMinifyEnabled = true
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="Fuck You"
|
android:label="NumberHubber (Debug)"
|
||||||
tools:ignore="MissingApplicationIcon"
|
tools:ignore="MissingApplicationIcon"
|
||||||
tools:replace="android:label" />
|
tools:replace="android:label" />
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ Used in this dialog window. Should be short -->
|
|||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
||||||
<string name="select_time_label">Zeit auswählen</string>
|
<string name="select_time_label">Zeit auswählen</string>
|
||||||
<string name="settings_about_unitto">Über Unitto</string>
|
<string name="settings_about_unitto">Über NumberHub</string>
|
||||||
<string name="settings_about_unitto_support">Mehr über die App erfahren</string>
|
<string name="settings_about_unitto_support">Mehr über die App erfahren</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
||||||
|
@ -83,7 +83,7 @@ Used in this dialog window. Should be short -->
|
|||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
||||||
<string name="select_time_label">Select time</string>
|
<string name="select_time_label">Select time</string>
|
||||||
<string name="settings_about_unitto">About Unitto</string>
|
<string name="settings_about_unitto">About NumberHub</string>
|
||||||
<string name="settings_about_unitto_support">Learn about the app</string>
|
<string name="settings_about_unitto_support">Learn about the app</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
||||||
|
@ -203,7 +203,7 @@ Used in this dialog window. Should be short -->
|
|||||||
https://s3.eu-west-1.amazonaws.com/po-pub/i/1oIHPj16krI0jyLmg4JaP2mk.png -->
|
https://s3.eu-west-1.amazonaws.com/po-pub/i/1oIHPj16krI0jyLmg4JaP2mk.png -->
|
||||||
<!-- Screen readers (accessibility) -->
|
<!-- Screen readers (accessibility) -->
|
||||||
<string name="selected_item">Item seleccionado</string>
|
<string name="selected_item">Item seleccionado</string>
|
||||||
<string name="settings_about_unitto">Acerca de Unitto</string>
|
<string name="settings_about_unitto">Acerca de NumberHub</string>
|
||||||
<string name="settings_about_unitto_support">Más información sobre la app</string>
|
<string name="settings_about_unitto_support">Más información sobre la app</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
||||||
|
1290
core/base/src/main/res/values-fa/strings.xml
Normal file
@ -18,15 +18,37 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<resources>
|
<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_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_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="calculator_title">Calculatrice</string>
|
||||||
<string name="cancel_label">Annuler</string>
|
<string name="cancel_label">Annuler</string>
|
||||||
<string name="checked_filter_description">Filtre vérifié</string>
|
<string name="checked_filter_description">Filtre vérifié</string>
|
||||||
<string name="clear_history_label">Vider l\'historique</string>
|
<string name="clear_history_label">Vider l\'historique</string>
|
||||||
<string name="clear_input_description">Effacer l\'entrée</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="click_to_try_again_label">Cliquez pour réessayer</string>
|
||||||
<string name="comma">Virgule</string>
|
<string name="comma">Virgule</string>
|
||||||
<string name="converter_favorite_button_description">Ajouter ou supprimer une unité des favoris</string>
|
<string name="converter_favorite_button_description">Ajouter ou supprimer une unité des favoris</string>
|
||||||
@ -36,7 +58,7 @@
|
|||||||
<string name="converter_search_bar_placeholder">Rechercher des unités</string>
|
<string name="converter_search_bar_placeholder">Rechercher des unités</string>
|
||||||
<string name="converter_swap_units_description">Échanger les unités</string>
|
<string name="converter_swap_units_description">Échanger les unités</string>
|
||||||
<string name="copied_label">%1$s! copié</string>
|
<string name="copied_label">%1$s! copié</string>
|
||||||
<string name="date_calculator_add">Ajouter</string>
|
<string name="date_calculator_add">Ajouter </string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/33QTn2NVrjJT772cBDFRqSMH.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/33QTn2NVrjJT772cBDFRqSMH.png -->
|
||||||
<string name="date_calculator_days">Jours</string>
|
<string name="date_calculator_days">Jours</string>
|
||||||
@ -52,7 +74,7 @@
|
|||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/33QTn2NVrjJT772cBDFRqSMH.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/33QTn2NVrjJT772cBDFRqSMH.png -->
|
||||||
<string name="date_calculator_months">Mois</string>
|
<string name="date_calculator_months">Mois</string>
|
||||||
<string name="date_calculator_start">Début</string>
|
<string name="date_calculator_start">Début</string>
|
||||||
<string name="date_calculator_subtract">Soustraire</string>
|
<string name="date_calculator_subtract"> Soustraire</string>
|
||||||
<string name="date_calculator_title">Calculateur de date</string>
|
<string name="date_calculator_title">Calculateur de date</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/33QTn2NVrjJT772cBDFRqSMH.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/33QTn2NVrjJT772cBDFRqSMH.png -->
|
||||||
@ -61,13 +83,11 @@
|
|||||||
<string name="drop_down_description">Ouvrir ou fermer le menu déroulant</string>
|
<string name="drop_down_description">Ouvrir ou fermer le menu déroulant</string>
|
||||||
<string name="enabled_label">Activé</string>
|
<string name="enabled_label">Activé</string>
|
||||||
<string name="error_label">Erreur</string>
|
<string name="error_label">Erreur</string>
|
||||||
<string name="hello_label">Bonjour!</string>
|
<string name="hello_label">Bonjour !</string>
|
||||||
<string name="loading_label">Chargement…</string>
|
<string name="loading_label">Chargement…</string>
|
||||||
<string name="navigate_up_description">Naviguer vers le haut</string>
|
<string name="navigate_up_description">Naviguer vers le haut</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/9lSfdkfKShwyQFEF4nvbVaIb.jpg
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/9lSfdkfKShwyQFEF4nvbVaIb.jpg Used in this dialog window. Should be short -->
|
||||||
|
|
||||||
Used in this dialog window. Should be short -->
|
|
||||||
<string name="next_label">Suite</string>
|
<string name="next_label">Suite</string>
|
||||||
<string name="no_results_description">Résultat de recherche vide</string>
|
<string name="no_results_description">Résultat de recherche vide</string>
|
||||||
<string name="no_results_label">Aucun résultat trouvé</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 -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
||||||
<string name="select_time_label">Choisir le temps</string>
|
<string name="select_time_label">Choisir le temps</string>
|
||||||
<string name="settings_about_unitto">À propos d\'Unitto</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_about_unitto_support">En savoir plus sur l\'application</string>
|
||||||
<string name="settings_additional">Additional</string>
|
<string name="settings_additional">Paramètres supplémentaires</string>
|
||||||
<string name="settings_amoled_dark">AMOLED Noir</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_amoled_dark_support">Utiliser un fond noir pour les thèmes sombres</string>
|
||||||
<string name="settings_auto">Auto</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_calculator_support">Vue historique</string>
|
||||||
<string name="settings_clear_cache">Effacer le cache</string>
|
<string name="settings_clear_cache">Effacer le cache</string>
|
||||||
<string name="settings_color_scheme">Palette de couleurs</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_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_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_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_currency_rates_note_title">Taux de conversion faux ?</string>
|
||||||
<string name="settings_dark_mode">Sombre</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_disable_unit_group_description">Désactiver le groupe d\'unités</string>
|
||||||
<string name="settings_display">Affichage</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">Couleurs dynamiques</string>
|
||||||
<string name="settings_dynamic_colors_support">Utilisez les couleurs de votre fond d\'écran</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_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_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_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>
|
<string name="settings_formatting_preview">Aperçu (cliquez pour changer)</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/Gj9ZCNPXIfKddDQgccvboVFz.jpg
|
<!-- 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. -->
|
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_formatting_support">Précision et format des nombres</string>
|
||||||
<string name="settings_language">Langue</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_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_middle_zero_support">Intervertir les boutons zéro et décimal</string>
|
||||||
<string name="settings_note">Note</string>
|
<string name="settings_note">Note</string>
|
||||||
<string name="settings_partial_history_view">Vue partielle de l\'historique</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_max">%1$s (Max)</string>
|
||||||
<string name="settings_precision_support">Nombre de décimales</string>
|
<string name="settings_precision_support">Nombre de décimales</string>
|
||||||
<string name="settings_privacy_policy">Politique de confidentialité</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_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_color">Couleur sélectionnée</string>
|
||||||
<string name="settings_selected_style">Style sélectionné</string>
|
<string name="settings_selected_style">Style sélectionné</string>
|
||||||
<string name="settings_separator">Séparateur</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 -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/r1VikAn70eXQP4da2hrntTGQ.jpg -->
|
||||||
<!-- Option name to use system default setting -->
|
<!-- Option name to use system default setting -->
|
||||||
<string name="settings_system">Système</string>
|
<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_terms_and_conditions">Termes et conditions</string>
|
||||||
<string name="settings_third_party_licenses">Licences tierces</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_title">Paramètres</string>
|
||||||
<string name="settings_translate_app">Traduire cette app</string>
|
<string name="settings_translate_app">Traduire cette app</string>
|
||||||
<string name="settings_translate_app_support">Rejoignez le projet POEditor pour aider</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_units_sorting_support">Changer l\'ordre des unités</string>
|
||||||
<string name="settings_version_name">Nom de la version</string>
|
<string name="settings_version_name">Nom de la version</string>
|
||||||
<string name="settings_vibrations">Vibrations</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="settings_view_source_code">Voir le code source</string>
|
||||||
<string name="time_zone_add_title">Ajouter un fuseau horaire</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="time_zone_title">Fuseaux horaires</string>
|
||||||
<string name="tomorrow">Demain</string>
|
<string name="tomorrow">Demain</string>
|
||||||
<string name="unit_acre">Acre</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_cubic_millimeter_short">mm³</string>
|
||||||
<string name="unit_currency_ada">Cardano</string>
|
<string name="unit_currency_ada">Cardano</string>
|
||||||
<string name="unit_currency_aed">Dirham des Émirats arabes unis</string>
|
<string name="unit_currency_aed">Dirham des Émirats arabes unis</string>
|
||||||
<string name="unit_currency_afn">Afghan afghani</string>
|
<string name="unit_currency_afn">Afghani</string>
|
||||||
<string name="unit_currency_all">Albanian lek</string>
|
<string name="unit_currency_all">Lek</string>
|
||||||
<string name="unit_currency_amd">Armenian dram</string>
|
<string name="unit_currency_amd">Dram</string>
|
||||||
<string name="unit_currency_ang">Netherlands Antillean Guilder</string>
|
<string name="unit_currency_ang">Florin des Antilles néerlandaises</string>
|
||||||
<string name="unit_currency_aoa">Angolan kwanza</string>
|
<string name="unit_currency_aoa">Kwanza</string>
|
||||||
<string name="unit_currency_ars">Argentine peso</string>
|
<string name="unit_currency_ars">Peso argentin</string>
|
||||||
<string name="unit_currency_aud">Australian dollar</string>
|
<string name="unit_currency_aud">Dollar australien</string>
|
||||||
<string name="unit_currency_awg">Aruban florin</string>
|
<string name="unit_currency_awg">Florin arubais</string>
|
||||||
<string name="unit_currency_azn">Azerbaijani manat</string>
|
<string name="unit_currency_azn">Manat azerbaïdjanais</string>
|
||||||
<string name="unit_currency_bam">Bosnia-Herzegovina Convertible Mark</string>
|
<string name="unit_currency_bam">Mark convertible de Bosnie-Herzégovine</string>
|
||||||
<string name="unit_currency_bbd">Bajan dollar</string>
|
<string name="unit_currency_bbd">Dollar barbadien</string>
|
||||||
<string name="unit_currency_bdt">Bangladeshi taka</string>
|
<string name="unit_currency_bdt">Taka</string>
|
||||||
<string name="unit_currency_bgn">Bulgarian lev</string>
|
<string name="unit_currency_bgn">Lev bulgare</string>
|
||||||
<string name="unit_currency_bhd">Bahraini dinar</string>
|
<string name="unit_currency_bhd">Dinar bahreïni</string>
|
||||||
<string name="unit_currency_bif">Burundian Franc</string>
|
<string name="unit_currency_bif">Franc burundais</string>
|
||||||
<string name="unit_currency_bmd">Bermudan dollar</string>
|
<string name="unit_currency_bmd">Dollar bermudien</string>
|
||||||
<string name="unit_currency_bnd">Brunei dollar</string>
|
<string name="unit_currency_bnd">Dollar de Brunei</string>
|
||||||
<string name="unit_currency_bob">Bolivian boliviano</string>
|
<string name="unit_currency_bob">Boliviano</string>
|
||||||
<string name="unit_currency_brl">Brazilian real</string>
|
<string name="unit_currency_brl">Réal brésilien</string>
|
||||||
<string name="unit_currency_bsd">Bahamian dollar</string>
|
<string name="unit_currency_bsd">Dollar bahaméen</string>
|
||||||
<string name="unit_currency_btn">Bhutan currency</string>
|
<string name="unit_currency_btn">Ngultrum</string>
|
||||||
<string name="unit_currency_bwp">Botswanan Pula</string>
|
<string name="unit_currency_bwp">Pula</string>
|
||||||
<string name="unit_currency_byn">New Belarusian Ruble</string>
|
<string name="unit_currency_byn">Nouveau rouble biélorusse</string>
|
||||||
<string name="unit_currency_byr">Belarusian Ruble</string>
|
<string name="unit_currency_byr">Rouble biélorusse</string>
|
||||||
<string name="unit_currency_bzd">Belize dollar</string>
|
<string name="unit_currency_bzd">Dollar bélizien</string>
|
||||||
<string name="unit_currency_cad">Canadian dollar</string>
|
<string name="unit_currency_cad">Dollar canadien</string>
|
||||||
<string name="unit_currency_cdf">Congolese franc</string>
|
<string name="unit_currency_cdf">Franc congolais</string>
|
||||||
<string name="unit_currency_chf">Swiss franc</string>
|
<string name="unit_currency_chf">Franc suisse</string>
|
||||||
<string name="unit_currency_clf">Chilean Unit of Account (UF)</string>
|
<string name="unit_currency_clf">Chilean Unit of Account (UF)</string>
|
||||||
<string name="unit_currency_clp">Chilean peso</string>
|
<string name="unit_currency_clp">Peso chilien</string>
|
||||||
<string name="unit_currency_cny">Chinese Yuan</string>
|
<string name="unit_currency_cny">Yuan</string>
|
||||||
<string name="unit_currency_cop">Colombian peso</string>
|
<string name="unit_currency_cop">Peso colombien</string>
|
||||||
<string name="unit_currency_crc">Costa Rican Colón</string>
|
<string name="unit_currency_crc">Colón costaricien</string>
|
||||||
<string name="unit_currency_cuc">Cuban convertible peso</string>
|
<string name="unit_currency_cuc">Peso cubain convertible</string>
|
||||||
<string name="unit_currency_cup">Cuban Peso</string>
|
<string name="unit_currency_cup">Peso cubain</string>
|
||||||
<string name="unit_currency_cve">Cape Verdean escudo</string>
|
<string name="unit_currency_cve">Escudo cap-verdien</string>
|
||||||
<string name="unit_currency_czk">Czech koruna</string>
|
<string name="unit_currency_czk">Couronne tchèque</string>
|
||||||
<string name="unit_currency_dai">Dai</string>
|
<string name="unit_currency_dai">Dai</string>
|
||||||
<string name="unit_currency_djf">Djiboutian franc</string>
|
<string name="unit_currency_djf">Franc Djibouti</string>
|
||||||
<string name="unit_currency_dkk">Danish krone</string>
|
<string name="unit_currency_dkk">Couronne danoise</string>
|
||||||
<string name="unit_currency_dop">Dominican peso</string>
|
<string name="unit_currency_dop">Peso dominicain</string>
|
||||||
<string name="unit_currency_dzd">Algerian dinar</string>
|
<string name="unit_currency_dzd">Dinar algérien</string>
|
||||||
<string name="unit_currency_egp">Egyptian pound</string>
|
<string name="unit_currency_egp">Livre égyptienne</string>
|
||||||
<string name="unit_currency_ern">Eritrean nakfa</string>
|
<string name="unit_currency_ern">Nakfa érythréen</string>
|
||||||
<string name="unit_currency_etb">Ethiopian birr</string>
|
<string name="unit_currency_etb">Birr éthiopien</string>
|
||||||
<string name="unit_currency_eur">Euro</string>
|
<string name="unit_currency_eur">Euro</string>
|
||||||
<string name="unit_currency_fjd">Fijian dollar</string>
|
<string name="unit_currency_fjd">Dollar fidjien</string>
|
||||||
<string name="unit_currency_fkp">Falkland Islands pound</string>
|
<string name="unit_currency_fkp">Livre des îles Malouines</string>
|
||||||
<string name="unit_currency_gbp">Pound sterling</string>
|
<string name="unit_currency_gbp">Livre sterling</string>
|
||||||
<string name="unit_currency_gel">Georgian lari</string>
|
<string name="unit_currency_gel">Lari géorgien</string>
|
||||||
<string name="unit_currency_ghs">Ghanaian cedi</string>
|
<string name="unit_currency_ghs">Cedi ghanéen</string>
|
||||||
<string name="unit_currency_gip">Gibraltar pound</string>
|
<string name="unit_currency_gip">Livre de Gibraltar</string>
|
||||||
<string name="unit_currency_gmd">Gambian dalasi</string>
|
<string name="unit_currency_gmd">Dalasi gambien</string>
|
||||||
<string name="unit_currency_gnf">Guinean franc</string>
|
<string name="unit_currency_gnf">Franc guinéen</string>
|
||||||
<string name="unit_currency_gtq">Guatemalan quetzal</string>
|
<string name="unit_currency_gtq">Quetzal guatémaltèque</string>
|
||||||
<string name="unit_currency_gyd">Guyanaese Dollar</string>
|
<string name="unit_currency_gyd">Dollar guyanien</string>
|
||||||
<string name="unit_currency_hkd">Hong Kong dollar</string>
|
<string name="unit_currency_hkd">Dollar de Hong Kong</string>
|
||||||
<string name="unit_currency_hnl">Honduran lempira</string>
|
<string name="unit_currency_hnl">Lempira hondurien</string>
|
||||||
<string name="unit_currency_hrk">Croatian kuna</string>
|
<string name="unit_currency_hrk">Kuna croate</string>
|
||||||
<string name="unit_currency_htg">Haitian gourde</string>
|
<string name="unit_currency_htg">Gourde haïtienne</string>
|
||||||
<string name="unit_currency_huf">Hungarian forint</string>
|
<string name="unit_currency_huf">Forint hongrois</string>
|
||||||
<string name="unit_currency_idr">Indonesian rupiah</string>
|
<string name="unit_currency_idr">Roupie indonésienne</string>
|
||||||
<string name="unit_currency_ils">Israeli New Shekel</string>
|
<string name="unit_currency_ils">Shekel israélien</string>
|
||||||
<string name="unit_currency_inr">Indian rupee</string>
|
<string name="unit_currency_inr">Roupie indienne</string>
|
||||||
<string name="unit_currency_iqd">Iraqi dinar</string>
|
<string name="unit_currency_iqd">Dinar irakien</string>
|
||||||
<string name="unit_currency_irr">Iranian rial</string>
|
<string name="unit_currency_irr">Rial iranien</string>
|
||||||
<string name="unit_currency_isk">Icelandic króna</string>
|
<string name="unit_currency_isk">Couronne islandaise</string>
|
||||||
<string name="unit_currency_jep">Jersey Pound</string>
|
<string name="unit_currency_jep">Livre de Jersey</string>
|
||||||
<string name="unit_currency_jmd">Jamaican dollar</string>
|
<string name="unit_currency_jmd">Dollar jamaïcain</string>
|
||||||
<string name="unit_currency_jod">Jordanian dinar</string>
|
<string name="unit_currency_jod">Dinar jordanien</string>
|
||||||
<string name="unit_currency_jpy">Japanese yen</string>
|
<string name="unit_currency_jpy">Yen japonais</string>
|
||||||
<string name="unit_currency_kes">Kenyan shilling</string>
|
<string name="unit_currency_kes">Shilling kényan</string>
|
||||||
<string name="unit_currency_kgs">Kyrgystani Som</string>
|
<string name="unit_currency_kgs">Som kirghize</string>
|
||||||
<string name="unit_currency_khr">Cambodian riel</string>
|
<string name="unit_currency_khr">Riel cambodgien</string>
|
||||||
<string name="unit_currency_kmf">Comorian franc</string>
|
<string name="unit_currency_kmf">Franc comorien</string>
|
||||||
<string name="unit_currency_kpw">North Korean won</string>
|
<string name="unit_currency_kpw">Won nord-coréen</string>
|
||||||
<string name="unit_currency_krw">South Korean won</string>
|
<string name="unit_currency_krw">Won sud-coréen</string>
|
||||||
<string name="unit_currency_kwd">Kuwaiti dinar</string>
|
<string name="unit_currency_kwd">Dinar koweïtien</string>
|
||||||
<string name="unit_currency_kyd">Cayman Islands dollar</string>
|
<string name="unit_currency_kyd">Dollar des îles Caïmans</string>
|
||||||
<string name="unit_currency_kzt">Kazakhstani tenge</string>
|
<string name="unit_currency_kzt">Tenge kazakh</string>
|
||||||
<string name="unit_currency_lak">Laotian Kip</string>
|
<string name="unit_currency_lak">Kip laotien</string>
|
||||||
<string name="unit_currency_lbp">Lebanese pound</string>
|
<string name="unit_currency_lbp">Livre libanaise</string>
|
||||||
<string name="unit_currency_lkr">Sri Lankan rupee</string>
|
<string name="unit_currency_lkr">Roupie srilankaise</string>
|
||||||
<string name="unit_currency_lrd">Liberian dollar</string>
|
<string name="unit_currency_lrd">Dollar libérien</string>
|
||||||
<string name="unit_currency_lsl">Lesotho loti</string>
|
<string name="unit_currency_lsl">Loti lesothan</string>
|
||||||
<string name="unit_currency_ltl">Lithuanian litas</string>
|
<string name="unit_currency_ltl">Litas lituanien</string>
|
||||||
<string name="unit_currency_lvl">Latvian lats</string>
|
<string name="unit_currency_lvl">Lats letton</string>
|
||||||
<string name="unit_currency_lyd">Libyan dinar</string>
|
<string name="unit_currency_lyd">Dinar libyen</string>
|
||||||
<string name="unit_currency_mad">Moroccan dirham</string>
|
<string name="unit_currency_mad">Dirham marocain</string>
|
||||||
<string name="unit_currency_mdl">Moldovan leu</string>
|
<string name="unit_currency_mdl">Leu moldave</string>
|
||||||
<string name="unit_currency_mga">Malagasy ariary</string>
|
<string name="unit_currency_mga">Ariary malgache</string>
|
||||||
<string name="unit_currency_mkd">Macedonian denar</string>
|
<string name="unit_currency_mkd">Denar macédonien</string>
|
||||||
<string name="unit_currency_mmk">Myanmar Kyat</string>
|
<string name="unit_currency_mmk">Kyat birman</string>
|
||||||
<string name="unit_currency_mnt">Mongolian tugrik</string>
|
<string name="unit_currency_mnt">Tugrik mongol</string>
|
||||||
<string name="unit_currency_mop">Macanese pataca</string>
|
<string name="unit_currency_mop">Pataca macanaise</string>
|
||||||
<string name="unit_currency_mro">Mauritanian ouguiya</string>
|
<string name="unit_currency_mro">Ouguiya mauritanien</string>
|
||||||
<string name="unit_currency_mur">Mauritian rupee</string>
|
<string name="unit_currency_mur">Roupie mauricienne</string>
|
||||||
<string name="unit_currency_mvr">Maldivian rufiyaa</string>
|
<string name="unit_currency_mvr">Rufiyaa maldivienne</string>
|
||||||
<string name="unit_currency_mwk">Malawian kwacha</string>
|
<string name="unit_currency_mwk">Kwacha malawien</string>
|
||||||
<string name="unit_currency_mxn">Mexican peso</string>
|
<string name="unit_currency_mxn">Peso mexicain</string>
|
||||||
<string name="unit_currency_myr">Malaysian ringgit</string>
|
<string name="unit_currency_myr">Ringgit malaisien</string>
|
||||||
<string name="unit_currency_mzn">Mozambican Metical</string>
|
<string name="unit_currency_mzn">Metical mozambicain</string>
|
||||||
<string name="unit_currency_nad">Namibian dollar</string>
|
<string name="unit_currency_nad">Dollar namibien</string>
|
||||||
<string name="unit_currency_ngn">Nigerian naira</string>
|
<string name="unit_currency_ngn">Naira nigérian</string>
|
||||||
<string name="unit_currency_nio">Nicaraguan córdoba</string>
|
<string name="unit_currency_nio">Córdoba nicaraguayen</string>
|
||||||
<string name="unit_currency_nok">Norwegian krone</string>
|
<string name="unit_currency_nok">Couronne norvégienne</string>
|
||||||
<string name="unit_currency_npr">Nepalese rupee</string>
|
<string name="unit_currency_npr">Roupie népalaise</string>
|
||||||
<string name="unit_currency_nzd">New Zealand dollar</string>
|
<string name="unit_currency_nzd">Dollar néo-zélandais</string>
|
||||||
<string name="unit_currency_omr">Omani rial</string>
|
<string name="unit_currency_omr">Rial omanais</string>
|
||||||
<string name="unit_currency_pab">Panamanian balboa</string>
|
<string name="unit_currency_pab">Balboa panaméen</string>
|
||||||
<string name="unit_currency_pen">Sol</string>
|
<string name="unit_currency_pen">Sol péruvien</string>
|
||||||
<string name="unit_currency_pgk">Papua New Guinean kina</string>
|
<string name="unit_currency_pgk">Kina papouasien</string>
|
||||||
<string name="unit_currency_php">Philippine peso</string>
|
<string name="unit_currency_php">Peso philippin</string>
|
||||||
<string name="unit_currency_pkr">Pakistani rupee</string>
|
<string name="unit_currency_pkr">Roupie pakistanaise</string>
|
||||||
<string name="unit_currency_pln">Poland złoty</string>
|
<string name="unit_currency_pln">Złoty polonais</string>
|
||||||
<string name="unit_currency_pyg">Paraguayan guarani</string>
|
<string name="unit_currency_pyg">Guaraní paraguayen</string>
|
||||||
<string name="unit_currency_qar">Qatari Rial</string>
|
<string name="unit_currency_qar">Riyal qatari</string>
|
||||||
<string name="unit_currency_ron">Romanian leu</string>
|
<string name="unit_currency_ron">Leu roumain</string>
|
||||||
<string name="unit_currency_rsd">Serbian dinar</string>
|
<string name="unit_currency_rsd">Dinar serbe</string>
|
||||||
<string name="unit_currency_rub">Russian ruble</string>
|
<string name="unit_currency_rub">Rouble russe</string>
|
||||||
<string name="unit_currency_rwf">Rwandan Franc</string>
|
<string name="unit_currency_rwf">Franc rwandais</string>
|
||||||
<string name="unit_currency_sar">Saudi riyal</string>
|
<string name="unit_currency_sar">Riyal saoudien</string>
|
||||||
<string name="unit_currency_sbd">Solomon Islands dollar</string>
|
<string name="unit_currency_sbd">Dollar des îles Salomon</string>
|
||||||
<string name="unit_currency_scr">Seychellois rupee</string>
|
<string name="unit_currency_scr">Roupie seychelloise</string>
|
||||||
<string name="unit_currency_sdg">Sudanese pound</string>
|
<string name="unit_currency_sdg">Livre soudanaise</string>
|
||||||
<string name="unit_currency_sek">Swedish krona</string>
|
<string name="unit_currency_sek">Couronne suédoise</string>
|
||||||
<string name="unit_currency_sgd">Singapore dollar</string>
|
<string name="unit_currency_sgd">Dollar de Singapour</string>
|
||||||
<string name="unit_currency_shib">Shiba Inu</string>
|
<string name="unit_currency_shib">Shiba Inu</string>
|
||||||
<string name="unit_currency_shp">Saint Helena pound</string>
|
<string name="unit_currency_shp">Livre de Sainte-Hélène</string>
|
||||||
<string name="unit_currency_sll">Sierra Leonean leone</string>
|
<string name="unit_currency_sll">Leone sierra-léonais</string>
|
||||||
<string name="unit_currency_sos">Somali shilling</string>
|
<string name="unit_currency_sos">Shilling somalien</string>
|
||||||
<string name="unit_currency_srd">Surinamese dollar</string>
|
<string name="unit_currency_srd">Dollar surinamais</string>
|
||||||
<string name="unit_currency_std">São Tomé and Príncipe Dobra (pre-2018)</string>
|
<string name="unit_currency_std">Dobra santoméen (avant 2018)</string>
|
||||||
<string name="unit_currency_svc">Salvadoran Colón</string>
|
<string name="unit_currency_svc">Colón salvadorien</string>
|
||||||
<string name="unit_currency_syp">Syrian pound</string>
|
<string name="unit_currency_syp">Livre syrienne</string>
|
||||||
<string name="unit_currency_szl">Swazi lilangeni</string>
|
<string name="unit_currency_szl">Lilangeni swazi</string>
|
||||||
<string name="unit_currency_thb">Thai baht</string>
|
<string name="unit_currency_thb">Baht thaïlandais</string>
|
||||||
<string name="unit_currency_theta">Theta</string>
|
<string name="unit_currency_theta">Theta</string>
|
||||||
<string name="unit_currency_tjs">Tajikistani somoni</string>
|
<string name="unit_currency_tjs">Somoni tadjik</string>
|
||||||
<string name="unit_currency_tmt">Turkmenistani manat</string>
|
<string name="unit_currency_tmt">Manat turkmène</string>
|
||||||
<string name="unit_currency_tnd">Tunisian dinar</string>
|
<string name="unit_currency_tnd">Dinar tunisien</string>
|
||||||
<string name="unit_currency_top">Tongan Paʻanga</string>
|
<string name="unit_currency_top">Paʻanga tongan</string>
|
||||||
<string name="unit_currency_try">Turkish lira</string>
|
<string name="unit_currency_try">Livre turque</string>
|
||||||
<string name="unit_currency_ttd">Trinidad & Tobago Dollar</string>
|
<string name="unit_currency_ttd">Dollar de Trinité-et-Tobago</string>
|
||||||
<string name="unit_currency_twd">New Taiwan dollar</string>
|
<string name="unit_currency_twd">Nouveau dollar taïwanais</string>
|
||||||
<string name="unit_currency_tzs">Tanzanian shilling</string>
|
<string name="unit_currency_tzs">Shilling tanzanien</string>
|
||||||
<string name="unit_currency_uah">Ukrainian hryvnia</string>
|
<string name="unit_currency_uah">Hryvnia ukrainienne</string>
|
||||||
<string name="unit_currency_ugx">Ugandan shilling</string>
|
<string name="unit_currency_ugx">Shilling ougandais</string>
|
||||||
<string name="unit_currency_uni">Universe</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_usdc">USD Coin</string>
|
||||||
<string name="unit_currency_uyu">Uruguayan peso</string>
|
<string name="unit_currency_uyu">Peso uruguayen</string>
|
||||||
<string name="unit_currency_uzs">Uzbekistani som</string>
|
<string name="unit_currency_uzs">Som ouzbek</string>
|
||||||
<string name="unit_currency_vef">Sovereign Bolivar</string>
|
<string name="unit_currency_vef">Bolivar souverain</string>
|
||||||
<string name="unit_currency_vnd">Vietnamese dong</string>
|
<string name="unit_currency_vnd">Dong vietnamien</string>
|
||||||
<string name="unit_currency_vuv">Vanuatu vatu</string>
|
<string name="unit_currency_vuv">Vatu vanuatu</string>
|
||||||
<string name="unit_currency_wbtc">Wrapped Bitcoin</string>
|
<string name="unit_currency_wbtc">Wrapped Bitcoin</string>
|
||||||
<string name="unit_currency_wst">Samoan tala</string>
|
<string name="unit_currency_wst">Tālā</string>
|
||||||
<string name="unit_currency_xaf">Central African CFA franc</string>
|
<string name="unit_currency_xaf">Franc CFA d\'Afrique centrale</string>
|
||||||
<string name="unit_currency_xag">Silver Ounce</string>
|
<string name="unit_currency_xag">Once d\'argent</string>
|
||||||
<string name="unit_currency_xcd">East Caribbean dollar</string>
|
<string name="unit_currency_xcd">Dollar des Caraïbes orientales</string>
|
||||||
<string name="unit_currency_xdr">Special Drawing Rights</string>
|
<string name="unit_currency_xdr">Droits de tirage spéciaux</string>
|
||||||
<string name="unit_currency_xof">West African CFA franc</string>
|
<string name="unit_currency_xof">Franc CFA d\'Afrique de l\'Ouest</string>
|
||||||
<string name="unit_currency_xpf">CFP franc</string>
|
<string name="unit_currency_xpf">Franc CFP</string>
|
||||||
<string name="unit_currency_yer">Yemeni rial</string>
|
<string name="unit_currency_yer">Rial yéménite</string>
|
||||||
<string name="unit_currency_zar">South African rand</string>
|
<string name="unit_currency_zar">Rand sud-africain</string>
|
||||||
<string name="unit_currency_zmk">Zambian kwacha</string>
|
<string name="unit_currency_zmk">Kwacha zambien</string>
|
||||||
<string name="unit_currency_zmw">Zambian Kwacha</string>
|
<string name="unit_currency_zmw">Kwacha zambien</string>
|
||||||
<string name="unit_currency_zwl">Zimbabwean Dollar</string>
|
<string name="unit_currency_zwl">Dollar zimbabwéen</string>
|
||||||
<string name="unit_day">Jour</string>
|
<string name="unit_day">Jour</string>
|
||||||
<string name="unit_day_short">j</string>
|
<string name="unit_day_short">j</string>
|
||||||
<string name="unit_decimal">Décimal</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">Gravité de surface de la Terre</string>
|
||||||
<string name="unit_earth_surface_gravity_short">G 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_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_cross_section_short">ecs</string>
|
||||||
<string name="unit_electron_mass_rest">Masse électronique</string>
|
<string name="unit_electron_mass_rest">Masse électronique</string>
|
||||||
<string name="unit_electron_mass_rest_short">me</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_data_transfer">Transfert de données</string>
|
||||||
<string name="unit_group_electrostatic_capacitance">Capacité</string>
|
<string name="unit_group_electrostatic_capacitance">Capacité</string>
|
||||||
<string name="unit_group_energy">Énergie</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_flux">Flux</string>
|
||||||
<string name="unit_group_force">Force</string>
|
<string name="unit_group_force">Force</string>
|
||||||
<string name="unit_group_length">Longueur</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_pressure">Pression</string>
|
||||||
<string name="unit_group_speed">Vélocité</string>
|
<string name="unit_group_speed">Vélocité</string>
|
||||||
<string name="unit_group_temperature">Température</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_torque">Couple</string>
|
||||||
<string name="unit_group_volume">Volume</string>
|
<string name="unit_group_volume">Volume</string>
|
||||||
<string name="unit_hectare">Hectare</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_hour_short">h</string>
|
||||||
<string name="unit_imperial_cup">Tasse impériale</string>
|
<string name="unit_imperial_cup">Tasse impériale</string>
|
||||||
<string name="unit_imperial_cup_short">cup</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_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_gallon_short">gal</string>
|
||||||
<string name="unit_imperial_pint">Pinte impériale</string>
|
<string name="unit_imperial_pint">Pinte impériale</string>
|
||||||
<string name="unit_imperial_pint_short">pt</string>
|
<string name="unit_imperial_pint_short">pt</string>
|
||||||
<string name="unit_imperial_quart">Quart impérial</string>
|
<string name="unit_imperial_quart">Quart impérial</string>
|
||||||
<string name="unit_imperial_quart_short">qt</string>
|
<string name="unit_imperial_quart_short">qt</string>
|
||||||
<string name="unit_imperial_tablespoon">Imperial tablespoon</string>
|
<string name="unit_imperial_tablespoon">Cuillère à soupe impériale</string>
|
||||||
<string name="unit_imperial_tablespoon_short">tablespoon</string>
|
<string name="unit_imperial_tablespoon_short">cuillère à soupe</string>
|
||||||
<string name="unit_imperial_teaspoon">Imperial teaspoon</string>
|
<string name="unit_imperial_teaspoon">Cuillère à café impériale</string>
|
||||||
<string name="unit_imperial_teaspoon_short">teaspoon</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">Tonne impériale</string>
|
||||||
<string name="unit_imperial_ton_short">t</string>
|
<string name="unit_imperial_ton_short">t</string>
|
||||||
<string name="unit_inch">Pouce</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_per_second_short">mL/s</string>
|
||||||
<string name="unit_milliliter_short">mL</string>
|
<string name="unit_milliliter_short">mL</string>
|
||||||
<string name="unit_millimeter">Millimètre</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_of_mercury_short">mm Hg</string>
|
||||||
<string name="unit_millimeter_per_hour">Millimètre/heure</string>
|
<string name="unit_millimeter_per_hour">Millimètre/heure</string>
|
||||||
<string name="unit_millimeter_per_hour_short">mm/h</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_mass_short">M Uranus</string>
|
||||||
<string name="unit_uranus_surface_gravity">Gravité de surface d\'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_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_fluid_ounce_short">fl oz</string>
|
||||||
<string name="unit_us_legal_cup">Tasse américaine</string>
|
<string name="unit_us_legal_cup">Tasse américaine</string>
|
||||||
<string name="unit_us_legal_cup_short">cup</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">Quarts américain</string>
|
||||||
<string name="unit_us_liquid_quart_short">qt</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">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">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_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">Radius équatorial de Vénus</string>
|
||||||
<string name="unit_venus_equatorial_radius_short">R Vénus</string>
|
<string name="unit_venus_equatorial_radius_short">R Vénus</string>
|
||||||
@ -1062,4 +1099,4 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
|||||||
<string name="unit_yard_short">yd</string>
|
<string name="unit_yard_short">yd</string>
|
||||||
<string name="unit_year_short">y</string>
|
<string name="unit_year_short">y</string>
|
||||||
<string name="yesterday">Hier</string>
|
<string name="yesterday">Hier</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
<string name="open_menu_description">Menü megnyitása</string>
|
<string name="open_menu_description">Menü megnyitása</string>
|
||||||
<string name="open_settings_label">Beállítások megnyitása</string>
|
<string name="open_settings_label">Beállítások megnyitása</string>
|
||||||
<string name="search_button_description">Keresőgomb</string>
|
<string name="search_button_description">Keresőgomb</string>
|
||||||
<string name="settings_about_unitto">Az Unitto-ról</string>
|
<string name="settings_about_unitto">Az NumberHub-ról</string>
|
||||||
<string name="settings_about_unitto_support">Tudj meg többet az appról</string>
|
<string name="settings_about_unitto_support">Tudj meg többet az appról</string>
|
||||||
<string name="settings_additional">Továbbiak</string>
|
<string name="settings_additional">Továbbiak</string>
|
||||||
<string name="settings_amoled_dark">AMOLED Sötét</string>
|
<string name="settings_amoled_dark">AMOLED Sötét</string>
|
||||||
|
@ -78,7 +78,7 @@ Used in this dialog window. Should be short -->
|
|||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
||||||
<string name="select_time_label">Pilih waktu</string>
|
<string name="select_time_label">Pilih waktu</string>
|
||||||
<string name="settings_about_unitto">Tentang Unitto</string>
|
<string name="settings_about_unitto">Tentang NumberHub</string>
|
||||||
<string name="settings_about_unitto_support">Pelajari tentang aplikasi</string>
|
<string name="settings_about_unitto_support">Pelajari tentang aplikasi</string>
|
||||||
<string name="settings_amoled_dark">Gelap AMOLED</string>
|
<string name="settings_amoled_dark">Gelap AMOLED</string>
|
||||||
<string name="settings_amoled_dark_support">Gunakan latar hitam untuk tema gelap</string>
|
<string name="settings_amoled_dark_support">Gunakan latar hitam untuk tema gelap</string>
|
||||||
|
@ -137,7 +137,7 @@ Used in this dialog window. Should be short -->
|
|||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
||||||
<string name="select_time_label">Seleziona orario</string>
|
<string name="select_time_label">Seleziona orario</string>
|
||||||
<string name="settings_about_unitto">Riguardo a Unitto</string>
|
<string name="settings_about_unitto">Riguardo a NumberHub</string>
|
||||||
<string name="settings_about_unitto_support">Impara riguardo all\'app</string>
|
<string name="settings_about_unitto_support">Impara riguardo all\'app</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
||||||
|
@ -203,7 +203,7 @@ Used in this dialog window. Should be short -->
|
|||||||
https://s3.eu-west-1.amazonaws.com/po-pub/i/1oIHPj16krI0jyLmg4JaP2mk.png -->
|
https://s3.eu-west-1.amazonaws.com/po-pub/i/1oIHPj16krI0jyLmg4JaP2mk.png -->
|
||||||
<!-- Screen readers (accessibility) -->
|
<!-- Screen readers (accessibility) -->
|
||||||
<string name="selected_item">Geselecteerd item</string>
|
<string name="selected_item">Geselecteerd item</string>
|
||||||
<string name="settings_about_unitto">Over Unitto</string>
|
<string name="settings_about_unitto">Over NumberHub</string>
|
||||||
<string name="settings_about_unitto_support">Leer meer over de app</string>
|
<string name="settings_about_unitto_support">Leer meer over de app</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
||||||
|
@ -83,7 +83,7 @@ Used in this dialog window. Should be short -->
|
|||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
||||||
<string name="select_time_label">Selecione o horário</string>
|
<string name="select_time_label">Selecione o horário</string>
|
||||||
<string name="settings_about_unitto">Sobre o Unitto</string>
|
<string name="settings_about_unitto">Sobre o NumberHub</string>
|
||||||
<string name="settings_about_unitto_support">Saiba mais sobre o app</string>
|
<string name="settings_about_unitto_support">Saiba mais sobre o app</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
||||||
|
@ -203,7 +203,7 @@ Used in this dialog window. Should be short -->
|
|||||||
https://s3.eu-west-1.amazonaws.com/po-pub/i/1oIHPj16krI0jyLmg4JaP2mk.png -->
|
https://s3.eu-west-1.amazonaws.com/po-pub/i/1oIHPj16krI0jyLmg4JaP2mk.png -->
|
||||||
<!-- Screen readers (accessibility) -->
|
<!-- Screen readers (accessibility) -->
|
||||||
<string name="selected_item">Выбранные элемент</string>
|
<string name="selected_item">Выбранные элемент</string>
|
||||||
<string name="settings_about_unitto">О Unitto</string>
|
<string name="settings_about_unitto">О NumberHub</string>
|
||||||
<string name="settings_about_unitto_support">Узнайте больше о приложении</string>
|
<string name="settings_about_unitto_support">Узнайте больше о приложении</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
||||||
|
@ -80,7 +80,7 @@ Used in this dialog window. Should be short -->
|
|||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/uWOHJmIq9riqsq7PO82ZQp3a.png -->
|
||||||
<string name="select_time_label">Zaman seçin</string>
|
<string name="select_time_label">Zaman seçin</string>
|
||||||
<string name="settings_about_unitto">Unitto hakkında</string>
|
<string name="settings_about_unitto">NumberHub hakkında</string>
|
||||||
<string name="settings_about_unitto_support">Uygulama hakkında bilgi edinin</string>
|
<string name="settings_about_unitto_support">Uygulama hakkında bilgi edinin</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/p3aY3IWUI5m9Vjs6vZP3EXAo.png -->
|
||||||
@ -146,7 +146,7 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
|||||||
<string name="settings_space">Boşluk</string>
|
<string name="settings_space">Boşluk</string>
|
||||||
<string name="settings_starting_screen">Başlangıç ekranı</string>
|
<string name="settings_starting_screen">Başlangıç ekranı</string>
|
||||||
<string name="settings_starting_screen_support">Uygulamayı başlattığınızda hangi ekranın gösterileceğini seçin</string>
|
<string name="settings_starting_screen_support">Uygulamayı başlattığınızda hangi ekranın gösterileceğini seçin</string>
|
||||||
|
|
||||||
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/r1VikAn70eXQP4da2hrntTGQ.jpg -->
|
<!-- https://s3.eu-west-1.amazonaws.com/po-pub/i/r1VikAn70eXQP4da2hrntTGQ.jpg -->
|
||||||
<!-- Option name to use system default setting -->
|
<!-- Option name to use system default setting -->
|
||||||
<string name="settings_system">Sistem</string>
|
<string name="settings_system">Sistem</string>
|
||||||
|
@ -135,7 +135,7 @@ Used in this dialog window. Should be short -->
|
|||||||
https://s3.eu-west-1.amazonaws.com/po-pub/i/1oIHPj16krI0jyLmg4JaP2mk.png -->
|
https://s3.eu-west-1.amazonaws.com/po-pub/i/1oIHPj16krI0jyLmg4JaP2mk.png -->
|
||||||
<!-- Screen readers (accessibility) -->
|
<!-- Screen readers (accessibility) -->
|
||||||
<string name="selected_item">已选定项目</string>
|
<string name="selected_item">已选定项目</string>
|
||||||
<string name="settings_about_unitto">关于 Unitto</string>
|
<string name="settings_about_unitto">关于 NumberHub</string>
|
||||||
<string name="settings_about_unitto_support">了解此应用</string>
|
<string name="settings_about_unitto_support">了解此应用</string>
|
||||||
<string name="settings_additional">额外的</string>
|
<string name="settings_additional">额外的</string>
|
||||||
<string name="settings_amoled_dark">AMOLED 黑</string>
|
<string name="settings_amoled_dark">AMOLED 黑</string>
|
||||||
|
@ -25,7 +25,6 @@ import androidx.compose.foundation.layout.FlowRowScope
|
|||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,8 +50,8 @@ fun KeypadFlow(
|
|||||||
@IntRange(0, 100) verticalPadding: Int = 10,
|
@IntRange(0, 100) verticalPadding: Int = 10,
|
||||||
content: @Composable FlowRowScope.(width: Float, height: Float) -> Unit,
|
content: @Composable FlowRowScope.(width: Float, height: Float) -> Unit,
|
||||||
) {
|
) {
|
||||||
val height: Float = remember { (1f - verticalPadding / 100f) / rows }
|
val height: Float = (1f - verticalPadding / 100f) / rows
|
||||||
val width: Float = remember { (1f - horizontalPadding / 100f) / columns }
|
val width: Float = (1f - horizontalPadding / 100f) / columns
|
||||||
|
|
||||||
FlowRow(
|
FlowRow(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
@ -102,17 +102,232 @@ class UnitsRepositoryImpl @Inject constructor(
|
|||||||
|
|
||||||
suspend fun getPairId(id: String): String = withContext(Dispatchers.IO) {
|
suspend fun getPairId(id: String): String = withContext(Dispatchers.IO) {
|
||||||
val basedUnitPair = getUnitStats(id).pairedUnitId
|
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 inMemoryUnit = inMemory.first { it.id == id }
|
||||||
val collection = inMemory.filter { it.group == inMemoryUnit.group }
|
val collection = inMemory.filter { it.group == inMemoryUnit.group }
|
||||||
|
|
||||||
val pair = collection
|
return@withContext when (inMemoryUnit.id) {
|
||||||
.map { getById(it.id) to getUnitStats(it.id) }
|
// === === === Length === === ===
|
||||||
.sortedByDescending { it.second.frequency }
|
UnitID.nanometer -> UnitID.micrometer
|
||||||
.firstOrNull { it.second.isFavorite }?.first ?: collection.first()
|
UnitID.micrometer -> UnitID.millimeter
|
||||||
|
UnitID.millimeter -> UnitID.centimeter
|
||||||
|
|
||||||
return@withContext pair.id
|
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()).id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun incrementCounter(id: String) = withContext(Dispatchers.IO) {
|
suspend fun incrementCounter(id: String) = withContext(Dispatchers.IO) {
|
||||||
|
@ -27,19 +27,100 @@ import java.math.BigDecimal
|
|||||||
|
|
||||||
internal val areaCollection: List<BasicUnit> by lazy {
|
internal val areaCollection: List<BasicUnit> by lazy {
|
||||||
listOf(
|
listOf(
|
||||||
NormalUnit(UnitID.cent, BigDecimal("6083246572000000000000000000000000"), UnitGroup.AREA, R.string.unit_cent, R.string.unit_cent_short),
|
// https://www.gowebtool.com/unit-conversion/area/convert.php?from=electron_cross_section&to=acre
|
||||||
NormalUnit(UnitID.acre, BigDecimal("60832465720000000000000000000000"), UnitGroup.AREA, R.string.unit_acre, R.string.unit_acre_short),
|
NormalUnit(
|
||||||
NormalUnit(UnitID.hectare, BigDecimal("150320296400000000000000000000000"), UnitGroup.AREA, R.string.unit_hectare, R.string.unit_hectare_short ),
|
UnitID.acre,
|
||||||
NormalUnit(UnitID.square_foot, BigDecimal("1396521251000000000000000000"), UnitGroup.AREA, R.string.unit_square_foot, R.string.unit_square_foot_short),
|
BigDecimal("60832465720659000000000000000000"),
|
||||||
NormalUnit(UnitID.square_mile, BigDecimal("38932778060000000000000000000000000"), UnitGroup.AREA, R.string.unit_square_mile, R.string.unit_square_mile_short),
|
UnitGroup.AREA,
|
||||||
NormalUnit(UnitID.square_yard, BigDecimal("12568691260000000000000000000"), UnitGroup.AREA, R.string.unit_square_yard, R.string.unit_square_yard_short),
|
R.string.unit_acre,
|
||||||
NormalUnit(UnitID.square_inch, BigDecimal("9698064247000000000000000"), UnitGroup.AREA, R.string.unit_square_inch, R.string.unit_square_inch_short),
|
R.string.unit_acre_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),
|
// https://www.gowebtool.com/unit-conversion/area/convert.php?from=electron_cross_section&to=cent
|
||||||
NormalUnit(UnitID.square_centimeter, BigDecimal("1503202964000000000000000"), UnitGroup.AREA, R.string.unit_square_centimeter, R.string.unit_square_centimeter_short),
|
NormalUnit(
|
||||||
NormalUnit(UnitID.square_decimeter, BigDecimal("150320296400000000000000000"), UnitGroup.AREA, R.string.unit_square_decimeter, R.string.unit_square_decimeter_short),
|
UnitID.cent,
|
||||||
NormalUnit(UnitID.square_meter, BigDecimal("15032029640000000000000000000"), UnitGroup.AREA, R.string.unit_square_meter, R.string.unit_square_meter_short),
|
BigDecimal("608324656845820000000000000000"),
|
||||||
NormalUnit(UnitID.square_kilometer, BigDecimal("15032029640000000000000000000000000"), UnitGroup.AREA, R.string.unit_square_kilometer, R.string.unit_square_kilometer_short),
|
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),
|
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
|
@Test
|
||||||
fun testArea() = testWithUnits {
|
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")
|
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_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, "75.9", "683.1")
|
||||||
|
square_yard.checkWith(square_foot, "1", "9")
|
||||||
square_inch.checkWith(square_foot, "75.9", "0.52708")
|
square_inch.checkWith(square_foot, "75.9", "0.52708")
|
||||||
square_micrometer.checkWith(square_millimeter, "75.9", "0.00008")
|
square_micrometer.checkWith(square_millimeter, "75.9", "0.00008")
|
||||||
square_millimeter.checkWith(square_centimeter, "75.9", "0.759")
|
square_millimeter.checkWith(square_centimeter, "75.9", "0.759")
|
||||||
@ -133,6 +142,7 @@ class AllUnitsTest {
|
|||||||
square_meter.checkWith(acre, "75.9", "0.01876")
|
square_meter.checkWith(acre, "75.9", "0.01876")
|
||||||
square_kilometer.checkWith(hectare, "75.9", "7590")
|
square_kilometer.checkWith(hectare, "75.9", "7590")
|
||||||
electron_cross_section.checkWith(square_micrometer, "75.9", "0.000000000000005")
|
electron_cross_section.checkWith(square_micrometer, "75.9", "0.000000000000005")
|
||||||
|
square_decimeter.checkWith(acre, "123.456", "0.00031")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -26,9 +26,19 @@ import kotlin.math.asin
|
|||||||
import kotlin.math.atan
|
import kotlin.math.atan
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
|
// Dirty hack to avoid -0.000000000001
|
||||||
|
val PI_THRESHOLD = BigDecimal("0.000000000000001")
|
||||||
|
|
||||||
internal fun BigDecimal.sin(radianMode: Boolean): BigDecimal {
|
internal fun BigDecimal.sin(radianMode: Boolean): BigDecimal {
|
||||||
val angle: Double = if (radianMode) this.toDouble() else Math.toRadians(this.toDouble())
|
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 {
|
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 {
|
internal fun BigDecimal.cos(radianMode: Boolean): BigDecimal {
|
||||||
val angle: Double = if (radianMode) this.toDouble() else Math.toRadians(this.toDouble())
|
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 {
|
internal fun BigDecimal.arcos(radianMode: Boolean): BigDecimal {
|
||||||
|
@ -93,10 +93,14 @@ class Expression(
|
|||||||
}
|
}
|
||||||
|
|
||||||
moveIfMatched(Token.Operator.divide) -> {
|
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()
|
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
|
// sin
|
||||||
if (moveIfMatched(Token.Func.sin)) {
|
if (moveIfMatched(Token.Func.sin)) {
|
||||||
expr = parseFuncParentheses().sin(radianMode)
|
val x = parseFuncParentheses()
|
||||||
|
expr = x.sin(radianMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cos
|
// cos
|
||||||
@ -211,7 +216,13 @@ class Expression(
|
|||||||
|
|
||||||
// Power
|
// Power
|
||||||
if (moveIfMatched(Token.Operator.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
|
// Modulo
|
||||||
|
@ -57,4 +57,7 @@ class ExpressionComplexTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun expression12() = assertExpr("2×(3+4)×(5−2)÷6", "7")
|
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
|
@Test
|
||||||
fun expression29() = assertExpr("0!", "1")
|
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")
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ val ALL_THIRD_PARTY by lazy {
|
|||||||
ThirdParty(
|
ThirdParty(
|
||||||
name = "currency-api",
|
name = "currency-api",
|
||||||
dev = "Fawaz Ahmed (fawazahmed0)",
|
dev = "Fawaz Ahmed (fawazahmed0)",
|
||||||
website = "https://github.com/fawazahmed0/currency-api",
|
website = "https://github.com/fawazahmed0/exchange-api",
|
||||||
license = "The Unlicense",
|
license = "The Unlicense",
|
||||||
description = "Free Currency Rates API",
|
description = "Free Currency Rates API",
|
||||||
),
|
),
|
||||||
|
@ -37,6 +37,16 @@ sealed interface BasicUnit {
|
|||||||
|
|
||||||
interface NumberBase : BasicUnit {
|
interface NumberBase : BasicUnit {
|
||||||
fun convert(unitTo: NumberBase, value: String): String
|
fun convert(unitTo: NumberBase, value: String): String
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val Hexadecimal = NumberBaseUnit(
|
||||||
|
"hexadecimal",
|
||||||
|
BigDecimal(16),
|
||||||
|
UnitGroup.NUMBER_BASE,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Default : BasicUnit {
|
interface Default : BasicUnit {
|
||||||
|
@ -120,7 +120,7 @@ internal fun Preferences.getUnitConverterFormatTime(): Boolean {
|
|||||||
|
|
||||||
internal fun Preferences.getUnitConverterSorting(): UnitsListSorting {
|
internal fun Preferences.getUnitConverterSorting(): UnitsListSorting {
|
||||||
return this[PrefsKeys.UNIT_CONVERTER_SORTING]
|
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> {
|
internal fun Preferences.getShownUnitGroups(): List<UnitGroup> {
|
||||||
|
@ -1,56 +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 or in-app purchases
|
||||||
• No ads, in-app purchases or asking for donations
|
* Open source
|
||||||
• Open source
|
|
||||||
|
|
||||||
<b>Calculator</b>
|
Calculator
|
||||||
|
|
||||||
• Copy, paste, save and share expression results
|
* Copy, paste, save and share expression results
|
||||||
• Trigonometric functions
|
* Trigonometric functions
|
||||||
• Fractional output
|
* Fractional output
|
||||||
|
|
||||||
<b>Unit converter</b>
|
**Unit converter**
|
||||||
|
|
||||||
• 570 units
|
Over 500 units! Convert miles to kilometers, Dollar to Euro, Bytes to Gigabytes and so much more!
|
||||||
• Built-in currency converter
|
|
||||||
• Favorite units
|
|
||||||
• Organize unit groups
|
|
||||||
• Smart search algorithm
|
|
||||||
|
|
||||||
<b>Date calculator</b>
|
**Date calculator**
|
||||||
• Add and subtract dates
|
|
||||||
• Calculate difference
|
|
||||||
• Create events in calendar
|
|
||||||
|
|
||||||
<b>Time converter</b>
|
Add and subtract dates with ease
|
||||||
• Add to favorites
|
|
||||||
• Add labels to time zones
|
|
||||||
|
|
||||||
<b>Permissions</b>
|
**Time converter**
|
||||||
|
|
||||||
app.myzel394.numberhub.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION
|
Convert time zones
|
||||||
Read (boring): https://developer.android.com/about/versions/14/behavior-changes-14#runtime-receivers-exported
|
|
||||||
|
|
||||||
android.permission.INTERNET
|
|
||||||
Used in Unit Converter to update currency rates. Requests are made only when you select a currency unit.
|
|
||||||
|
|
||||||
android.permission.ACCESS_NETWORK_STATE
|
|
||||||
Used in Unit Converter as a callback. Retries to update currency rates if there was an error (no network, for example) and the Internet connection is back.
|
|
||||||
|
|
||||||
android.permission.WAKE_LOCK
|
|
||||||
Not used explicitly. Added automatically by Widget feature.
|
|
||||||
|
|
||||||
android.permission.RECEIVE_BOOT_COMPLETED
|
|
||||||
Not used explicitly. Added automatically by Widget feature.
|
|
||||||
|
|
||||||
android.permission.FOREGROUND_SERVICE
|
|
||||||
Not used explicitly. Added automatically by Widget feature.
|
|
||||||
|
|
||||||
Non-free network service
|
|
||||||
<i>Non-free</i> doesn't mean that you need to pay, put your credit card away. In this context it means that you can't host it on your machine.
|
|
||||||
|
|
||||||
The app uses https://github.com/fawazahmed0/currency-api by https://github.com/fawazahmed0
|
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: 93 KiB |
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 @@
|
|||||||
Calculator, converter and more
|
Your Hub for Math / Currency rates / Date calculations / Time zones...
|
||||||
|
@ -1 +1 @@
|
|||||||
Unitto — calculator and unit converter
|
NumberHub
|
@ -204,7 +204,7 @@ private fun BodyMassScreen(
|
|||||||
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
openLink(mContext, "https://sadellie.github.io/unitto/help#body-mass-index")
|
openLink(mContext, "https://github.com/Myzel394/NumberHub/blob/master/HELP.md#body-mass-index")
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.time_zone_no_results_button)) // TODO Rename
|
Text(text = stringResource(R.string.time_zone_no_results_button)) // TODO Rename
|
||||||
|
@ -22,6 +22,7 @@ import androidx.compose.animation.AnimatedContent
|
|||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.SizeTransform
|
import androidx.compose.animation.SizeTransform
|
||||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||||
|
import androidx.compose.animation.core.LinearEasing
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.expandHorizontally
|
import androidx.compose.animation.expandHorizontally
|
||||||
@ -31,6 +32,11 @@ import androidx.compose.animation.fadeOut
|
|||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
import androidx.compose.foundation.background
|
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.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
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.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.SwapHoriz
|
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.focus.onFocusEvent
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
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.ConverterResult
|
||||||
import app.myzel394.numberhub.data.converter.UnitID
|
import app.myzel394.numberhub.data.converter.UnitID
|
||||||
import app.myzel394.numberhub.data.model.converter.UnitGroup
|
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.DefaultKeyboard
|
||||||
import app.myzel394.numberhub.feature.converter.components.NumberBaseKeyboard
|
import app.myzel394.numberhub.feature.converter.components.NumberBaseKeyboard
|
||||||
import app.myzel394.numberhub.feature.converter.components.UnitSelectionButton
|
import app.myzel394.numberhub.feature.converter.components.UnitSelectionButton
|
||||||
|
import app.myzel394.numberhub.feature.converter.components.ValueOneSummary
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun ConverterRoute(
|
internal fun ConverterRoute(
|
||||||
@ -203,10 +214,30 @@ private fun NumberBase(
|
|||||||
convert()
|
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(
|
PortraitLandscape(
|
||||||
modifier = modifier.fillMaxSize(),
|
modifier = modifier.fillMaxSize(),
|
||||||
content1 = { contentModifier ->
|
content1 = { contentModifier ->
|
||||||
ColumnWithConstraints(modifier = contentModifier) {
|
ColumnWithConstraints(
|
||||||
|
modifier = contentModifier
|
||||||
|
.anchoredDraggable(
|
||||||
|
state = dragState,
|
||||||
|
orientation = Orientation.Vertical,
|
||||||
|
),
|
||||||
|
) {
|
||||||
val textFieldModifier = Modifier.weight(2f)
|
val textFieldModifier = Modifier.weight(2f)
|
||||||
|
|
||||||
NumberBaseTextField(
|
NumberBaseTextField(
|
||||||
@ -224,6 +255,22 @@ private fun NumberBase(
|
|||||||
)
|
)
|
||||||
AnimatedUnitShortName(stringResource(uiState.unitTo.shortName))
|
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))
|
Spacer(modifier = Modifier.height(it.maxHeight * 0.03f))
|
||||||
|
|
||||||
UnitSelectionButtons(
|
UnitSelectionButtons(
|
||||||
@ -250,6 +297,7 @@ private fun NumberBase(
|
|||||||
addDigit = { updateInput1(uiState.input.addTokens(it)) },
|
addDigit = { updateInput1(uiState.input.addTokens(it)) },
|
||||||
deleteDigit = { updateInput1(uiState.input.deleteTokens()) },
|
deleteDigit = { updateInput1(uiState.input.deleteTokens()) },
|
||||||
clearInput = { updateInput1(TextFieldValue()) },
|
clearInput = { updateInput1(TextFieldValue()) },
|
||||||
|
basis = uiState.unitFrom,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -284,6 +332,20 @@ private fun Default(
|
|||||||
}
|
}
|
||||||
var focusedOnInput1 by rememberSaveable { mutableStateOf(true) }
|
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) {
|
LaunchedEffect(connection) {
|
||||||
if ((connection == ConnectionState.Available) and (uiState.result is ConverterResult.Error)) {
|
if ((connection == ConnectionState.Available) and (uiState.result is ConverterResult.Error)) {
|
||||||
val unitFrom = uiState.unitFrom
|
val unitFrom = uiState.unitFrom
|
||||||
@ -304,7 +366,13 @@ private fun Default(
|
|||||||
PortraitLandscape(
|
PortraitLandscape(
|
||||||
modifier = modifier.fillMaxSize(),
|
modifier = modifier.fillMaxSize(),
|
||||||
content1 = { contentModifier ->
|
content1 = { contentModifier ->
|
||||||
ColumnWithConstraints(modifier = contentModifier) { boxWithConstraintsScope ->
|
ColumnWithConstraints(
|
||||||
|
modifier = contentModifier
|
||||||
|
.anchoredDraggable(
|
||||||
|
state = dragState,
|
||||||
|
orientation = Orientation.Vertical,
|
||||||
|
),
|
||||||
|
) { boxWithConstraintsScope ->
|
||||||
val textFieldModifier = Modifier
|
val textFieldModifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.weight(2f)
|
.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))
|
Spacer(modifier = Modifier.height(boxWithConstraintsScope.maxHeight * 0.03f))
|
||||||
|
|
||||||
UnitSelectionButtons(
|
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,
|
selectedUnitGroup = UnitGroup.SPEED,
|
||||||
shownUnitGroups = UnitGroup.entries,
|
shownUnitGroups = UnitGroup.entries,
|
||||||
showFavoritesOnly = false,
|
showFavoritesOnly = false,
|
||||||
sorting = UnitsListSorting.USAGE,
|
sorting = UnitsListSorting.SCALE_ASC,
|
||||||
),
|
),
|
||||||
onQueryChange = {},
|
onQueryChange = {},
|
||||||
toggleFavoritesOnly = {},
|
toggleFavoritesOnly = {},
|
||||||
|
@ -155,7 +155,7 @@ private fun UnitToSelectorPreview() {
|
|||||||
query = TextFieldValue("test"),
|
query = TextFieldValue("test"),
|
||||||
units = units,
|
units = units,
|
||||||
showFavoritesOnly = false,
|
showFavoritesOnly = false,
|
||||||
sorting = UnitsListSorting.USAGE,
|
sorting = UnitsListSorting.SCALE_ASC,
|
||||||
input = "100",
|
input = "100",
|
||||||
scale = 3,
|
scale = 3,
|
||||||
outputFormat = OutputFormat.PLAIN,
|
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
|
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.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.runtime.Composable
|
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.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
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.R
|
||||||
import app.myzel394.numberhub.core.base.Token
|
import app.myzel394.numberhub.core.base.Token
|
||||||
import app.myzel394.numberhub.core.ui.LocalWindowSize
|
import app.myzel394.numberhub.core.ui.LocalWindowSize
|
||||||
import app.myzel394.numberhub.core.ui.WindowHeightSizeClass
|
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.KeyboardButtonFilled
|
||||||
import app.myzel394.numberhub.core.ui.common.KeyboardButtonLight
|
import app.myzel394.numberhub.core.ui.common.KeyboardButtonLight
|
||||||
import app.myzel394.numberhub.core.ui.common.KeyboardButtonTertiary
|
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.Power
|
||||||
import app.myzel394.numberhub.core.ui.common.icons.iconpack.RightBracket
|
import app.myzel394.numberhub.core.ui.common.icons.iconpack.RightBracket
|
||||||
import app.myzel394.numberhub.core.ui.common.icons.iconpack.Root
|
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
|
@Composable
|
||||||
internal fun DefaultKeyboard(
|
internal fun DefaultKeyboard(
|
||||||
@ -79,92 +97,401 @@ internal fun DefaultKeyboard(
|
|||||||
) {
|
) {
|
||||||
val fractionalIcon = remember(fractional) { if (fractional == Token.PERIOD) IconPack.Dot else IconPack.Comma }
|
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 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(
|
KeypadFlow(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
rows = 5,
|
rows = 5,
|
||||||
columns = 4,
|
columns = 4,
|
||||||
) { width, height ->
|
) { width, height ->
|
||||||
val bModifier = Modifier.fillMaxWidth(width).fillMaxHeight(height)
|
val bModifier = Modifier
|
||||||
|
.fillMaxWidth(width)
|
||||||
|
.fillMaxHeight(height)
|
||||||
|
|
||||||
if (acButton) {
|
if (acButton) {
|
||||||
KeyboardButtonTertiary(bModifier, IconPack.Clear, stringResource(R.string.delete_label), contentHeight) { clearInput() }
|
KeyboardButtonTertiary(
|
||||||
KeyboardButtonFilled(bModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), contentHeight) { addBracket() }
|
bModifier,
|
||||||
|
IconPack.Clear,
|
||||||
|
stringResource(R.string.delete_label),
|
||||||
|
contentHeight,
|
||||||
|
) { clearInput() }
|
||||||
|
KeyboardButtonFilled(
|
||||||
|
bModifier,
|
||||||
|
IconPack.Brackets,
|
||||||
|
stringResource(R.string.keyboard_brackets),
|
||||||
|
contentHeight,
|
||||||
|
) { addBracket() }
|
||||||
} else {
|
} else {
|
||||||
KeyboardButtonFilled(bModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), contentHeight) { addDigit(Token.Operator.leftBracket) }
|
KeyboardButtonFilled(
|
||||||
KeyboardButtonFilled(bModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), contentHeight) { addDigit(Token.Operator.rightBracket) }
|
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(
|
||||||
KeyboardButtonFilled(bModifier, IconPack.Root, stringResource(R.string.keyboard_root), contentHeight) { addDigit(Token.Operator.sqrt) }
|
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(
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key8, Token.Digit._8, contentHeight) { addDigit(Token.Digit._8) }
|
bModifier,
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key9, Token.Digit._9, contentHeight) { addDigit(Token.Digit._9) }
|
IconPack.Key7,
|
||||||
KeyboardButtonFilled(bModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), contentHeight) { addDigit(Token.Operator.divide) }
|
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(
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key5, Token.Digit._5, contentHeight) { addDigit(Token.Digit._5) }
|
bModifier,
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key6, Token.Digit._6, contentHeight) { addDigit(Token.Digit._6) }
|
IconPack.Key4,
|
||||||
KeyboardButtonFilled(bModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), contentHeight) { addDigit(Token.Operator.multiply) }
|
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(
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key2, Token.Digit._2, contentHeight) { addDigit(Token.Digit._2) }
|
bModifier,
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key3, Token.Digit._3, contentHeight) { addDigit(Token.Digit._3) }
|
IconPack.Key1,
|
||||||
KeyboardButtonFilled(bModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), contentHeight) { addDigit(Token.Operator.minus) }
|
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) {
|
if (middleZero) {
|
||||||
KeyboardButtonLight(bModifier, fractionalIcon, stringResource(fractionalIconDescription), contentHeight) { addDigit(Token.Digit.dot) }
|
KeyboardButtonLight(
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key0, Token.Digit._0, contentHeight) { addDigit(Token.Digit._0) }
|
bModifier,
|
||||||
|
fractionalIcon,
|
||||||
|
stringResource(fractionalIconDescription),
|
||||||
|
contentHeight,
|
||||||
|
) { addDigit(Token.Digit.dot) }
|
||||||
|
KeyboardButtonLight(
|
||||||
|
bModifier,
|
||||||
|
IconPack.Key0,
|
||||||
|
Token.Digit._0,
|
||||||
|
contentHeight,
|
||||||
|
) { addDigit(Token.Digit._0) }
|
||||||
} else {
|
} else {
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key0, Token.Digit._0, contentHeight) { addDigit(Token.Digit._0) }
|
KeyboardButtonLight(
|
||||||
KeyboardButtonLight(bModifier, fractionalIcon, stringResource(fractionalIconDescription), contentHeight) { addDigit(Token.Digit.dot) }
|
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() }
|
KeyboardButtonLight(
|
||||||
KeyboardButtonFilled(bModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), contentHeight) { addDigit(Token.Operator.plus) }
|
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
|
@Composable
|
||||||
internal fun NumberBaseKeyboard(
|
internal fun NumberBaseKeyboard(
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
addDigit: (String) -> Unit,
|
addDigit: (String) -> Unit,
|
||||||
clearInput: () -> Unit,
|
clearInput: () -> Unit,
|
||||||
deleteDigit: () -> 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 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 {
|
||||||
modifier = modifier,
|
mutableStateOf(AnimatedContentTransitionScope.SlideDirection.Right)
|
||||||
rows = 6,
|
}
|
||||||
columns = 3,
|
|
||||||
) { width, height ->
|
|
||||||
val bModifier = Modifier.fillMaxWidth(width).fillMaxHeight(height)
|
|
||||||
val wideButtonModifier = Modifier.fillMaxHeight(height).fillMaxWidth(width * 2)
|
|
||||||
|
|
||||||
KeyboardButtonFilled(bModifier, IconPack.KeyA, Token.Letter._A, contentHeight) { addDigit(Token.Letter._A) }
|
LaunchedEffect(isUsingColumn) {
|
||||||
KeyboardButtonFilled(bModifier, IconPack.KeyB, Token.Letter._B, contentHeight) { addDigit(Token.Letter._B) }
|
direction = if (isUsingColumn) {
|
||||||
KeyboardButtonFilled(bModifier, IconPack.KeyC, Token.Letter._C, contentHeight) { addDigit(Token.Letter._C) }
|
AnimatedContentTransitionScope.SlideDirection.Right
|
||||||
|
} else {
|
||||||
|
AnimatedContentTransitionScope.SlideDirection.Up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KeyboardButtonFilled(bModifier, IconPack.KeyD, Token.Letter._D, contentHeight) { addDigit(Token.Letter._D) }
|
LaunchedEffect(basis) {
|
||||||
KeyboardButtonFilled(bModifier, IconPack.KeyE, Token.Letter._E, contentHeight) { addDigit(Token.Letter._E) }
|
direction = when (direction) {
|
||||||
KeyboardButtonFilled(bModifier, IconPack.KeyF, Token.Letter._F, contentHeight) { addDigit(Token.Letter._F) }
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key7, Token.Digit._7, contentHeight) { addDigit(Token.Digit._7) }
|
ColumnWithConstraints(modifier) { constraints ->
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key8, Token.Digit._8, contentHeight) { addDigit(Token.Digit._8) }
|
AnimatedContent(
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key9, Token.Digit._9, contentHeight) { addDigit(Token.Digit._9) }
|
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
|
||||||
|
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key4, Token.Digit._4, contentHeight) { addDigit(Token.Digit._4) }
|
FlowRow(
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key5, Token.Digit._5, contentHeight) { addDigit(Token.Digit._5) }
|
modifier = modifier,
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key6, Token.Digit._6, contentHeight) { addDigit(Token.Digit._6) }
|
maxItemsInEachRow = columns,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(horizontalSpacing),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(verticalSpacing),
|
||||||
|
) {
|
||||||
|
val bModifier = Modifier
|
||||||
|
.fillMaxHeight(height)
|
||||||
|
.fillMaxWidth()
|
||||||
|
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key1, Token.Digit._1, contentHeight) { addDigit(Token.Digit._1) }
|
when {
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key2, Token.Digit._2, contentHeight) { addDigit(Token.Digit._2) }
|
amount in arrayOf(3, 5, 7) -> {
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key3, Token.Digit._3, contentHeight) { addDigit(Token.Digit._3) }
|
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) }
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Should be a separate o use custom widthFillFactors and heightFillFactors
|
KeyboardButtonLight(
|
||||||
KeyboardButtonLight(bModifier, IconPack.Key0, Token.Digit._0, contentHeight) { addDigit(Token.Digit._0) }
|
bModifier.weight(1f),
|
||||||
KeyboardButtonLight(wideButtonModifier, IconPack.Backspace, stringResource(R.string.delete_label), contentHeight, clearInput) { deleteDigit() }
|
IconPack.Key0,
|
||||||
|
Token.Digit._0,
|
||||||
|
contentHeight,
|
||||||
|
) { addDigit(Token.Digit._0) }
|
||||||
|
KeyboardButtonTertiary(
|
||||||
|
bModifier.weight(1f),
|
||||||
|
IconPack.Backspace,
|
||||||
|
stringResource(R.string.delete_label),
|
||||||
|
contentHeight,
|
||||||
|
clearInput,
|
||||||
|
) { deleteDigit() }
|
||||||
|
}
|
||||||
|
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardButtonTertiary(
|
||||||
|
bModifier,
|
||||||
|
IconPack.Backspace,
|
||||||
|
stringResource(R.string.delete_label),
|
||||||
|
contentHeight,
|
||||||
|
clearInput,
|
||||||
|
) { deleteDigit() }
|
||||||
|
}
|
||||||
|
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = {},
|
addDigit = {},
|
||||||
clearInput = {},
|
clearInput = {},
|
||||||
deleteDigit = {},
|
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 monthsInSeconds by lazy { BigDecimal("2592000") }
|
||||||
private val dayInSeconds by lazy { BigDecimal("86400") }
|
private val dayInSeconds by lazy { BigDecimal("86400") }
|
||||||
private val hourInSeconds by lazy { BigDecimal("3600") }
|
private val hourInSeconds by lazy { BigDecimal("3600") }
|
||||||
|
@ -86,18 +86,18 @@ private fun AboutScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TERMS AND CONDITIONS
|
// TERMS AND CONDITIONS
|
||||||
item {
|
// item {
|
||||||
ListItem(
|
// ListItem(
|
||||||
icon = Icons.Default.PrivacyTip,
|
// icon = Icons.Default.PrivacyTip,
|
||||||
headlineText = stringResource(R.string.settings_terms_and_conditions),
|
// headlineText = stringResource(R.string.settings_terms_and_conditions),
|
||||||
modifier = Modifier.clickable {
|
// modifier = Modifier.clickable {
|
||||||
openLink(
|
// openLink(
|
||||||
mContext,
|
// mContext,
|
||||||
"https://sadellie.github.io/unitto/terms",
|
// "https://sadellie.github.io/unitto/terms",
|
||||||
)
|
// )
|
||||||
},
|
// },
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
// PRIVACY POLICY
|
// PRIVACY POLICY
|
||||||
item {
|
item {
|
||||||
@ -107,7 +107,7 @@ private fun AboutScreen(
|
|||||||
modifier = Modifier.clickable {
|
modifier = Modifier.clickable {
|
||||||
openLink(
|
openLink(
|
||||||
mContext,
|
mContext,
|
||||||
"https://sadellie.github.io/unitto/privacy",
|
"https://github.com/Myzel394/NumberHub/blob/master/PRIVACY.md",
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -139,7 +139,7 @@ private fun PreviewConverterSettingsScreen() {
|
|||||||
precision = 3,
|
precision = 3,
|
||||||
outputFormat = OutputFormat.PLAIN,
|
outputFormat = OutputFormat.PLAIN,
|
||||||
unitConverterFormatTime = false,
|
unitConverterFormatTime = false,
|
||||||
unitConverterSorting = UnitsListSorting.USAGE,
|
unitConverterSorting = UnitsListSorting.SCALE_ASC,
|
||||||
shownUnitGroups = UnitGroup.entries,
|
shownUnitGroups = UnitGroup.entries,
|
||||||
unitConverterFavoritesOnly = false,
|
unitConverterFavoritesOnly = false,
|
||||||
enableToolsExperiment = false,
|
enableToolsExperiment = false,
|
||||||
|
@ -38,8 +38,8 @@ rootProject {
|
|||||||
target("**/*.kt")
|
target("**/*.kt")
|
||||||
targetExclude(
|
targetExclude(
|
||||||
"**/build/**/*.kt",
|
"**/build/**/*.kt",
|
||||||
"**/com/sadellie/unitto/data/converter/collections/*.kt",
|
"**/app/myzel394/numberhub/data/converter/collections/*.kt",
|
||||||
"**/com/sadellie/unitto/core/ui/common/icons/iconpack/*.kt",
|
"**/app/myzel394/numberhub/core/ui/common/icons/iconpack/*.kt",
|
||||||
)
|
)
|
||||||
ktlint(ktlintVersion).editorConfigOverride(
|
ktlint(ktlintVersion).editorConfigOverride(
|
||||||
mapOf(
|
mapOf(
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
[versions]
|
[versions]
|
||||||
versionCode = "2"
|
versionCode = "22"
|
||||||
versionName = "NumberHub"
|
versionName = "0.2.2"
|
||||||
|
|
||||||
androidxBrowserBrowser = "1.8.0"
|
androidxBrowserBrowser = "1.8.0"
|
||||||
androidGradlePlugin = "8.3.2"
|
androidGradlePlugin = "8.3.2"
|
||||||
androidxActivityActivityCompose = "1.9.0"
|
androidxActivityActivityCompose = "1.9.3"
|
||||||
androidxAppCompatAppCompat = "1.6.1"
|
androidxAppCompatAppCompat = "1.7.0"
|
||||||
androidxCompose = "1.6.6"
|
androidxCompose = "1.6.8"
|
||||||
androidxComposeCompiler = "1.5.9"
|
androidxComposeCompiler = "1.5.9"
|
||||||
androidxComposeMaterial3 = "1.2.1"
|
androidxComposeMaterial3 = "1.2.1"
|
||||||
androidxCoreCoreKts = "1.13.0"
|
androidxCoreCoreKts = "1.13.1"
|
||||||
androidxGlanceGlance = "1.0.0"
|
androidxGlanceGlance = "1.1.1"
|
||||||
androidxDatastoreDatastorePreferences = "1.1.0"
|
androidxDatastoreDatastorePreferences = "1.1.1"
|
||||||
androidxEspresso = "3.5.1"
|
androidxEspresso = "3.6.1"
|
||||||
androidxHiltHiltNavigationCompose = "1.2.0"
|
androidxHiltHiltNavigationCompose = "1.2.0"
|
||||||
androidxMacroBenchmark = "1.2.4"
|
androidxMacroBenchmark = "1.3.3"
|
||||||
androidxLifecycleLifecycleRuntimeCompose = "2.7.0"
|
androidxLifecycleLifecycleRuntimeCompose = "2.8.6"
|
||||||
androidxNavigationNavigationCompose = "2.7.7"
|
androidxNavigationNavigationCompose = "2.7.7"
|
||||||
androidxProfileinstallerProfileinstaller = "1.3.1"
|
androidxProfileinstallerProfileinstaller = "1.4.1"
|
||||||
androidxRoom = "2.6.1"
|
androidxRoom = "2.6.1"
|
||||||
androidxTest = "1.5.0"
|
androidxTest = "1.6.1"
|
||||||
androidxTestExtJunitKtx = "1.1.5"
|
androidxTestExtJunitKtx = "1.2.1"
|
||||||
androidxTestRunner = "1.5.2"
|
androidxTestRunner = "1.6.2"
|
||||||
androidxUiAutomator = "2.3.0"
|
androidxUiAutomator = "2.3.0"
|
||||||
androidxWindowWindow = "1.2.0"
|
androidxWindowWindow = "1.3.0"
|
||||||
androidxWorkWorkRuntimeKtx = "2.9.0"
|
androidxWorkWorkRuntimeKtx = "2.9.1"
|
||||||
comAndroidToolsDesugarJdkLibs = "2.0.4"
|
comAndroidToolsDesugarJdkLibs = "2.1.2"
|
||||||
comGithubSadellieThemmo = "1.3.0"
|
comGithubSadellieThemmo = "1.3.0"
|
||||||
comGoogleDagger = "2.49"
|
comGoogleDagger = "2.49"
|
||||||
comSquareupMoshiMoshiKotlin = "1.15.0"
|
comSquareupMoshiMoshiKotlin = "1.15.0"
|
||||||
|
15
logo.svg
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="108" height="108" rx="54" fill="white"/>
|
||||||
|
<path d="M72.1693 56.3386C76.3679 56.3386 80.3945 58.0065 83.3633 60.9753C86.3321 63.9442 88 67.9708 88 72.1693C88 76.3679 86.3321 80.3945 83.3633 83.3633C80.3945 86.3321 76.3679 88 72.1693 88C67.9707 88 63.9441 86.3321 60.9753 83.3633C58.0065 80.3945 56.3386 76.3679 56.3386 72.1693C56.3386 67.9708 58.0065 63.9442 60.9753 60.9753C63.9441 58.0065 67.9707 56.3386 72.1693 56.3386Z" fill="#378648"/>
|
||||||
|
<path d="M63.1746 72.1693C63.1746 70.9766 64.1406 70.0106 65.3333 70.0106H79.0053C80.198 70.0106 81.164 70.9766 81.164 72.1693C81.164 73.362 80.198 74.328 79.0053 74.328H65.3333C64.1406 74.328 63.1746 73.362 63.1746 72.1693Z" fill="#FCFCF7"/>
|
||||||
|
<path d="M70.0106 65.6931C70.0106 64.5004 70.9766 63.5344 72.1693 63.5344C73.362 63.5344 74.3281 64.5004 74.3281 65.6931C74.3281 66.8858 73.362 67.8519 72.1693 67.8519C70.9766 67.8519 70.0106 66.8858 70.0106 65.6931Z" fill="#FCFCF7"/>
|
||||||
|
<path d="M70.0106 78.6455C70.0106 77.4528 70.9766 76.4868 72.1693 76.4868C73.362 76.4868 74.3281 77.4528 74.3281 78.6455C74.3281 79.8382 73.362 80.8042 72.1693 80.8042C70.9766 80.8042 70.0106 79.8382 70.0106 78.6455Z" fill="#FCFCF7"/>
|
||||||
|
<path d="M35.8307 56.3386C40.0292 56.3386 44.0558 58.0065 47.0247 60.9753C49.9935 63.9442 51.6614 67.9708 51.6614 72.1693C51.6614 76.3679 49.9935 80.3945 47.0247 83.3633C44.0558 86.3321 40.0292 88 35.8307 88C31.6321 88 27.6055 86.3321 24.6367 83.3633C21.6679 80.3945 20 76.3679 20 72.1693C20 67.9708 21.6679 63.9442 24.6367 60.9753C27.6055 58.0065 31.6321 56.3386 35.8307 56.3386Z" fill="#378648"/>
|
||||||
|
<path d="M28.6619 65.0005C29.4175 64.2449 30.6443 64.2449 31.3999 65.0005L43.138 76.7386C43.8935 77.4942 43.8935 78.721 43.138 79.4766C42.3824 80.2321 41.1555 80.2321 40.4 79.4766L28.6619 67.7385C27.9063 66.9829 27.9063 65.7561 28.6619 65.0005Z" fill="#FCFCF7"/>
|
||||||
|
<path d="M43.138 65.0005C43.8935 65.7561 43.8935 66.9829 43.138 67.7385L31.3999 79.4766C30.6443 80.2321 29.4175 80.2321 28.6619 79.4766C27.9063 78.721 27.9063 77.4942 28.6619 76.7386L40.4 65.0005C41.1555 64.2449 42.3824 64.2449 43.138 65.0005Z" fill="#FCFCF7"/>
|
||||||
|
<path d="M72.1693 20C76.3679 20 80.3945 21.6679 83.3633 24.6367C86.3321 27.6055 88 31.6321 88 35.8307C88 40.0292 86.3321 44.0558 83.3633 47.0247C80.3945 49.9935 76.3679 51.6614 72.1693 51.6614C67.9707 51.6614 63.9441 49.9935 60.9753 47.0247C58.0065 44.0558 56.3386 40.0292 56.3386 35.8307C56.3386 31.6321 58.0065 27.6055 60.9753 24.6367C63.9441 21.6679 67.9707 20 72.1693 20Z" fill="#378648"/>
|
||||||
|
<path d="M63.1746 35.8307C63.1746 34.638 64.1406 33.672 65.3333 33.672H79.0053C80.198 33.672 81.164 34.638 81.164 35.8307C81.164 37.0234 80.198 37.9894 79.0053 37.9894H65.3333C64.1406 37.9894 63.1746 37.0234 63.1746 35.8307Z" fill="#FCFCF7"/>
|
||||||
|
<path d="M35.8307 20C40.0292 20 44.0558 21.6679 47.0247 24.6367C49.9935 27.6055 51.6614 31.6321 51.6614 35.8307C51.6614 40.0292 49.9935 44.0558 47.0247 47.0247C44.0558 49.9935 40.0292 51.6614 35.8307 51.6614C31.6321 51.6614 27.6055 49.9935 24.6367 47.0247C21.6679 44.0558 20 40.0292 20 35.8307C20 31.6321 21.6679 27.6055 24.6367 24.6367C27.6055 21.6679 31.6321 20 35.8307 20Z" fill="#378648"/>
|
||||||
|
<path d="M26.836 35.8307C26.836 34.638 27.802 33.672 28.9947 33.672H42.6667C43.8594 33.672 44.8254 34.638 44.8254 35.8307C44.8254 37.0234 43.8594 37.9894 42.6667 37.9894H28.9947C27.802 37.9894 26.836 37.0234 26.836 35.8307Z" fill="#FCFCF7"/>
|
||||||
|
<path d="M35.8307 26.836C37.0234 26.836 37.9894 27.802 37.9894 28.9947V42.6667C37.9894 43.8594 37.0234 44.8254 35.8307 44.8254C34.638 44.8254 33.672 43.8594 33.672 42.6667V28.9947C33.672 27.802 34.638 26.836 35.8307 26.836Z" fill="#FCFCF7"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
BIN
readme_content/github-badge.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
readme_content/google-play-badge.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
readme_content/izzyondroid-badge.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
readme_content/obtainium-badge.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
readme_content/showcase.png
Normal file
After Width: | Height: | Size: 65 KiB |