mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-10 09:01:55 +01:00
Merge branch 'master' into plot_temperature
# Conflicts: # app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityChartsActivity.java # app/src/main/res/values/arrays.xml # app/src/main/res/values/values.xml
This commit is contained in:
commit
1ff782c08e
@ -1,49 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
You can use the `Preview` tab ^ above to see final rendering of your report. Use `x` in brackets ([x]) to "check" a checkbox.
|
||||
|
||||
If you just have a question, please ask first in the user chatroom in Matrix: [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
|
||||
|
||||
|
||||
#### Before reporting a bug, please confirm the following:
|
||||
- [ ] I have read the [wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki), and I didn't find a solution to my problem / an answer to my question.
|
||||
- [ ] I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
|
||||
- [ ] If you upload an image or other content, please make sure you have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md)
|
||||
|
||||
### Where did you get Gadgetbridge from:
|
||||
* [ ] F-Droid
|
||||
* [ ] Gadgetbridge Nightly F-Droid repository
|
||||
* [ ] Bangle.js Gadgetbridge from the Play Store
|
||||
* [ ] I built it myself from source code (specify tag / commit)
|
||||
* [ ] I previously used Gadgetbridge from other sources and then updated to F-Droid version
|
||||
|
||||
### Your Gadgetbridge version is:
|
||||
|
||||
(This can be found in Gadgetbridge - Menu - About: Version and Commit)
|
||||
|
||||
#### Your issue is:
|
||||
*If possible, please attach [logs](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Log-Files)! that might help identifying the problem.*
|
||||
*Long logs can be also included but make sure to tuck them into the `details` tag:*
|
||||
|
||||
<details>
|
||||
<summary>Click to see my log under this fold</summary>
|
||||
|
||||
```
|
||||
Here go lines of your log.
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
#### Your wearable device is:
|
||||
|
||||
*Please specify model and firmware version if possible*
|
||||
|
||||
#### Your Android version/manufacturer flavor is:
|
||||
|
||||
|
||||
*New issues about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.*
|
||||
|
||||
Please use `Preview` tab above to see final rendering of your report before submitting.
|
@ -1,49 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
You can use the `Preview` tab ^ above to see final rendering of your report. Use `x` in brackets ([x]) to "check" a checkbox.
|
||||
|
||||
If you just have a question, please ask first in the user chatroom in Matrix: [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
|
||||
|
||||
|
||||
#### Before reporting a bug, please confirm the following:
|
||||
- [ ] I have read the [wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki), and I didn't find a solution to my problem / an answer to my question.
|
||||
- [ ] I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
|
||||
- [ ] If you upload an image or other content, please make sure you have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md)
|
||||
|
||||
### Where did you get Gadgetbridge from:
|
||||
* [ ] F-Droid
|
||||
* [ ] Gadgetbridge Nightly F-Droid repository
|
||||
* [ ] Bangle.js Gadgetbridge from the Play Store
|
||||
* [ ] I built it myself from source code (specify tag / commit)
|
||||
* [ ] I previously used Gadgetbridge from other sources and then updated to F-Droid version
|
||||
|
||||
### Your Gadgetbridge version is:
|
||||
|
||||
(This can be found in Gadgetbridge - Menu - About: Version and Commit)
|
||||
|
||||
#### Your issue is:
|
||||
*If possible, please attach [logs](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Log-Files)! that might help identifying the problem.*
|
||||
*Long logs can be also included but make sure to tuck them into the `details` tag:*
|
||||
|
||||
<details>
|
||||
<summary>Click to see my log under this fold</summary>
|
||||
|
||||
```
|
||||
Here go lines of your log.
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
#### Your wearable device is:
|
||||
|
||||
*Please specify model and firmware version if possible*
|
||||
|
||||
#### Your Android version/manufacturer flavor is:
|
||||
|
||||
|
||||
*New issues about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.*
|
||||
|
||||
Please use `Preview` tab above to see final rendering of your report before submitting.
|
@ -1,51 +0,0 @@
|
||||
---
|
||||
name: Device request
|
||||
about: Request for a new device
|
||||
labels:
|
||||
- device request
|
||||
---
|
||||
|
||||
You are trying to submit a request for a device implementation into Gadgetbridge. We cannot make any promise that the device will be implemented, as adding an implementation for a new device requires either an experienced or a willing to learn developer, ideally with the device at hand. Without that, you may try to submit a device request and see if anyone steps up and implements it and you are basically indicating that you have the device and are willing to help with testing, should anyone try to add this device to Gadgetbridge.
|
||||
|
||||
You can use the `Preview` tab ^ above to see final rendering of your report. Use `x` in brackets ([x]) to "check" a checkbox.
|
||||
|
||||
#### Before proceeding further, please confirm the following:
|
||||
- [ ] I have read the [wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki), and I didn't find this device mentioned there
|
||||
- [ ] I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find this device mentioned there
|
||||
- [ ] Please make sure you have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md)
|
||||
|
||||
#### Device information
|
||||
|
||||
- Provide device name, manufacturer and similarity to other devices:
|
||||
|
||||
|
||||
- Ideally, use an Android Bluetooth scanner app like nRF Connect or BLExplorer and provide screenshots of the scanned device from that app. This provides a name and some available UUIDs, which are needed for implementation. You may want to blur a MAC address for privacy reasons.
|
||||
|
||||
|
||||
- Specify model and firmware version if possible:
|
||||
|
||||
|
||||
- Please let us know if you have the device and if you are able to provide logs and testing:
|
||||
|
||||
|
||||
- If you want to help getting this device supported (and thus speed up the process), please take a look at:
|
||||
- what you can do as a user: [Support for a new Device](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Support-for-a-new-Device)
|
||||
- if you are a developer and could maybe even help getting the code ready: [New Device Tutorial](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/New-Device-Tutorial)
|
||||
|
||||
- If possible, please attach [logs](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Log-Files)! which might help to implement the device support into Gadgetbridge.
|
||||
*Long logs can be also included in the text but make sure to tuck them into the `details` tag below:*
|
||||
|
||||
<details>
|
||||
<summary>Click to see my log under this fold</summary>
|
||||
|
||||
```
|
||||
Here go lines of your log.
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
|
||||
*New issues about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.*
|
||||
|
||||
Please use `Preview` tab above to see final rendering of your report before submitting.
|
@ -1,40 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest a feature or an idea
|
||||
---
|
||||
You can use the `Preview` tab ^ above to see final rendering of your report. Use `x` in brackets ([x]) to "check" a checkbox.
|
||||
|
||||
If you just have a question, please ask first in the user chatroom in Matrix: [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
|
||||
|
||||
#### Before requesting a new feature, please confirm the following:
|
||||
- [ ] I have read the [wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki), and I didn't find a solution to my problem / an answer to my question.
|
||||
- [ ] I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
|
||||
- [ ] If you upload an image or other content, please make sure you have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md)
|
||||
|
||||
#### Log files
|
||||
*If applicable, please attach [logs](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Log-Files)*
|
||||
*Long logs can be also included in the text but make sure to tuck them into the `details` tag below:*
|
||||
|
||||
<details>
|
||||
<summary>Click to see my log under this fold</summary>
|
||||
|
||||
```
|
||||
Here go lines of your log.
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
#### Your wearable device is:
|
||||
|
||||
*Please specify model and firmware version if possible*
|
||||
|
||||
#### Your Android version/manufacturer flavor is:
|
||||
|
||||
#### Your Gadgetbridge version is:
|
||||
|
||||
|
||||
|
||||
*New requests about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.*
|
||||
|
||||
Please use `Preview` tab above to see final rendering of your report before submitting.
|
||||
|
@ -1,14 +0,0 @@
|
||||
Thank you for your contribution! 🎉
|
||||
|
||||
Please make sure that you:
|
||||
|
||||
- Use `git rebase` to bring your branch up to date, do not use a merge commit
|
||||
for that
|
||||
- Do not add translations by editing the language variants of strings.xml as
|
||||
that creates merge conflicts between Codeberg git repo and Weblate git repo,
|
||||
use Weblate https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/
|
||||
- do not use `e.printStacktrace()`, use slf4j logger or `GB.toast` for logging
|
||||
as per https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Developer-Documentation#logging
|
||||
- Please erase these hints from this PR :), thank you!
|
||||
---
|
||||
|
77
.gitea/issue_template/bug_report.yml
Normal file
77
.gitea/issue_template/bug_report.yml
Normal file
@ -0,0 +1,77 @@
|
||||
name: Bug report
|
||||
about: Create a report to help us improve.
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to make Gadgetbridge better!
|
||||
|
||||
If you just have a question, please ask first in the user chatroom in Matrix at [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please confirm that;
|
||||
options:
|
||||
- label: I have checked the [website](https://gadgetbridge.org), and I didn't find a solution to my problem / an answer to my question.
|
||||
required: true
|
||||
- label: I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
|
||||
required: true
|
||||
- label: I have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md) for images or other type of content that I included here.
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: source
|
||||
attributes:
|
||||
label: Where did you get Gadgetbridge from?
|
||||
options:
|
||||
- F-Droid
|
||||
- Gadgetbridge Nightly F-Droid repository
|
||||
- Bangle.js Gadgetbridge from the Play Store
|
||||
- I built it myself from source code
|
||||
- I previously used Gadgetbridge from other sources and then updated to F-Droid version
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: What is your Gadgetbridge version?
|
||||
description: |
|
||||
This can be found in "Menu > About > Version" in Gadgetbridge.
|
||||
Also include tag / commit SHA if you built Gadgetbridge from the source.
|
||||
placeholder: e.g. "0.77.0" or "0.77.0-2618adac1" to include commit
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: content
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: >
|
||||
Please note that new issues about already solved/documented topics
|
||||
**could be closed without further comments.** Same for too generic or incomplete reports.
|
||||
placeholder: If you want to include logs, don't include it here. Use the next text field for that.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Do you have logs?
|
||||
description: >
|
||||
If possible, please attach [logs](https://gadgetbridge.org/internals/topics/logs/)
|
||||
that might help identifying the problem. This will be automatically formatted into
|
||||
code, so no need for backticks.
|
||||
render: shell
|
||||
- type: input
|
||||
id: gadget
|
||||
attributes:
|
||||
label: What gadget do you use?
|
||||
description: >
|
||||
Please specify model and firmware version if possible. Leave blank if you believe the
|
||||
issue is not specific to the gadget that you currently use with Gadgetbridge.
|
||||
placeholder: e.g. ExampleWatch A1 with 0.1 firmware
|
||||
- type: input
|
||||
id: android
|
||||
attributes:
|
||||
label: What is your Android version/manufacturer flavor?
|
||||
description: >
|
||||
Android phone manufacturers may customise the Android source code as they wish, so
|
||||
if you are using a phone that running a vendor-exclusive system (like MIUI) or if
|
||||
you use a custom ROM, make sure to also include the name of the OS/ROM.
|
||||
placeholder: e.g. LineageOS 20 based on Android 13
|
11
.gitea/issue_template/config.yml
Normal file
11
.gitea/issue_template/config.yml
Normal file
@ -0,0 +1,11 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Ask a question
|
||||
url: https://matrix.to/#/#gadgetbridge:matrix.org
|
||||
about: If you just have a question, please ask in the user chatroom in Matrix.
|
||||
- name: Website
|
||||
url: https://gadgetbridge.org
|
||||
about: Visit Gadgetbridge website for FAQ, getting started and common troubleshooting.
|
||||
- name: See supported gadgets
|
||||
url: https://gadgetbridge.org/gadgets/
|
||||
about: List of all supported gadget vendors and models in Gadgetbridge.
|
77
.gitea/issue_template/device_request.yml
Normal file
77
.gitea/issue_template/device_request.yml
Normal file
@ -0,0 +1,77 @@
|
||||
name: Device request
|
||||
about: Request for a new device/gadget.
|
||||
labels:
|
||||
- device request
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
You are trying to submit a request for a device implementation into Gadgetbridge.
|
||||
**We cannot make any promise that the device will be implemented**, as adding an implementation
|
||||
for a new device requires either an experienced or a willing to learn developer,
|
||||
ideally with the device at hand. Without that, you may try to submit a device request
|
||||
and see if anyone steps up and implements it and you are basically indicating that you
|
||||
have the device and are willing to help with testing, should anyone try to add
|
||||
this device to Gadgetbridge.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to make Gadgetbridge better!
|
||||
|
||||
If you just have a question, please ask first in the user chatroom in Matrix at [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please confirm that;
|
||||
options:
|
||||
- label: I have checked the [website](https://gadgetbridge.org) and [gadget list](https://gadgetbridge.org/gadgets/), and I didn't find this device mentioned there.
|
||||
required: true
|
||||
- label: I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find this device mentioned there.
|
||||
required: true
|
||||
- label: I have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md) for images or other type of content that I included here.
|
||||
required: true
|
||||
- type: input
|
||||
id: gadget
|
||||
attributes:
|
||||
label: Which gadget are you requesting support for?
|
||||
description: Please specify name, manufacturer, model and firmware version if possible.
|
||||
placeholder: e.g. ExampleWatch A1 with 0.1 firmware
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Does this gadget have similarities to other gadgets?
|
||||
description: >
|
||||
If the gadget you request support for has similarities to other gadgets that we currently support,
|
||||
it is more likely for us (still, not guaranteed) to add support for your gadget too.
|
||||
- type: textarea
|
||||
id: info
|
||||
attributes:
|
||||
label: Device information
|
||||
description: >
|
||||
Include all details about the gadget that will be useful to us when implementing a support for this gadget.
|
||||
|
||||
Ideally, use an Android Bluetooth scanner app like nRF Connect or BLExplorer and provide screenshots
|
||||
of the scanned gadget from that app. This provides a name and some available UUIDs, which are needed
|
||||
for implementation. You may want to blur MAC addresses for privacy reasons.
|
||||
placeholder: If you want to include logs, don't include it here. Use the next text field for that.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Do you have logs?
|
||||
description: >
|
||||
If possible, please attach [logs](https://gadgetbridge.org/internals/topics/logs/)
|
||||
which might help to implement the device support into Gadgetbridge. This will be automatically
|
||||
formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
- type: dropdown
|
||||
id: source
|
||||
attributes:
|
||||
label: Do you have the gadget and are you able to help us for testing?
|
||||
options:
|
||||
- Yes, I have the gadget and I'm willing to provide further feedback and help testing.
|
||||
- No, I don't have the gadget or/and I'm not able to help during the development.
|
||||
validations:
|
||||
required: true
|
76
.gitea/issue_template/feature_request.yml
Normal file
76
.gitea/issue_template/feature_request.yml
Normal file
@ -0,0 +1,76 @@
|
||||
name: Feature request
|
||||
about: Suggest a feature or an idea.
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to make Gadgetbridge better!
|
||||
|
||||
If you just have a question, please ask first in the user chatroom in Matrix at [`#gadgetbridge:matrix.org`](https://matrix.to/#/#gadgetbridge:matrix.org)
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please confirm that;
|
||||
options:
|
||||
- label: I have checked the [website](https://gadgetbridge.org), and I didn't find a solution to my problem / an answer to my question.
|
||||
required: true
|
||||
- label: I have searched the [issues](https://codeberg.org/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
|
||||
required: true
|
||||
- label: I have read and understood the [Codeberg Terms of Use](https://codeberg.org/Codeberg/org/src/branch/main/TermsOfUse.md) for images or other type of content that I included here.
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: source
|
||||
attributes:
|
||||
label: Where did you get Gadgetbridge from?
|
||||
options:
|
||||
- F-Droid
|
||||
- Gadgetbridge Nightly F-Droid repository
|
||||
- Bangle.js Gadgetbridge from the Play Store
|
||||
- I built it myself from source code
|
||||
- I previously used Gadgetbridge from other sources and then updated to F-Droid version
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: What is your Gadgetbridge version?
|
||||
description: |
|
||||
This can be found in "Menu > About > Version" in Gadgetbridge.
|
||||
Also include tag / commit SHA if you built Gadgetbridge from the source.
|
||||
placeholder: e.g. "0.77.0" or "0.77.0-2618adac1" to include commit
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: content
|
||||
attributes:
|
||||
label: What is your suggestion/idea?
|
||||
description: >
|
||||
Please note that new requests about already solved/documented topics
|
||||
**could be closed without further comments.** Same for too generic or incomplete reports.
|
||||
placeholder: If you want to include logs, don't include it here. Use the next text field for that.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Do you have logs?
|
||||
description: >
|
||||
If possible, please attach [logs.](https://gadgetbridge.org/internals/topics/logs/)
|
||||
This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
- type: input
|
||||
id: gadget
|
||||
attributes:
|
||||
label: What gadget do you use?
|
||||
description: >
|
||||
Please specify model and firmware version if possible. Leave blank if you believe the
|
||||
issue is not specific to the gadget that you currently use with Gadgetbridge.
|
||||
placeholder: e.g. ExampleWatch A1 with 0.1 firmware
|
||||
- type: input
|
||||
id: android
|
||||
attributes:
|
||||
label: What is your Android version/manufacturer flavor?
|
||||
description: >
|
||||
Android phone manufacturers may customise the Android source code as they wish, so
|
||||
if you are using a phone that running a vendor-exclusive system (like MIUI) or if
|
||||
you use a custom ROM, make sure to also include the name of the OS/ROM.
|
||||
placeholder: e.g. LineageOS 20 based on Android 13
|
16
.gitea/pull_request_template.md
Normal file
16
.gitea/pull_request_template.md
Normal file
@ -0,0 +1,16 @@
|
||||
<!--
|
||||
Thank you for your contribution! 🎉
|
||||
|
||||
Please make sure that you:
|
||||
|
||||
- Use `git rebase` to bring your branch up to date, do not use a merge commit for that.
|
||||
|
||||
- Do not add translations by editing the language variants of strings.xml as that
|
||||
creates merge conflicts between Codeberg git repo and Weblate git repo,
|
||||
use Weblate https://hosted.weblate.org/projects/freeyourgadget/gadgetbridge/
|
||||
|
||||
- Do not use `e.printStacktrace()`, use slf4j logger or `GB.toast` for logging
|
||||
as per https://gadgetbridge.org/internals/development/project-overview/#logging
|
||||
|
||||
You can erase this comment from PR description, thank you!
|
||||
-->
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,6 +1,6 @@
|
||||
[submodule "fossil-hr-watchface"]
|
||||
path = external/fossil-hr-watchface
|
||||
url = https://codeberg.org/Freeyourgadget/fossil-hr-watchface
|
||||
[submodule "jerryscript"]
|
||||
path = external/jerryscript
|
||||
url = https://github.com/jerryscript-project/jerryscript
|
||||
[submodule "fossil-hr-gbapps"]
|
||||
path = external/fossil-hr-gbapps
|
||||
url = https://codeberg.org/Freeyourgadget/fossil-hr-gbapps
|
||||
|
@ -12,5 +12,8 @@ steps:
|
||||
#https://github.com/woodpecker-ci/woodpecker/issues/687
|
||||
|
||||
when:
|
||||
event:
|
||||
exclude: ['cron', 'deployment']
|
||||
# Everything except cron (nightly) and deployment
|
||||
- event: push
|
||||
- event: pull_request
|
||||
- event: tag
|
||||
- event: manual
|
||||
|
@ -26,8 +26,8 @@ steps:
|
||||
- if [ -f .do_not_build ]; then return 0; fi
|
||||
# build the apks
|
||||
- echo "$${SIGNING_KEY}" | base64 -d > app/keystore.p12
|
||||
- ./gradlew assembleMainNightly -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
|
||||
- ./gradlew assembleMainNopebble -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
|
||||
- ./gradlew assembleMainlineNightly -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
|
||||
- ./gradlew assembleMainlineNopebble -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
|
||||
- ./gradlew assembleBanglejsNightly -Dnightly_store_file="keystore.p12" -Dnightly_store_password="$${KEYSTOREPASS}" -Dnightly_key_alias="gadgetbridge" -Dnightly_key_password="$${KEYPASS}"
|
||||
secrets: [ signing_key, keystorepass, keypass ]
|
||||
|
||||
|
@ -12,5 +12,8 @@ steps:
|
||||
#https://github.com/woodpecker-ci/woodpecker/issues/687
|
||||
|
||||
when:
|
||||
event:
|
||||
exclude: ['cron', 'deployment']
|
||||
# Everything except cron (nightly) and deployment
|
||||
- event: push
|
||||
- event: pull_request
|
||||
- event: tag
|
||||
- event: manual
|
||||
|
@ -12,5 +12,8 @@ steps:
|
||||
#https://github.com/woodpecker-ci/woodpecker/issues/687
|
||||
|
||||
when:
|
||||
event:
|
||||
exclude: ['cron', 'deployment']
|
||||
# Everything except cron (nightly) and deployment
|
||||
- event: push
|
||||
- event: pull_request
|
||||
- event: tag
|
||||
- event: manual
|
||||
|
105
CHANGELOG.md
105
CHANGELOG.md
@ -1,35 +1,136 @@
|
||||
### Changelog
|
||||
|
||||
#### Next release (WIP)
|
||||
#### 0.79.0
|
||||
* Initial support for Honor Magic Watch 2
|
||||
* Initial support for Mijia MHO-C303
|
||||
* Initial support for Nothing CMF Watch Pro
|
||||
* Initial support for Sony WI-SP600N
|
||||
* Experimental support for Redmi Watch 2
|
||||
* Experimental support for Xiaomi Smart Band 8 Pro
|
||||
* Experimental support for Xiaomi Watch S1 Pro
|
||||
* Experimental support for Xiaomi Watch S1
|
||||
* Experimental support for Xiaomi Watch S3
|
||||
* Galaxy Buds2 Pro: Fix recognition of some versions
|
||||
* Huawei Watch GT 2: Fix pairing
|
||||
* Redmi Smart Band Pro: Fix password digits
|
||||
* Pebble: Fix app configuration page
|
||||
* Pebble 2: Fix pairing issue
|
||||
* PineTime: Fix weather forecast on InfiniTime's new simple weather
|
||||
* Xiaomi: Fix sleep sometimes extending past the wakeup time
|
||||
* Xiaomi: Request battery level and charging state periodically
|
||||
* Xiaomi: Fix sleep stage parsing for some devices
|
||||
* Zepp OS: Improve device discovery
|
||||
* Zepp OS: Fix weather not working on some devices
|
||||
* Zepp OS: Prevent crash when installing large firmware updates
|
||||
* Fix sport activity summary group order
|
||||
* Fix reconnection to devices failing occasionally
|
||||
|
||||
#### 0.78.0
|
||||
* Initial support for Honor Band 3,4,5,6
|
||||
* Initial support for Huawei Band 4, 4 Pro, 6, 7, 3e, 4e
|
||||
* Initial support for Huawei Talk Band B6
|
||||
* Initial support for Huawei Watch GT, GT 2
|
||||
* Initial support for Mijia LYWSD03MMC
|
||||
* Initial support for Nothing Ear (2)
|
||||
* Initial support for Nothing Ear (Stick)
|
||||
* Experimental support for Honor Band 7
|
||||
* Experimental support for Redmi Watch 2 Lite
|
||||
* Experimental support for Redmi Smart Band Pro
|
||||
* Casio GBX100: Add support for snooze alarm
|
||||
* Fossil/Skagen Hybrids: Update navigationApp to 1.1
|
||||
* Huami: Fetch SpO2 on devices that support it
|
||||
* Pebble: Attempt to fix app configuration webview
|
||||
* PineTime: Add support for InfiniTime's new simple weather
|
||||
* PineTime: Fix freeze and reboot when upgrading firmware
|
||||
* Pixoo: Enable sending images (non-persistent)
|
||||
* Pixoo: Get and send alarms
|
||||
* Pixoo: Set custom device name
|
||||
* Pixoo: support "clap hands to turn off screen" and "sleep after silence" settings
|
||||
* Xiaomi: Improve activity and workout parsing
|
||||
* Xiaomi: Improve stability and fix some crashes
|
||||
* Xiaomi: Improve weather
|
||||
* Xiaomi: Parse sleep stages
|
||||
* Add a notifications channel for connection status notifications
|
||||
* Improve automatic connection to all or previous devices
|
||||
* Fix devices sometimes staying stuck in a "Connecting" state
|
||||
* Map some missing Google Maps navigation actions
|
||||
|
||||
#### 0.77.0
|
||||
* Initial support for Amazfit Balance
|
||||
* Initial support for Amazfit Active
|
||||
* Initial support for ColaCao 2021
|
||||
* Initial support for ColaCao 2023
|
||||
* Initial support for Femometer Vinca II
|
||||
* Initial support for Mijia LYWSD02MMC variant
|
||||
* Initial support for Sony Wena 3
|
||||
* Experimental support for Divoom Pixoo
|
||||
* Experimental support for Sony WF-1000XM5
|
||||
* Experimental support for Amazfit Active Edge
|
||||
* Experimental support for Mi Band 7 Pro (Xiaomi Smart Band 7 Pro)
|
||||
* Experimental support for Mi Band 8 (Xiaomi Smart Band 8)
|
||||
* Experimental support for Mi Watch Lite
|
||||
* Experimental support for Mi Watch Color Sport
|
||||
* Experimental support for Redmi Smart Band 2
|
||||
* Experimental support for Redmi Watch 3 Active
|
||||
* Experimental support for Xiaomi Watch S1 Active
|
||||
* Amazfit Band 7: Add alexa menu entries
|
||||
* Amazfit GTR 3 Pro: Fix firmware and watchface upload
|
||||
* Amazfit T-Rex: Fix activity summary parsing
|
||||
* Amazfit T-Rex Pro: Add activate display on lift sensitivity
|
||||
* AsteroidOS: Add more supported watch models
|
||||
* AsteroidOS: Fix media info
|
||||
* AsteroidOS: Fix notification dismissal
|
||||
* Bangle.js: Add loyalty cards integration with Catima
|
||||
* Bangle.js: Ensure SMS messages have src field set to "SMS Message"
|
||||
* Bangle.js: Fix GPS speed
|
||||
* Bangle.js: Improve handling of chinese characters
|
||||
* Bangle.js: Lower threshold for low battery warning
|
||||
* Bangle.js: Recover from device initialization failure
|
||||
* Casio GBX100/GBD-200: Fix first connect
|
||||
* Casio GB5600/6900/STB-1000: Fix pairing
|
||||
* Casio GDB-200: Fix notification timestamp
|
||||
* Casio GDB-200: Fixed notification categories and default category
|
||||
* Casio GDB-200: Allow preview of notification message alongside title
|
||||
* Casio GDB-200: Fixed find my phone feature
|
||||
* Intent API: Add debug action for test new function
|
||||
* Fossil/Skagen Hybrids: Add new navigation app
|
||||
* Fossil/Skagen Hybrids: Allow configuring call rejection method
|
||||
* Fossil/Skagen Hybrids: Fix some preference crashes on the nightly
|
||||
* Fossil/Skagen Hybrids: Reduce toasts on release builds
|
||||
* Fossil/Skagen Hybrids: Show device specific settings in more logical order
|
||||
* Huami: Toggle phone silent mode from band
|
||||
* Message privacy: Add mode Hide only body
|
||||
* Mijia LYWSD02: Add battery
|
||||
* Mijia LYWSD02: Add low battery notification
|
||||
* Mijia LYWSD02: Set temperature unit
|
||||
* Mijia LYWSD02: Fix battery drain while connected
|
||||
* PineTime: Display app name for VoIP app calls
|
||||
* PineTime: Honor Sync time setting on connect
|
||||
* PineTime: Improve notification handling
|
||||
* PineTime: Reduce weather memory usage
|
||||
* Withings Steel HR: Fix crash when calibrating hands on the nightly
|
||||
* Zepp OS: Add blood oxygen graph
|
||||
* Zepp OS: Add workout codes for hiking and outdoor swimming
|
||||
* Zepp OS: Allow disabling app notifications per device
|
||||
* Zepp OS: Attempt to fix activity fetch operation getting stuck
|
||||
* Zepp OS: Display swimming activity data
|
||||
* Zepp OS: Fix health settings on older Zepp OS versions
|
||||
* Zepp OS: Fix setting of unknown button press apps
|
||||
* Zepp OS: Fix sunrise and moon dates being off by local time + UTC offset
|
||||
* Zepp OS: Map hiking, outdoor swimming, climbing and table tennis activity types
|
||||
* Add transliteration for Latvian and Common Symbols
|
||||
* Zepp OS: Toggle phone silent mode from band
|
||||
* Add transliteration for Latvian, Hungarian, Common Symbols
|
||||
* Allow multiple device actions to be triggered for the same event
|
||||
* Allow toggling DND through device actions
|
||||
* Autodetect OsmAnd package name and make it configurable
|
||||
* Improve ASCII transliterator
|
||||
* Make GMaps navigation handler follow the "navigation forwarding" setting
|
||||
* Support selecting enabled navigation apps
|
||||
* Allow ignore notifications from work profile apps
|
||||
* Display alias in low battery notification
|
||||
* Fix crash when pairing current device as companion
|
||||
* Fix emoji when a transliterator is enabled
|
||||
* Fix UV Index and rain probability for some weather apps
|
||||
* Improve device discovery stability and fix freezes
|
||||
* Improve Telegram and COL Reminder notifications
|
||||
* Replace old-style preference switch with Material 3 switch
|
||||
|
278
CONTRIBUTORS.rst
278
CONTRIBUTORS.rst
@ -24,89 +24,143 @@
|
||||
|
||||
* Andreas Shimokawa <shimokawa@fsfe.org>
|
||||
* Carsten Pfeiffer <cpfeiffer@users.noreply.github.com>
|
||||
* José Rebelo <joserebelo@outlook.com>
|
||||
* Daniele Gobbetti <daniele+github@gobbetti.name>
|
||||
* Daniel Dakhno <dakhnod@gmail.com>
|
||||
* Petr Vaněk <petr@linuks.cz>
|
||||
* Yaron Shahrabani <sh.yaron@gmail.com>
|
||||
* Allan Nordhøy <epost@anotheragency.no>
|
||||
* Taavi Eomäe <taavi.eomae+github@gmail.com>
|
||||
* Daniel Dakhno <dakhnod@gmail.com>
|
||||
* 陈少举 <oshirisu.red@gmail.com>
|
||||
* Rafael Fontenelle <rafaelff@gnome.org>
|
||||
* João Paulo Barraca <jpbarraca@gmail.com>
|
||||
* Sebastian Kranz <tklightforce@googlemail.com>
|
||||
* Arjan Schrijver <arjan5@noreply.codeberg.org>
|
||||
* Vincèn PUJOL <vincen@vincen.org>
|
||||
* Oğuz Ersen <oguzersen@protonmail.com>
|
||||
* Allan Nordhøy <epost@anotheragency.no>
|
||||
* Ihor Hordiichuk <igor_ck@outlook.com>
|
||||
* nautilusx <mail.ka@mailbox.org>
|
||||
* Taavi Eomäe <taavi.eomae+github@gmail.com>
|
||||
* Gordon Williams <gw@pur3.co.uk>
|
||||
* Rafael Fontenelle <rafaelff@gnome.org>
|
||||
* Michal L <michalrmsmi@wp.pl>
|
||||
* Sebastian Kranz <lightwars@web.de>
|
||||
* João Paulo Barraca <jpbarraca@gmail.com>
|
||||
* Linerly <linerly@protonmail.com>
|
||||
* Rex_sa <rex.sa@pm.me>
|
||||
* mamucho <mamut_killer@yahoo.com>
|
||||
* postsorino <postsorino@krutt.org>
|
||||
* Oğuz Ersen <oguzersen@protonmail.com>
|
||||
* FransM <fransmeulenbroeks@yahoo.com>
|
||||
* Manuel-Senpai <senpai99@hotmail.com>
|
||||
* Andreas Böhler <dev@aboehler.at>
|
||||
* FransM <fransmeulenbroeks@yahoo.com>
|
||||
* Jonas <jonasdcdm@posteo.net>
|
||||
* HenRy <helge1o1o1@gmail.com>
|
||||
* Yukai Li <yukaili.geek@gmail.com>
|
||||
* Roi Greenberg <roigreenberg@gmail.com>
|
||||
* HenRy <helge1o1o1@gmail.com>
|
||||
* gallegonovato <fran-carro@hotmail.es>
|
||||
* Nikita Epifanov <nikgreens@protonmail.com>
|
||||
* kirill blaze <kirillblaze2@gmail.com>
|
||||
* Óscar Fernández Díaz <oscfdezdz@tuta.io>
|
||||
* Jeannette L <j.lavoie@net-c.ca>
|
||||
* Vadim Kaushan <admin@disasm.info>
|
||||
* protomors <protomors@gmail.com>
|
||||
* Cre3per <lukas96s@web.de>
|
||||
* Michal L <michalrmsmi@wp.pl>
|
||||
* José Rebelo <joserebelo@outlook.com>
|
||||
* Vincèn PUJOL <vincen@vincen.org>
|
||||
* Nikita Epifanov <nikgreens@protonmail.com>
|
||||
* Davis Mosenkovs <davikovs@gmail.com>
|
||||
* ssantos <ssantos@web.de>
|
||||
* Michael <quelbs@gmail.com>
|
||||
* glemco <glemco@codeberg>
|
||||
* 115ek <e.blosz@hotmail.de>
|
||||
* 0que <0que@users.noreply.hosted.weblate.org>
|
||||
* Саша Петровић <salepetronije@gmail.com>
|
||||
* naofum <naofum@gmail.com>
|
||||
* Gordon Williams <gw@pur3.co.uk>
|
||||
* My Random Thoughts <weblate@myrandomthoughts.co.uk>
|
||||
* Damien 'Psolyca' Gaignon <damien.gaignon@gmail.com>
|
||||
* 0eoc <0eoc@users.noreply.hosted.weblate.org>
|
||||
* mesnevi <shams@airpost.net>
|
||||
* Jeannette L <j.lavoie@net-c.ca>
|
||||
* Kintu <kintukp@gmail.com>
|
||||
* youzhiran <2668760098@qq.com>
|
||||
* mueller-ma <mueller-ma@users.noreply.github.com>
|
||||
* ivanovlev <ivanovlev@mail.ru>
|
||||
* Tijl Schepens <tijl.schepens@hotmail.com>
|
||||
* ssantos <ssantos@web.de>
|
||||
* Sophanimus <sennamails@googlemail.com>
|
||||
* Pavel Elagin <elagin.pasha@gmail.com>
|
||||
* NekoBox <nekobox@noreply.codeberg.org>
|
||||
* MPeter <>
|
||||
* MrYoranimo <yvulker@gmail.com>
|
||||
* mondstern <hello@mondstern.tk>
|
||||
* Hadrián Candela <hadrian.candela@gmail.com>
|
||||
* Ács Zoltán <acszoltan111@gmail.com>
|
||||
* Zhong Jianxin <azuwis@gmail.com>
|
||||
* Kintu <kintukp@gmail.com>
|
||||
* Milo Ivir <mail@milotype.de>
|
||||
* Gabriele Monaco <monaco@eit.uni-kl.de>
|
||||
* foxstidious <foxstidious@gmail.com>
|
||||
* Andy Yang <a962702@yahoo.com>
|
||||
* Abdullah Manaz <manaz@noreply.codeberg.org>
|
||||
* Richard de Boer <git@tubul.net>
|
||||
* mkusnierz <>
|
||||
* Julien Pivotto <roidelapluie@inuits.eu>
|
||||
* tomechio <tomasz@salamon.fi>
|
||||
* Steffen Liebergeld <perl@gmx.org>
|
||||
* Skrripy <rozihrash.ya6w7@simplelogin.com>
|
||||
* Petr Kadlec <mormegil@centrum.cz>
|
||||
* Pavel <pavel.gorbanj@gmail.com>
|
||||
* Lem Dulfo <lemuel.dulfo@gmail.com>
|
||||
* Dmitriy Bogdanov <di72nn@gmail.com>
|
||||
* Olexandr Nesterenko <olexn@ukr.net>
|
||||
* Nevena Mircheva <nevena.mircheva@gmail.com>
|
||||
* musover <meoberto@mthree.es>
|
||||
* Matthieu Baerts <matttbe@gmail.com>
|
||||
* J. Lavoie <j.lavoie@net-c.ca>
|
||||
* Felix Konstantin Maurer <maufl@maufl.de>
|
||||
* Andy Yang <a962702@yahoo.com>
|
||||
* Axus Wizix <aw.ts@bk.ru>
|
||||
* Xtremo3 <a.lewicki95@gmail.com>
|
||||
* Utsob Roy <uroybd@gmail.com>
|
||||
* taras3333 <taras3333@gmail.com>
|
||||
* Sergey Trofimov <sarg@sarg.org.ru>
|
||||
* Sebastian Krey <sebastian@skrey.net>
|
||||
* Noodlez <contact@nathanielbarragan.xyz>
|
||||
* M. Hadi <hhhadddi@yahoo.com>
|
||||
* Martin Boonk <martin@boonk.info>
|
||||
* Lukas <lukas.edi@gmx.net>
|
||||
* Ganblejs <ganblejs@noreply.codeberg.org>
|
||||
* Deixondit <jperals@protonmail.com>
|
||||
* akasaka / Genjitsu Labs <vladkorotnev@gmail.com>
|
||||
* Szylu <chipolade@gmail.com>
|
||||
* Robert Barat <rbarat07@gmail.com>
|
||||
* Pavel <pavel.gorbanj@gmail.com>
|
||||
* Reza Almanda <rezaalmanda27@gmail.com>
|
||||
* Mario <mariomobla@gmail.com>
|
||||
* ksiwczynski <k.siwczynski@gmail.com>
|
||||
* JohnnySun <bmy001@gmail.com>
|
||||
* Gilles Émilien MOREL <contact@gilles-morel.fr>
|
||||
* Deixondit <jperals@protonmail.com>
|
||||
* firekonstantin <firekonstantin@mail.ru>
|
||||
* bruh <quangtrung02hn16@gmail.com>
|
||||
* Uwe Hermann <uwe@hermann-uwe.de>
|
||||
* Patric Gruber <me@patric-gruber.at>
|
||||
* opavlov <forpoststuff@gmail.com>
|
||||
* Olexandr Nesterenko <olexn@ukr.net>
|
||||
* Michalis <michalisntovas@yahoo.gr>
|
||||
* Mario Rossi <kk1o2n+61euckrwqwqecz3pme3@sharklasers.com>
|
||||
* ifurther <i.further.5.4@gmail.com>
|
||||
* Edoardo Rosa <edoardo.rosa90@gmail.com>
|
||||
* Dmitriy Bogdanov <di72nn@gmail.com>
|
||||
* d <dmanye@gmail.com>
|
||||
* Bożydar <trening302@o2.pl>
|
||||
* Alberto <albertsal83@gmail.com>
|
||||
* AiLab <vpuhoff92@gmail.com>
|
||||
* zsolt3991 <zsolt_93@yahoo.com>
|
||||
* winver <kirillstuzhuk@gmail.com>
|
||||
* Vladislav Serkov <vladserkoff@protonmail.com>
|
||||
* Vebryn <vebryn@gmail.com>
|
||||
* uli <cybuzuma@vnxs.de>
|
||||
* Ted Stein <me@tedstein.net>
|
||||
* sinore <sinoren263@niekie.com>
|
||||
* Shimon <simonfarm0@gmail.com>
|
||||
* Reiner Herrmann <reiner@reiner-h.de>
|
||||
* NicoBuntu <nicolas__du95@hotmail.fr>
|
||||
* Nee Sorry <sven.fasterding@posteo.de>
|
||||
* Marc Nause <marc.nause@audioattack.de>
|
||||
* Louis-Marie Croisez <louis.croisez@gmail.com>
|
||||
* Kryštof Černý <cleverline1mc@gmail.com>
|
||||
* Johannes Krude <johannes@krude.de>
|
||||
* Jean-François Greffier <jf.greffier@gmail.com>
|
||||
* Hasan Ammar <ammarh@gmail.com>
|
||||
* Giuseppe Caliendo <giuseppe.caliendo@gmail.com>
|
||||
* Gergely Peidl <gergely@peidl.net>
|
||||
* Fabio Parri <parrif_ibb@yahoo.com>
|
||||
* Evo <weblate@verahawk.com>
|
||||
* Emre <wenigerpluesch@mailbox.org>
|
||||
* Elwood <elwood21@gmail.com>
|
||||
* Dmitry Markin <dmitry@markin.tech>
|
||||
@ -118,153 +172,236 @@
|
||||
* 0nse <0nse@users.noreply.github.com>
|
||||
* Максим Якимчук <xpinovo@gmail.com>
|
||||
* Ye Wint Htut Kyaw <oxygen.2521998@gmail.com>
|
||||
* xaos <xaos@noreply.codeberg.org>
|
||||
* Thomas <tutonis@gmail.com>
|
||||
* TheScientistPT <joao.ed.reis.gomes@gmail.com>
|
||||
* SnowCat <kittythesnowcat@protonmail.com>
|
||||
* Sergio Varela <sergitroll9@gmail.com>
|
||||
* Sebastian Obrusiewicz <sobrus2@o2.pl>
|
||||
* Sebastian Espinosa <hipypuff@gmail.com>
|
||||
* Robbert Gurdeep Singh <git@beardhatcode.be>
|
||||
* Rimas Raguliūnas <rarimas@gmail.com>
|
||||
* mvn23 <schopdiedwaas@gmail.com>
|
||||
* Minori Hiraoka (미노리) <minori@mnetwork.co.kr>
|
||||
* MASVA <masva10@gmail.com>
|
||||
* masakoodaa <masakoodaa@protonmail.com>
|
||||
* Marius Cornescu <marius_cornescu@yahoo.com>
|
||||
* Mario Rossi <kk1o2n+61euckrwqwqecz3pme3@sharklasers.com>
|
||||
* mantas-p <megaliuz@gmail.com>
|
||||
* Lukas Veneziano <fs@venezilu.de>
|
||||
* LL <lu.lecocq@free.fr>
|
||||
* LizardWithHat <martin.betcher@gmail.com>
|
||||
* Lesur Frederic <contact@memiks.fr>
|
||||
* leela <53352@protonmail.com>
|
||||
* kukuruzka <anton.dan1657@gmail.com>
|
||||
* Kompact <joaorafael123@hotmail.com>
|
||||
* Kalle <hiwokey596@vip4e.com>
|
||||
* K0L0B0G <github@gorobav.ru>
|
||||
* Johann C. Rode <jcrode@ece.ucsb.edu>
|
||||
* jimman2003 <jim41825@gmail.com>
|
||||
* jfgreffier <jfgreffier@users.noreply.github.com>
|
||||
* Jasper <jespiex456@hotmail.com>
|
||||
* ITCactus <itcactus@noreply.codeberg.org>
|
||||
* illis <illis@beyond8labs.com>
|
||||
* Francesco Marinucci <francesco.marinucci@posteo.net>
|
||||
* FintasticMan <finlay.neon.kid@gmail.com>
|
||||
* Doma Gergő <domag02@gmail.com>
|
||||
* Dikay900 <dark900@xyz.de>
|
||||
* Denis <korden@sky-play.ru>
|
||||
* Christian Fischer <sw-dev@computerlyrik.de>
|
||||
* Benjamin Swartley <reep236@gmail.com>
|
||||
* Asbesbopispa <c.alfano+github@outlook.it>
|
||||
* AiLab <vpuhoff92@gmail.com>
|
||||
* Adolfo Jayme Barrientos <fitojb@ubuntu.com>
|
||||
* 6arms1leg <m.brnsfld@googlemail.com>
|
||||
* Your Name <you@example.com>
|
||||
* XqweX <xqwex@seznam.cz>
|
||||
* walkjivefly <mark@walkjivefly.com>
|
||||
* WaldiS <admin@sto.ugu.pl>
|
||||
* Vytenis <slivinskasvytenis@gmail.com>
|
||||
* Vladislav Glinsky <cl0ne@mithril.org.ua>
|
||||
* vishnu <vishnu012@protonmail.com>
|
||||
* Thomas <tutonis@gmail.com>
|
||||
* Sebastian Espinosa <hipypuff@gmail.com>
|
||||
* Vianney le Clément de Saint-Marcq <vianney@noreply.codeberg.org>
|
||||
* Toby Murray <toby.murray+gitkraken@protonmail.com>
|
||||
* thyttan <6uuxstm66@mozmail.com>
|
||||
* Thorsten <js1_531b3pm29ng2@byom.de>
|
||||
* Stephan Lachnit <stephanlachnit@protonmail.com>
|
||||
* Sebastian Reichel <sre@ring0.de>
|
||||
* Saul Nunez <saul.nunez99@gmail.com>
|
||||
* Rui Mendes <xz9@protonmail.com>
|
||||
* roolx <rbzikadze@gmail.com>
|
||||
* rarder44 <rarder44@noreply.codeberg.org>
|
||||
* rany <ranygh@riseup.net>
|
||||
* Ranved Sticon <the7bulk@gmail.com>
|
||||
* Rajesh Kumbhakar <sssraj.sssraj@gmail.com>
|
||||
* Ptilopsis Leucotis <PtilopsisLeucotis@yandex.com>
|
||||
* petronovak <petro.novak@gmail.com>
|
||||
* Petr Kadlec <mormegil@centrum.cz>
|
||||
* Pascal <pascal.tannich@gmail.com>
|
||||
* odavo32nof <odavo32nof@noreply.codeberg.org>
|
||||
* octospacc <octo@tutamail.com>
|
||||
* NotAFIle <nota@notafile.com>
|
||||
* Normano64 <per.bergqwist@gmail.com>
|
||||
* Nikolay Korotkiy <sikmir@gmail.com>
|
||||
* Nick Spacek <peter.spacek@siemens.com>
|
||||
* Nee Sorry <sven.fasterding@posteo.de>
|
||||
* Nekromanser <ari.taitto@protonmail.com>
|
||||
* Nathan <bonnemainsnathan@gmail.com>
|
||||
* narektor <narektor@noreply.codeberg.org>
|
||||
* MyTimeKill <26295589+MyTimeKill@users.noreply.github.com>
|
||||
* Molnár Barnabás <nsd4rkn3ss@gmail.com>
|
||||
* Moarc <aldwulf@gmail.com>
|
||||
* Michal Novotny <mignov@gmail.com>
|
||||
* maxvel <maxvel@noreply.codeberg.org>
|
||||
* Maxime Reyrolle <dev@reyrolle.fr>
|
||||
* Mattias Münster <mattiasmun@gmail.com>
|
||||
* Mattherix <mattherix@protonmail.com>
|
||||
* Martin <ritualz@users.noreply.github.com>
|
||||
* marco.altomonte <marco.altomonte@gmail.com>
|
||||
* LizardWithHat <martin.betcher@gmail.com>
|
||||
* Le Poisson Libre <services@spika.xyz>
|
||||
* Krzysztof Marcinek <krzymar2002@gmail.com>
|
||||
* krzys_h <krzys_h@interia.pl>
|
||||
* Konrad Iturbe <KonradIT@users.noreply.github.com>
|
||||
* Kamalei Zestri <38802353+KamaleiZestri@users.noreply.github.com>
|
||||
* Joel Beckmeyer <joel@beckmeyer.us>
|
||||
* Jesús <zaagur@gmail.com>
|
||||
* Jesús F <jfmiguel@wanadoo.es>
|
||||
* Irul <wedesignthing@gmail.com>
|
||||
* ifurther <i.further.5.4@gmail.com>
|
||||
* Igor Polyakov <igorpolyakov@protonmail.com>
|
||||
* homocomputeris <homocomputeris+git@gmail.com>
|
||||
* Grzegorz <grzesjam@duck.com>
|
||||
* GeekosaurusR3x <skad@protonmail.com>
|
||||
* Francesco Franchina <cescus92@gmail.com>
|
||||
* fparri <fparri@noreply.codeberg.org>
|
||||
* Fabien Brachere <fabien@brachere.net>
|
||||
* exit-failure <hakrala@web.de>
|
||||
* Ertu (Er2, Err) <er2official@outlook.com>
|
||||
* Er2 <er2@dismail.de>
|
||||
* Dreamwalker <aristojeff@gmail.com>
|
||||
* DAWID <aggregate_diffused400@simplelogin.com>
|
||||
* Dario Lopez-Kästen <cl2dlope@gmail.com>
|
||||
* Da Pa <da.pa@noreply.codeberg.org>
|
||||
* DanialHanif <danialhanif@outlook.com>
|
||||
* Cristian Alfano <c.alfano@outlook.it>
|
||||
* criogenic <criogenic@gmail.com>
|
||||
* chabotsi <chabotsi+github@chabotsi.fr>
|
||||
* bowornsin <bowornsin@gmail.com>
|
||||
* Avamander <Avamander@users.noreply.github.com>
|
||||
* Artem <KovalevArtem.ru@gmail.com>
|
||||
* AnthonyDiGirolamo <anthony.digirolamo@gmail.com>
|
||||
* Anonymous <noreply@weblate.org>
|
||||
* Andreas Kromke <Andreas.Kromke@web.de>
|
||||
* Alex <leha-bot@yandex.ru>
|
||||
* Albert <albert@avdm043>
|
||||
* Ainārs <ainars71@inbox.lv>
|
||||
* عبدالرئوف عابدی <abdolraoofabedi@gmail.com>
|
||||
* Егор Ермаков <eg.ermakov2016@yandex.ru>
|
||||
* Ⲇⲁⲛⲓ Φi <daniphii@outlook.com>
|
||||
* Your Name <you@example.com>
|
||||
* Yusuf Cihan <yusufcihandemirbas@gmail.com>
|
||||
* yk <bivol21883@cyadp.com>
|
||||
* Yar <yaroslav.isakov@gmail.com>
|
||||
* xzovy <caleb@caleb-cooper.net>
|
||||
* xphnx <xphnx@users.noreply.github.com>
|
||||
* Xosé M <xosem@disroot.org>
|
||||
* Xeoy <arventh@pm.me>
|
||||
* Xavier RENE-CORAIL <xavier.renecorail@gmail.com>
|
||||
* xaos <xaos@noreply.codeberg.org>
|
||||
* x29a <x29a@noreply.codeberg.org>
|
||||
* w2q <w2q@noreply.codeberg.org>
|
||||
* Vitaliy Shuruta <vshuruta@gmail.com>
|
||||
* veecue <veecue@ventos.tk>
|
||||
* Unixware <csynt@hotmail.com>
|
||||
* TylerWilliamson <tyler.williamson51@gmail.com>
|
||||
* Triet Pham <triet.phm@gmail.com>
|
||||
* Traladarer <Traladarer@users.noreply.hosted.weblate.org>
|
||||
* Tomer Rosenfeld <tomerosenfeld007@gmail.com>
|
||||
* Tomas Radej <tradej@redhat.com>
|
||||
* Toby Murray <toby.murray+gitkraken@protonmail.com>
|
||||
* t-m-w <t-m-w-codeberg@galac.tk>
|
||||
* tiparega <11555126+tiparega@users.noreply.github.com>
|
||||
* TinfoilSubmarine <tinfoilsubmarine@noreply.codeberg.org>
|
||||
* Tim <tim.w1995@gmail.com>
|
||||
* thirschbuechler <thirschbuechler@github.com>
|
||||
* Thiago Rodrigues <thiaguinho.the@gmail.com>
|
||||
* thermatk <thermatk@noreply.codeberg.org>
|
||||
* theghostofheathledger <theghostofheathledger@noreply.codeberg.org>
|
||||
* Temuri Doghonadze <temuri.doghonadze@gmail.com>
|
||||
* Tarik Sekmen <tarik@ilixi.org>
|
||||
* Szymon Tomasz Stefanek <s.stefanek@gmail.com>
|
||||
* szilardx <15869670+szilardx@users.noreply.github.com>
|
||||
* Swann Martinet <swann.ranskassa@laposte.net>
|
||||
* Stefan Bora <stefan.bora@outlook.de>
|
||||
* Stan Gomin <stan@gomin.me>
|
||||
* ssilverr <ssilverr@noreply.codeberg.org>
|
||||
* Sky233ml <sky233@sky233.ml>
|
||||
* SinMan <emilio.galvan@gmail.com>
|
||||
* Simon Sievert <ssievert@protonmail.com>
|
||||
* Sergio Lopez <slp@sinrega.org>
|
||||
* Sergey Vasilyev <koniponi@gmail.com>
|
||||
* sedy89 <sedy89@noreply.codeberg.org>
|
||||
* Sebastian Nilsson <sebbe_kompis@hotmail.com>
|
||||
* S Dantas <dantasosteney@gmail.com>
|
||||
* Santiago Benalcázar <santiagosdbc@gmail.com>
|
||||
* Samuel Carvalho de Araújo <samuelnegro12345@gmail.com>
|
||||
* Sami Alaoui <4ndroidgeek@gmail.com>
|
||||
* Saman rsh <sasan.r75@gmail.com>
|
||||
* Salif Mehmed <mail@salif.eu>
|
||||
* SalavatR <salavat.rakhmanov@gmail.com>
|
||||
* Roxystar <roxystar@arcor.de>
|
||||
* Roman Plevka <rplevka@redhat.com>
|
||||
* rom4nik <codeberg@rom4nik.pl>
|
||||
* Robin Davidsson <robindavidsson@outlook.com>
|
||||
* Roberto P. Rubio <outtakes_handgun090@familiapm.com>
|
||||
* rober <rober@prtl.nodomain.net>
|
||||
* Rivo Zängov <rivozangov@gmail.com>
|
||||
* rimasx <riks_12@hot.ee>
|
||||
* rikka356 <rikka356@outlook.com>
|
||||
* Richard Finegold <goldfndr+git@gmail.com>
|
||||
* Retew <salau@tutanota.com>
|
||||
* redking <redking974@gmail.com>
|
||||
* Ray <RayL-er@outlook.com>
|
||||
* RandomItalianGuy <donatoperruso@protonmail.com>
|
||||
* Raghd Hamzeh <raghd@rhamzeh.com>
|
||||
* Quang Ngô <ngoquang2708@gmail.com>
|
||||
* Quallenauge <Hamsi2k@freenet.de>
|
||||
* Q-er <9142398+Q-er@users.noreply.github.com>
|
||||
* pommes <pommes@noreply.codeberg.org>
|
||||
* pishite <pishite@meta.ua>
|
||||
* Perflyst <mail@perflyst.de>
|
||||
* Pavel Motyrev <legioner.r@gmail.com>
|
||||
* Pauli Salmenrinne <susundberg@gmail.com>
|
||||
* pangwalla <pangwalla@noreply.codeberg.org>
|
||||
* Pander <pander@users.sourceforge.net>
|
||||
* ozkanpakdil <ozkan.pakdil@gmail.com>
|
||||
* opcode <luigi@sciolla.net>
|
||||
* Ondřej Sedláček <ond.sedlacek@gmail.com>
|
||||
* Olivier Bloch <blochjunior@gmail.com>
|
||||
* Oleg Vasilev <oleg.vasilev@virtuozzo.com>
|
||||
* Oleg <oleg.invisibleman@protonmail.com>
|
||||
* Nur Aiman Fadel <nuraiman@gmail.com>
|
||||
* Nikolai Sinyov <nikolay.sinyov@yandex.ru>
|
||||
* Nicolò Balzarotti <anothersms@gmail.com>
|
||||
* Nephiel <Nephiel@users.noreply.github.com>
|
||||
* Nathan Philipp Bo Seddig <natpbs@gmail.com>
|
||||
* Natanael Arndt <arndtn@gmail.com>
|
||||
* Nabil BENDAFI <nabil@bendafi.fr>
|
||||
* myxor <myxor@noreply.codeberg.org>
|
||||
* Morten Rieger Hannemose <mohan@dtu.dk>
|
||||
* Mirko Covizzi <mrkcvzz@gmail.com>
|
||||
* Milo Ivir <mail@milotype.de>
|
||||
* Milan Šalka <salka.milan@googlemail.com>
|
||||
* Mike van Rossum <mike@vanrossum.net>
|
||||
* mika laka <Mikhaila.Eaddy@easymailer.live>
|
||||
* Michal Novak <michal.novak@post.cz>
|
||||
* Michael Wiesinger <michw2014@gmail.com>
|
||||
* michaelneu <git@michaeln.eu>
|
||||
* Lesur Frederic <contact@memiks.fr>
|
||||
* MedusasSphinx <medusassphinx@noreply.codeberg.org>
|
||||
* McSym28 <McSym28@users.noreply.github.com>
|
||||
* MaxL <z60loa8qw3umzu3@my10minutemail.com>
|
||||
* maxirnilian <maxirnilian@users.noreply.github.com>
|
||||
* Maxim Baz <git@maximbaz.com>
|
||||
* Mave95 <mave95@noreply.codeberg.org>
|
||||
* Matej Drobnič <matejdro@gmail.com>
|
||||
* Marvin D <mave95@posteo.de>
|
||||
* Martin Piatka <chachacha2323@gmail.com>
|
||||
* Martin.JM <>
|
||||
* Margreet <margreetkeelan@gmail.com>
|
||||
* Marc Schlaich <marc.schlaich@googlemail.com>
|
||||
* Marco Alberto Diosdado Nava <betoxxdiosnava@gmail.com>
|
||||
* Marco A <35718078+TomasCartman@users.noreply.github.com>
|
||||
* Marc Nause <marc.nause@audioattack.de>
|
||||
* Marc Laporte <marc@laporte.name>
|
||||
* Marcin <ml.cichy@gmail.com>
|
||||
* Marcel pl (m4rcel) <marcel.garbarczyk@gmail.com>
|
||||
@ -274,87 +411,142 @@
|
||||
* magimel.francois <magimel.francois@gmail.com>
|
||||
* Maciej Kuśnierz <>
|
||||
* m4sk1n <me@m4sk.in>
|
||||
* LukasEdl <lukasedl@noreply.codeberg.org>
|
||||
* LuK1337 <priv.luk@gmail.com>
|
||||
* Luiz Felipe das Neves Lopes <androidfelipe23@gmail.com>
|
||||
* Luis zas <dalues@gmail.com>
|
||||
* Ludovic Jozeau <unifai@protonmail.com>
|
||||
* luca sain <luca.sain@outlook.com>
|
||||
* lucanomax <lucano.valo@gmail.com>
|
||||
* Liao junchao <liaojunchao@outlook.com>
|
||||
* Leon Omelan <rozpierog@gmail.com>
|
||||
* Leonardo Amaral <contato@leonardoamaral.com.br>
|
||||
* Leo bonilla <leo_lf9@hotmail.com>
|
||||
* LeJun <lejun@gmx.fr>
|
||||
* Lejun <adrienzhang@hotmail.com>
|
||||
* lazarosfs <lazarosfs@csd.auth.gr>
|
||||
* Lars Vogdt <lars.vogdt@suse.com>
|
||||
* ladbsoft <30509719+ladbsoft@users.noreply.github.com>
|
||||
* Kyaw Min Khant <kyawmink@gmail.com>
|
||||
* Krisztián Gáncs <990024@gmail.com>
|
||||
* Kristjan Räts <kristjanrats@gmail.com>
|
||||
* Kornél Schmidt <kornel.schmidt@clubspot.app>
|
||||
* kirk1984 <kirk1984@noreply.codeberg.org>
|
||||
* kieranc001 <kieranc001@noreply.codeberg.org>
|
||||
* kevlarcade <kevlarcade@gmail.com>
|
||||
* Kevin Richter <me@kevinrichter.nl>
|
||||
* Kevin MacMartin <prurigro@gmail.com>
|
||||
* keeshii <keeshii@ptcg.eu>
|
||||
* Kaz Wolfe <root@kazwolfe.io>
|
||||
* Kasha <kasha_malaga@hotmail.com>
|
||||
* kalaee <alex.kalaee@gmail.com>
|
||||
* Julien Winning <heijulien@web.de>
|
||||
* Julian Lam <julian@nodebb.org>
|
||||
* jugendhacker <jugendhacker@gmail.com>
|
||||
* Joseph Kim <official.jkim@gmail.com>
|
||||
* jonnsoft <>
|
||||
* Johannes Tysiak <vinyl@users.sf.net>
|
||||
* Joan Perals <jperals@protonmail.com>
|
||||
* Jochen S <tsalin@noreply.codeberg.org>
|
||||
* joaquim.org <joaquim.org@gmail.com>
|
||||
* jhey <jhey@noreply.codeberg.org>
|
||||
* JF <jf@codingfield.com>
|
||||
* Jean-François Milants <jf@codingfield.com>
|
||||
* jcrode <46062294+jcrode@users.noreply.github.com>
|
||||
* Jan Lolek <janlolek@seznam.cz>
|
||||
* Jakub Jelínek <jakub.jelinek@gmail.com>
|
||||
* Jacque Fresco <aidter@use.startmail.com>
|
||||
* Izzy <izzy@qumran.org>
|
||||
* iwonder <hosted.weblate.org@heychris.eu>
|
||||
* Ivan <ivan_tizhanin@mail.ru>
|
||||
* Igor Polyakov <igorpolyakov@protonmail.com>
|
||||
* InternalErrorX <internalerrorx@noreply.codeberg.org>
|
||||
* Hüseyin Aslan <ha098784@gmail.com>
|
||||
* Hugel <qihu@nfschina.com>
|
||||
* hr-sales <hericsonregis@hotmail.com>
|
||||
* Hirnchirurg <anonymous11@posteo.net>
|
||||
* Hasan Ammar <ammarh@gmail.com>
|
||||
* Hen Ry <nobo@go4more.de>
|
||||
* HelloCodeberg <hellocodeberg@noreply.codeberg.org>
|
||||
* HardLight <hardlightxda@gmail.com>
|
||||
* Hanhan Husna <matcherapy@gmail.com>
|
||||
* halemmerich <halemmerich@noreply.codeberg.org>
|
||||
* hackoder <hackoder@noreply.codeberg.org>
|
||||
* Gustavo Ramires <gustavo.nramires@gmail.com>
|
||||
* gsbhat <>
|
||||
* Grzegorz Dznsk <grantmlody96@gmail.com>
|
||||
* Golbinex <2061409-Golbinex@users.noreply.gitlab.com>
|
||||
* gnufella <gnufella@noreply.codeberg.org>
|
||||
* gnu-ewm <gnu.ewm@protonmail.com>
|
||||
* Gleb Chekushin <mail@glebchek.com>
|
||||
* Giuseppe <giuseppe.parasilitipalumbo@studium.unict.it>
|
||||
* Gideão Gomes Ferreira <trjctr@gmail.com>
|
||||
* gfwilliams <gfwilliams@noreply.codeberg.org>
|
||||
* GabO <gabosuelto@gmail.com>
|
||||
* Gabe Schrecker <gabe@pbrb.co.uk>
|
||||
* freezed-or-frozen <freezed.or.frozen@gmail.com>
|
||||
* Frank Slezak <KazWolfe@users.noreply.github.com>
|
||||
* Frank Ertl <hrglpfrmpf@noreply.codeberg.org>
|
||||
* Florian Beuscher <florianbeuscher@gmail.com>
|
||||
* Fabian Hof <weblate@fabian-hof.de>
|
||||
* Étienne Deparis <etienne@depar.is>
|
||||
* Estébastien Robespi <estebastien@mailbox.org>
|
||||
* Ernst <ernst@seebens.de>
|
||||
* Enrico Brambilla <enricobilla@noreply.codeberg.org>
|
||||
* Edoardo Tronconi <edoardo.tronconi@gmail.com>
|
||||
* Dougal19 <4662351+Dougal19@users.noreply.github.com>
|
||||
* Donato <pread.xa4mx@simplelogin.com>
|
||||
* Dmytro Bielik <mitrandir.hex@gmail.com>
|
||||
* djurik <dirceu.semighini@protonmail.com>
|
||||
* DerFetzer <kontakt@der-fetzer.de>
|
||||
* Dean <3114661520@qq.com>
|
||||
* Deactivated Account <diastasis@gmail.com>
|
||||
* Davis Mosenkovs <davikovs@gmail.com>
|
||||
* David Girón <contacto@duhowpi.net>
|
||||
* Davide Corradini <updates+weblate.org@corradinidavi.de>
|
||||
* Daniel Thompson <daniel@redfelineninja.org.uk>
|
||||
* Daniel Hauck <maill@dhauck.eu>
|
||||
* Dam BOND <dambond2001@gmail.com>
|
||||
* 이정희 <daemul72@gmail.com>
|
||||
* Dachi G <duchy007@yahoo.com>
|
||||
* C <weblate@wolki.de>
|
||||
* cokecodecock <lights1140977891@163.com>
|
||||
* CodeSpoof <nao.s_l_t_e_e_l@protonmail.com>
|
||||
* C O <cosmin.oprisan@gmail.com>
|
||||
* clach04 <Chris.Clark@actian.com>
|
||||
* Chris Perelstein <chris.perelstein@gmail.com>
|
||||
* chklump <chklump@noreply.codeberg.org>
|
||||
* Cédric Bellegarde <cedric.bellegarde@adishatz.org>
|
||||
* Carlos Ferreira <calbertoferreira@gmail.com>
|
||||
* C0rn3j <spleefer90@gmail.com>
|
||||
* ButterflyOfFire <ButterflyOfFire@protonmail.com>
|
||||
* bucala <marcel.bucala@gmail.com>
|
||||
* boun <boun@gmx.de>
|
||||
* BobIsMyManager <bobismymanager@noreply.codeberg.org>
|
||||
* Bilel MEDIMEGH <bilel.medimegh@gmail.com>
|
||||
* Benjamin Kahlau <nyhkkbjyek@roanapur.de>
|
||||
* Ben <ben.david.wallner@gmail.com>
|
||||
* beardhatcode <beardhatcode@noreply.codeberg.org>
|
||||
* batataspt@gmail.com <batataspt@gmail.com>
|
||||
* atkyritsis <at.kyritsis@gmail.com>
|
||||
* Artem <KovalevArtem.ru@gmail.com>
|
||||
* Ascense <ascense@noreply.codeberg.org>
|
||||
* Aprilhoomie <Aprilhoomie@gmail.com>
|
||||
* apre <adrienpre+github@gmail.com>
|
||||
* Ann Test <testkimochiaz@gmail.com>
|
||||
* Aniruddha Adhikary <aniruddha@adhikary.net>
|
||||
* angelpup <angelpup@noreply.codeberg.org>
|
||||
* Anemograph <dyraybn@gmail.com>
|
||||
* Andrzej Surowiec <emeryth@gmail.com>
|
||||
* Andrew Watkins <randnv20@noreply.codeberg.org>
|
||||
* andrewlytvyn <indusfreelancer@gmail.com>
|
||||
* AndrewH <36428679+andrewheadricke@users.noreply.github.com>
|
||||
* andre <andre.buesgen@yahoo.de>
|
||||
* Andrea Lepori <mafaldo@hotmail.it>
|
||||
* Allen B <28495335+Allen-B1@users.noreply.github.com>
|
||||
* Alicia Hormann <ahormann@gmx.net>
|
||||
* Alfeu Lucas Guedes dos Santos <alfeugds@gmail.com>
|
||||
* Alex <leha-bot@yandex.ru>
|
||||
* Alexey Afanasev <avafanasiev@gmail.com>
|
||||
* Alexandra Sevostyanova <asevostyanova@gmail.com>
|
||||
* Aidan Crane <aidancrane78@gmail.com>
|
||||
* aerowolf <aerowolf@tom.com>
|
||||
* Adam Büchner <buechner.adam@gmx.de>
|
||||
* a b <65567823+abb128@users.noreply.github.com>
|
||||
|
||||
And all the former Transifex translators, who cannot be listed automatically.
|
||||
|
||||
|
35
FEATURES.md
35
FEATURES.md
@ -1,35 +0,0 @@
|
||||
## Feature Matrix
|
||||
|
||||
| | Pebble OG | Pebble Time/2 | Mi Band | Mi Band 2 | Mi Band 3 | Mi Band 4/5 | Amazfit Bip | Amazfit Cor |
|
||||
|-----------------------------------| ----------|---------------|---------|-----------|-----------|-------------|-------------|-------------|
|
||||
|Calls Notification | YES | YES | YES | YES | YES | YES | YES | YES |
|
||||
|Reject Calls | YES | YES | NO | NO | YES | YES | YES | YES |
|
||||
|Accept Calls | NO(2) | NO(2) | NO | NO | NO | NO | NO | NO |
|
||||
|Generic Notification | YES | YES | YES | YES | YES | YES | YES | YES |
|
||||
|Dismiss Notifications on Phone | YES | YES | NO | NO | NO | NO | NO | NO |
|
||||
|Predefined Replies | YES | YES | NO | NO | NO | NO | NO | NO |
|
||||
|Voice Replies | N/A | NO(3) | N/A | N/A | N/A | N/A | N/A | N/A |
|
||||
|Calendar Sync | YES | YES | NO | NO | NO | NO | NO(3) | NO |
|
||||
|Configure alarms from Gadgetbridge | NO | NO | YES | YES | YES | YES(1) | YES | YES |
|
||||
|Smart alarms | NO(1) | YES | YES | NO | NO | NO | NO | NO |
|
||||
|Weather | NO(1) | YES | NO | NO | YES | YES | YES | YES |
|
||||
|Activity Tracking | NO(1) | YES | YES | YES | YES | YES | YES | YES |
|
||||
|GPS tracks import | NO | NO | NO | NO | NO | NO | YES | NO |
|
||||
|Sleep Tracking | NO(1) | YES | YES | YES | YES | YES | YES | YES |
|
||||
|HR Tracking | N/A | YES | YES | YES | YES | YES | YES | YES |
|
||||
|Realtime Activity Tracking | NO | NO | YES | YES | YES | YES | YES | YES |
|
||||
|Music Control | YES | YES | NO | NO | NO | YES | NO | YES |
|
||||
|Watchapp/face Installation | YES | YES | NO | NO | NO | YES | YES | YES |
|
||||
|Firmware Installation | YES | YES | YES | YES | YES | YES | YES | YES |
|
||||
|Taking Screenshots | YES | YES | NO | NO | NO | NO | NO | NO |
|
||||
|Support Android Companion Apps | YES | YES | NO | NO | NO | NO | NO | NO |
|
||||
|
||||
(1) Possible via 3rd Party Watchapp
|
||||
(2) Theoretically possible (works on iOS, would need lot of work)
|
||||
(3) Possible but not implemented yet
|
||||
|
||||
|
||||
### Notes about Pebble Firmware >=3.0
|
||||
|
||||
* Gadgetbridge will keep track of installed watchfaces, but if the Pebble is used with another phone or another app, the information displayed in the app manager can get out of sync since it is impossible to query Firmware >= 3.x for installed apps/watchfaces.
|
||||
|
@ -45,7 +45,7 @@ public class GBDaoGenerator {
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final Schema schema = new Schema(60, MAIN_PACKAGE + ".entities");
|
||||
final Schema schema = new Schema(70, MAIN_PACKAGE + ".entities");
|
||||
|
||||
Entity userAttributes = addUserAttributes(schema);
|
||||
Entity user = addUserInfo(schema, userAttributes);
|
||||
@ -70,6 +70,18 @@ public class GBDaoGenerator {
|
||||
addHuamiHeartRateRestingSample(schema, user, device);
|
||||
addHuamiPaiSample(schema, user, device);
|
||||
addHuamiSleepRespiratoryRateSample(schema, user, device);
|
||||
addXiaomiActivitySample(schema, user, device);
|
||||
addXiaomiSleepTimeSamples(schema, user, device);
|
||||
addXiaomiSleepStageSamples(schema, user, device);
|
||||
addXiaomiManualSamples(schema, user, device);
|
||||
addXiaomiDailySummarySamples(schema, user, device);
|
||||
addCmfActivitySample(schema, user, device);
|
||||
addCmfStressSample(schema, user, device);
|
||||
addCmfSpo2Sample(schema, user, device);
|
||||
addCmfSleepSessionSample(schema, user, device);
|
||||
addCmfSleepStageSample(schema, user, device);
|
||||
addCmfHeartRateSample(schema, user, device);
|
||||
addCmfWorkoutGpsSample(schema, user, device);
|
||||
addPebbleHealthActivitySample(schema, user, device);
|
||||
addPebbleHealthActivityKindOverlay(schema, user, device);
|
||||
addPebbleMisfitActivitySample(schema, user, device);
|
||||
@ -105,6 +117,12 @@ public class GBDaoGenerator {
|
||||
addWena3StressSample(schema, user, device);
|
||||
addFemometerVinca2TemperatureSample(schema, user, device);
|
||||
|
||||
addHuaweiActivitySample(schema, user, device);
|
||||
|
||||
Entity huaweiWorkoutSummary = addHuaweiWorkoutSummarySample(schema, user, device);
|
||||
addHuaweiWorkoutDataSample(schema, user, device, huaweiWorkoutSummary);
|
||||
addHuaweiWorkoutPaceSample(schema, user, device, huaweiWorkoutSummary);
|
||||
|
||||
addCalendarSyncState(schema, device);
|
||||
addAlarms(schema, user, device);
|
||||
addReminders(schema, user, device);
|
||||
@ -203,7 +221,8 @@ public class GBDaoGenerator {
|
||||
device.addStringProperty("name").notNull();
|
||||
device.addStringProperty("manufacturer").notNull();
|
||||
device.addStringProperty("identifier").notNull().unique().javaDocGetterAndSetter("The fixed identifier, i.e. MAC address of the device.");
|
||||
device.addIntProperty("type").notNull().javaDocGetterAndSetter("The DeviceType key, i.e. the GBDevice's type.");
|
||||
device.addIntProperty("type").notNull().javaDocGetterAndSetter("The DeviceType key, i.e. the GBDevice's type.").codeBeforeGetterAndSetter("@Deprecated");
|
||||
device.addStringProperty("typeName").notNull().javaDocGetterAndSetter("The DeviceType enum name, for example SONY_WH_1000XM3");
|
||||
device.addStringProperty("model").javaDocGetterAndSetter("An optional model, further specifying the kind of device.");
|
||||
device.addStringProperty("alias");
|
||||
device.addStringProperty("parentFolder").javaDocGetterAndSetter("Folder name containing this device.");
|
||||
@ -263,7 +282,7 @@ public class GBDaoGenerator {
|
||||
private static Entity addHuamiStressSample(Schema schema, Entity user, Entity device) {
|
||||
Entity stressSample = addEntity(schema, "HuamiStressSample");
|
||||
addCommonTimeSampleProperties("AbstractStressSample", stressSample, user, device);
|
||||
stressSample.addIntProperty("typeNum").notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
stressSample.addIntProperty("typeNum").notNull().codeBeforeGetter(OVERRIDE);
|
||||
stressSample.addIntProperty("stress").notNull().codeBeforeGetter(OVERRIDE);
|
||||
return stressSample;
|
||||
}
|
||||
@ -271,7 +290,7 @@ public class GBDaoGenerator {
|
||||
private static Entity addHuamiSpo2Sample(Schema schema, Entity user, Entity device) {
|
||||
Entity spo2sample = addEntity(schema, "HuamiSpo2Sample");
|
||||
addCommonTimeSampleProperties("AbstractSpo2Sample", spo2sample, user, device);
|
||||
spo2sample.addIntProperty("typeNum").notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
spo2sample.addIntProperty("typeNum").notNull().codeBeforeGetter(OVERRIDE);
|
||||
spo2sample.addIntProperty("spo2").notNull().codeBeforeGetter(OVERRIDE);
|
||||
return spo2sample;
|
||||
}
|
||||
@ -323,6 +342,136 @@ public class GBDaoGenerator {
|
||||
return sleepRespiratoryRateSample;
|
||||
}
|
||||
|
||||
private static Entity addXiaomiActivitySample(Schema schema, Entity user, Entity device) {
|
||||
Entity activitySample = addEntity(schema, "XiaomiActivitySample");
|
||||
addCommonActivitySampleProperties("AbstractActivitySample", activitySample, user, device);
|
||||
activitySample.implementsSerializable();
|
||||
activitySample.addIntProperty(SAMPLE_RAW_INTENSITY).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
addHeartRateProperties(activitySample);
|
||||
activitySample.addIntProperty("stress");
|
||||
activitySample.addIntProperty("spo2");
|
||||
return activitySample;
|
||||
}
|
||||
|
||||
private static Entity addXiaomiSleepTimeSamples(Schema schema, Entity user, Entity device) {
|
||||
Entity sample = addEntity(schema, "XiaomiSleepTimeSample");
|
||||
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
|
||||
sample.addLongProperty("wakeupTime");
|
||||
sample.addBooleanProperty("isAwake");
|
||||
sample.addIntProperty("totalDuration");
|
||||
sample.addIntProperty("deepSleepDuration");
|
||||
sample.addIntProperty("lightSleepDuration");
|
||||
sample.addIntProperty("remSleepDuration");
|
||||
sample.addIntProperty("awakeDuration");
|
||||
return sample;
|
||||
}
|
||||
|
||||
private static Entity addXiaomiSleepStageSamples(Schema schema, Entity user, Entity device) {
|
||||
Entity sample = addEntity(schema, "XiaomiSleepStageSample");
|
||||
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
|
||||
sample.addIntProperty("stage");
|
||||
return sample;
|
||||
}
|
||||
|
||||
private static Entity addXiaomiManualSamples(Schema schema, Entity user, Entity device) {
|
||||
Entity sample = addEntity(schema, "XiaomiManualSample");
|
||||
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
|
||||
sample.addIntProperty("type");
|
||||
sample.addIntProperty("value");
|
||||
return sample;
|
||||
}
|
||||
|
||||
private static Entity addXiaomiDailySummarySamples(Schema schema, Entity user, Entity device) {
|
||||
Entity sample = addEntity(schema, "XiaomiDailySummarySample");
|
||||
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
|
||||
sample.addIntProperty("timezone");
|
||||
sample.addIntProperty("steps");
|
||||
sample.addIntProperty("hrResting");
|
||||
sample.addIntProperty("hrMax");
|
||||
sample.addIntProperty("hrMaxTs");
|
||||
sample.addIntProperty("hrMin");
|
||||
sample.addIntProperty("hrMinTs");
|
||||
sample.addIntProperty("hrAvg");
|
||||
sample.addIntProperty("stressAvg");
|
||||
sample.addIntProperty("stressMax");
|
||||
sample.addIntProperty("stressMin");
|
||||
sample.addIntProperty("standing");
|
||||
sample.addIntProperty("calories");
|
||||
sample.addIntProperty("spo2Max");
|
||||
sample.addIntProperty("spo2MaxTs");
|
||||
sample.addIntProperty("spo2Min");
|
||||
sample.addIntProperty("spo2MinTs");
|
||||
sample.addIntProperty("spo2Avg");
|
||||
sample.addIntProperty("trainingLoadDay");
|
||||
sample.addIntProperty("trainingLoadWeek");
|
||||
sample.addIntProperty("trainingLoadLevel");
|
||||
sample.addIntProperty("vitalityIncreaseLight");
|
||||
sample.addIntProperty("vitalityIncreaseModerate");
|
||||
sample.addIntProperty("vitalityIncreaseHigh");
|
||||
sample.addIntProperty("vitalityCurrent");
|
||||
return sample;
|
||||
}
|
||||
|
||||
private static Entity addCmfActivitySample(Schema schema, Entity user, Entity device) {
|
||||
Entity activitySample = addEntity(schema, "CmfActivitySample");
|
||||
addCommonActivitySampleProperties("AbstractActivitySample", activitySample, user, device);
|
||||
activitySample.implementsSerializable();
|
||||
activitySample.addIntProperty(SAMPLE_RAW_INTENSITY).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
addHeartRateProperties(activitySample);
|
||||
activitySample.addIntProperty("distance");
|
||||
activitySample.addIntProperty("calories");
|
||||
return activitySample;
|
||||
}
|
||||
|
||||
private static Entity addCmfStressSample(Schema schema, Entity user, Entity device) {
|
||||
Entity stressSample = addEntity(schema, "CmfStressSample");
|
||||
addCommonTimeSampleProperties("AbstractStressSample", stressSample, user, device);
|
||||
stressSample.addIntProperty("stress").notNull().codeBeforeGetter(OVERRIDE);
|
||||
return stressSample;
|
||||
}
|
||||
|
||||
private static Entity addCmfSpo2Sample(Schema schema, Entity user, Entity device) {
|
||||
Entity spo2sample = addEntity(schema, "CmfSpo2Sample");
|
||||
addCommonTimeSampleProperties("AbstractSpo2Sample", spo2sample, user, device);
|
||||
spo2sample.addIntProperty("spo2").notNull().codeBeforeGetter(OVERRIDE);
|
||||
return spo2sample;
|
||||
}
|
||||
|
||||
private static Entity addCmfSleepSessionSample(Schema schema, Entity user, Entity device) {
|
||||
Entity sleepSessionSample = addEntity(schema, "CmfSleepSessionSample");
|
||||
addCommonTimeSampleProperties("AbstractTimeSample", sleepSessionSample, user, device);
|
||||
sleepSessionSample.addLongProperty("wakeupTime");
|
||||
sleepSessionSample.addByteArrayProperty("metadata");
|
||||
return sleepSessionSample;
|
||||
}
|
||||
|
||||
private static Entity addCmfSleepStageSample(Schema schema, Entity user, Entity device) {
|
||||
Entity sleepStageSample = addEntity(schema, "CmfSleepStageSample");
|
||||
addCommonTimeSampleProperties("AbstractTimeSample", sleepStageSample, user, device);
|
||||
sleepStageSample.addIntProperty("duration").notNull();
|
||||
sleepStageSample.addIntProperty("stage").notNull();
|
||||
return sleepStageSample;
|
||||
}
|
||||
|
||||
private static Entity addCmfHeartRateSample(Schema schema, Entity user, Entity device) {
|
||||
Entity heartRateSample = addEntity(schema, "CmfHeartRateSample");
|
||||
addCommonTimeSampleProperties("AbstractHeartRateSample", heartRateSample, user, device);
|
||||
heartRateSample.addIntProperty(SAMPLE_HEART_RATE).notNull().codeBeforeGetter(OVERRIDE);
|
||||
return heartRateSample;
|
||||
}
|
||||
|
||||
private static Entity addCmfWorkoutGpsSample(Schema schema, Entity user, Entity device) {
|
||||
Entity sample = addEntity(schema, "CmfWorkoutGpsSample");
|
||||
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
|
||||
sample.addIntProperty("latitude");
|
||||
sample.addIntProperty("longitude");
|
||||
return sample;
|
||||
}
|
||||
|
||||
private static void addHeartRateProperties(Entity activitySample) {
|
||||
activitySample.addIntProperty(SAMPLE_HEART_RATE).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
}
|
||||
@ -861,6 +1010,7 @@ public class GBDaoGenerator {
|
||||
return activitySample;
|
||||
}
|
||||
|
||||
|
||||
private static Entity addWithingsSteelHRActivitySample(Schema schema, Entity user, Entity device) {
|
||||
Entity activitySample = addEntity(schema, "WithingsSteelHRActivitySample");
|
||||
activitySample.implementsSerializable();
|
||||
@ -896,7 +1046,7 @@ public class GBDaoGenerator {
|
||||
private static Entity addWena3StressSample(Schema schema, Entity user, Entity device) {
|
||||
Entity stressSample = addEntity(schema, "Wena3StressSample");
|
||||
addCommonTimeSampleProperties("AbstractStressSample", stressSample, user, device);
|
||||
stressSample.addIntProperty("typeNum").notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
stressSample.addIntProperty("typeNum").notNull().codeBeforeGetter(OVERRIDE);
|
||||
stressSample.addIntProperty("stress").notNull().codeBeforeGetter(OVERRIDE);
|
||||
return stressSample;
|
||||
}
|
||||
@ -942,6 +1092,99 @@ public class GBDaoGenerator {
|
||||
return perAppSetting;
|
||||
}
|
||||
|
||||
private static Entity addHuaweiActivitySample(Schema schema, Entity user, Entity device) {
|
||||
Entity activitySample = addEntity(schema, "HuaweiActivitySample");
|
||||
addCommonActivitySampleProperties("AbstractActivitySample", activitySample, user, device);
|
||||
activitySample.addIntProperty("otherTimestamp").notNull().primaryKey();
|
||||
activitySample.addByteProperty("source").notNull().primaryKey();
|
||||
activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
activitySample.addIntProperty(SAMPLE_RAW_INTENSITY).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE);
|
||||
activitySample.addIntProperty("calories").notNull();
|
||||
activitySample.addIntProperty("distance").notNull();
|
||||
activitySample.addIntProperty("spo").notNull();
|
||||
activitySample.addIntProperty("heartRate").notNull();
|
||||
return activitySample;
|
||||
}
|
||||
|
||||
private static Entity addHuaweiWorkoutSummarySample(Schema schema, Entity user, Entity device) {
|
||||
Entity workoutSummary = addEntity(schema, "HuaweiWorkoutSummarySample");
|
||||
|
||||
workoutSummary.setJavaDoc("Contains Huawei Workout Summary samples (one per workout)");
|
||||
|
||||
workoutSummary.addLongProperty("workoutId").primaryKey().autoincrement();
|
||||
|
||||
Property deviceId = workoutSummary.addLongProperty("deviceId").notNull().getProperty();
|
||||
workoutSummary.addToOne(device, deviceId);
|
||||
Property userId = workoutSummary.addLongProperty("userId").notNull().getProperty();
|
||||
workoutSummary.addToOne(user, userId);
|
||||
|
||||
workoutSummary.addShortProperty("workoutNumber").notNull();
|
||||
workoutSummary.addByteProperty("status").notNull();
|
||||
workoutSummary.addIntProperty("startTimestamp").notNull();
|
||||
workoutSummary.addIntProperty("endTimestamp").notNull();
|
||||
workoutSummary.addIntProperty("calories").notNull();
|
||||
workoutSummary.addIntProperty("distance").notNull();
|
||||
workoutSummary.addIntProperty("stepCount").notNull();
|
||||
workoutSummary.addIntProperty("totalTime").notNull();
|
||||
workoutSummary.addIntProperty("duration").notNull();
|
||||
workoutSummary.addByteProperty("type").notNull();
|
||||
workoutSummary.addShortProperty("strokes").notNull();
|
||||
workoutSummary.addShortProperty("avgStrokeRate").notNull();
|
||||
workoutSummary.addShortProperty("poolLength").notNull();
|
||||
workoutSummary.addShortProperty("laps").notNull();
|
||||
workoutSummary.addShortProperty("avgSwolf").notNull();
|
||||
|
||||
workoutSummary.addByteArrayProperty("rawData");
|
||||
|
||||
return workoutSummary;
|
||||
}
|
||||
|
||||
private static Entity addHuaweiWorkoutDataSample(Schema schema, Entity user, Entity device, Entity summaryEntity) {
|
||||
Entity workoutDataSample = addEntity(schema, "HuaweiWorkoutDataSample");
|
||||
|
||||
workoutDataSample.setJavaDoc("Contains Huawei Workout data samples (multiple per workout)");
|
||||
|
||||
Property id = workoutDataSample.addLongProperty("workoutId").primaryKey().notNull().getProperty();
|
||||
workoutDataSample.addToOne(summaryEntity, id);
|
||||
|
||||
workoutDataSample.addIntProperty("timestamp").notNull().primaryKey();
|
||||
workoutDataSample.addByteProperty("heartRate").notNull();
|
||||
workoutDataSample.addShortProperty("speed").notNull();
|
||||
workoutDataSample.addByteProperty("stepRate").notNull();
|
||||
workoutDataSample.addShortProperty("cadence").notNull();
|
||||
workoutDataSample.addShortProperty("stepLength").notNull();
|
||||
workoutDataSample.addShortProperty("groundContactTime").notNull();
|
||||
workoutDataSample.addByteProperty("impact").notNull();
|
||||
workoutDataSample.addShortProperty("swingAngle").notNull();
|
||||
workoutDataSample.addByteProperty("foreFootLanding").notNull();
|
||||
workoutDataSample.addByteProperty("midFootLanding").notNull();
|
||||
workoutDataSample.addByteProperty("backFootLanding").notNull();
|
||||
workoutDataSample.addByteProperty("eversionAngle").notNull();
|
||||
workoutDataSample.addByteProperty("swolf").notNull();
|
||||
workoutDataSample.addShortProperty("strokeRate").notNull();
|
||||
|
||||
workoutDataSample.addByteArrayProperty("dataErrorHex");
|
||||
|
||||
return workoutDataSample;
|
||||
}
|
||||
|
||||
private static Entity addHuaweiWorkoutPaceSample(Schema schema, Entity user, Entity device, Entity summaryEntity) {
|
||||
Entity workoutPaceSample = addEntity(schema, "HuaweiWorkoutPaceSample");
|
||||
|
||||
workoutPaceSample.setJavaDoc("Contains Huawei Workout pace data samples (one per workout)");
|
||||
|
||||
Property id = workoutPaceSample.addLongProperty("workoutId").primaryKey().notNull().getProperty();
|
||||
workoutPaceSample.addToOne(summaryEntity, id);
|
||||
|
||||
workoutPaceSample.addIntProperty("distance").notNull().primaryKey();
|
||||
workoutPaceSample.addByteProperty("type").notNull().primaryKey();
|
||||
workoutPaceSample.addIntProperty("pace").notNull();
|
||||
workoutPaceSample.addIntProperty("correction").notNull();
|
||||
|
||||
return workoutPaceSample;
|
||||
}
|
||||
|
||||
private static void addTemperatureProperties(Entity activitySample) {
|
||||
activitySample.addFloatProperty(SAMPLE_TEMPERATURE).notNull().codeBeforeGetter(OVERRIDE);
|
||||
activitySample.addIntProperty(SAMPLE_TEMPERATURE_TYPE).notNull().codeBeforeGetter(OVERRIDE);
|
||||
@ -953,5 +1196,4 @@ public class GBDaoGenerator {
|
||||
addTemperatureProperties(sample);
|
||||
return sample;
|
||||
}
|
||||
|
||||
}
|
||||
|
111
README.md
111
README.md
@ -12,7 +12,7 @@ Pebble, Mi Band, Amazfit Bip and HPlus device (and more) without the vendor's cl
|
||||
and without the need to create an account and transmit any of your data to the
|
||||
vendor's servers.
|
||||
|
||||
[Homepage](https://gadgetbridge.org) - [Blog](https://blog.freeyourgadget.org) - [Wiki](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki) - <a rel="me" href="https://social.anoxinon.de/@gadgetbridge">Mastodon</a>
|
||||
[Homepage](https://gadgetbridge.org) - [Blog](https://blog.freeyourgadget.org) - <a rel="me" href="https://social.anoxinon.de/@gadgetbridge">Mastodon</a>
|
||||
|
||||
[![Donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/Gadgetbridge/donate)
|
||||
|
||||
@ -21,120 +21,25 @@ vendor's servers.
|
||||
|
||||
## Code Licenses
|
||||
|
||||
* Gadgetbrige is licensed under the AGPLv3
|
||||
* Gadgetbridge is licensed under the AGPLv3
|
||||
* Files in app/src/main/java/net/osmand/ and app/src/main/aidl/net/osmand/ are licensed under the GPLv3 by OsmAnd BV
|
||||
|
||||
* Files in app/src/main/java/org/bouncycastle are licensed under the MIT license by The Legion of the Bouncy Castle Inc.
|
||||
|
||||
## Download
|
||||
|
||||
[<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="80">](https://f-droid.org/app/nodomain.freeyourgadget.gadgetbridge)
|
||||
|
||||
[List of changes](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/master/CHANGELOG.md)
|
||||
- [Nightly releases](https://freeyourgadget.codeberg.page/fdroid/repo?fingerprint=CD381ECCC465AB324E21BCC335895615E07E70EE11E9FD1DF3C020C5194F00B2)
|
||||
- Nightly releases are updated more frequently and may be less stable than standard releases, and they are distributed by our F-Droid repository unlike standard releases.
|
||||
- [List of changes](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/master/CHANGELOG.md)
|
||||
|
||||
## Supported Devices
|
||||
**(WARNING: Some of them WIP and some of them without maintainer)**
|
||||
|
||||
- Amazfit
|
||||
- [Balance](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Balance) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Band 5](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Band-5), [Band 7](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Band-7) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Bip](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip)
|
||||
- [Bip Lite](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-Lite), [Bip S](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-S), [Bip U, Bip U Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-U) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Bip 3 Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-3-Pro) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Bip 5 (experimental)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Bip-5) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Cor](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor), [Cor 2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cor-2)
|
||||
- [Falcon (experimental)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Falcon) [**\[!\]**](#special-pairing-procedures)
|
||||
- [GTR](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR), [GTR 2/2e](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR), [GTR 3](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR-3), [GTR 3 Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR-3-Pro), [GTR 4](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR-4) [**\[!\]**](#special-pairing-procedures)
|
||||
- [GTR Mini](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR-Mini) [**\[!\]**](#special-pairing-procedures)
|
||||
- [GTS](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS), [GTS 2/2e](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS), [GTS 3](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS-3), [GTS 4](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS-4), [GTS 4 Mini](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTS-4-Mini) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Neo](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Neo) [**\[!\]**](#special-pairing-procedures)
|
||||
- T-Rex, T-Rex Pro, [T-Rex 2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-T-Rex-2) [**\[!\]**](#special-pairing-procedures)
|
||||
- [T-Rex Ultra (experimental)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-T-Rex-Ultra) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Cheetah (Round/Square) (experimental)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cheetah) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Cheetah Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-Cheetah-Pro) [**\[!\]**](#special-pairing-procedures)
|
||||
- Verge Lite [**\[!\]**](#special-pairing-procedures)
|
||||
- [X ](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-5) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Bangle.js](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Bangle.js)
|
||||
- BFH-16
|
||||
- [Casio](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Casio)
|
||||
- Casio GB-X6900B
|
||||
- Casio GB-6900B
|
||||
- Casio GB-5600B
|
||||
- Casio GW-B5600
|
||||
- Casio GMW-B5000 (untested)
|
||||
- Casio STB-1000
|
||||
- Casio GBX-100
|
||||
- Casio GBD-100
|
||||
- Casio GBD-200
|
||||
- Casio GBD-H1000
|
||||
- [Femometer Vinca II](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Femometer-Vinca-II)
|
||||
- [FitPro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/FitPro)
|
||||
- Fossil
|
||||
- [Hybrid HR](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Fossil-Hybrid-HR) [**\[!\]**](#special-pairing-procedures)
|
||||
- Q Hybrid
|
||||
- [Galaxy Buds](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds)
|
||||
- [Galaxy Buds](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#user-content-galaxy-buds)
|
||||
- [Galaxy Buds Live](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#user-content-galaxy-buds-live)
|
||||
- [Galaxy Buds Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#galaxy-buds-pro)
|
||||
- [Galaxy Buds2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#galaxy-buds2)
|
||||
- [Galaxy Buds2 Pro](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Galaxy-Buds#galaxy-buds2-pro)
|
||||
- Garmin
|
||||
- Vívomove HR
|
||||
- [HPlus Devices (e.g. ZeBand)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/HPlus)
|
||||
- ID115
|
||||
- [iTag](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/iTag)
|
||||
- JYou Y5
|
||||
- Lefun
|
||||
- Lefun ID115 Plus
|
||||
- Other clones: bohemic smart bracelet
|
||||
- Lenovo
|
||||
- Watch 9
|
||||
- [Watch X (Plus)](https://codeberg.org/mamutcho/Gadgetbridge/wiki)
|
||||
- Liveview
|
||||
- Makibes HR3
|
||||
- Mi
|
||||
- [Band, Band 1A, Band 1S](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band), [Band 2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-2), [Band 3](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-3)
|
||||
- [Band 4](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-4), [Band 5](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-5), [Band 6](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-6) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Xiaomi Smart Band 7](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Mi-Band-7) [**\[!\]**](#special-pairing-procedures)
|
||||
- Xiaomi Temperature and Humidity Monitor Clock (LYWSD02/LYWSD02MMC) (partial support)
|
||||
- Scale 2 (Currently only displays a toast after stepping on the scale)
|
||||
- [MyKronoz ZeTime](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/MyKronoz-ZeTime)
|
||||
- NO.1 F1
|
||||
- [Nothing Ear (1)](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Nothing-Ear-%281%29)
|
||||
- [Nut Mini 3, Nut 2 and possibly others](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Nut)
|
||||
- Pebble
|
||||
- [Pebble, Steel, Time, Time Steel, Time Round, 2](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Pebble)
|
||||
- PineTime (InfiniTime Firmware)
|
||||
- Roidmi, Roidmi 3, Mojietu 3 (Bluetooth FM Transmitters)
|
||||
- [SMA](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/SMA) Q2 (SMA-Q2-OSS Firmware)
|
||||
- Sony
|
||||
- [Headphones](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Sony-Headphones)
|
||||
- LinkBuds S
|
||||
- WH-1000XM2, WH-1000XM3, WH-1000XM4, WH-1000XM5
|
||||
- WF-SP800N
|
||||
- WF-1000XM3, WF-1000XM4, WF-1000XM5 (experimental)
|
||||
- [Wena 3](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Sony-Wena-3)
|
||||
- Teclast H10, H30
|
||||
- TLW64
|
||||
- Vibratissimo (Experimental)
|
||||
- Wasp-OS devices
|
||||
- XWatch (Affordable Chinese Casio-like smartwatches)
|
||||
- [Zepp E](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Amazfit-GTR) [**\[!\]**](#special-pairing-procedures)
|
||||
- [Shell Racing cars](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/SuperCars) (BLE RC car models)
|
||||
- [Flipper Zero](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Flipper-Zero) (Multi-tool Device for Geeks)
|
||||
- VESC (BLDC controller VESC)
|
||||
- UM25 (USB Voltage meter)
|
||||
|
||||
|
||||
|
||||
### Special Pairing Procedures
|
||||
|
||||
Some Huami / Amazfit / Mi / Zepp devices can only be paired with Gadgetbridge using a secret key that has to be obtained once using the proprietary app with an account. Detailed instructions in the wiki: [Huami Server Pairing](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Huami-Server-Pairing)
|
||||
|
||||
The Fossil Hybrid HR also requires using the proprietary app, but with a more complicated procedure. Details in the wiki: [Hybrid HR](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Fossil-Hybrid-HR).
|
||||
Please see the [Gadgets](https://gadgetbridge.org/gadgets/) page on the website for a complete list of supported devices.
|
||||
|
||||
## Features
|
||||
|
||||
Please see [FEATURES.md](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/master/FEATURES.md)
|
||||
Please see the [Features](https://gadgetbridge.org/basics/features/) page on the website.
|
||||
|
||||
## Authors
|
||||
### Core Team (in order of first code contribution)
|
||||
|
@ -78,17 +78,19 @@ android {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
compileSdkVersion 33
|
||||
buildToolsVersion "33.0.0"
|
||||
|
||||
namespace 'nodomain.freeyourgadget.gadgetbridge'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "nodomain.freeyourgadget.gadgetbridge"
|
||||
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 33
|
||||
compileSdk 33
|
||||
|
||||
// Note: always bump BOTH versionCode and versionName!
|
||||
versionName "0.76.1"
|
||||
versionCode 226
|
||||
versionName "0.79.0"
|
||||
versionCode 229
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
buildConfigField "String", "GIT_HASH_SHORT", "\"${getGitHashShort()}\""
|
||||
buildConfigField "boolean", "INTERNET_ACCESS", "false"
|
||||
@ -112,8 +114,8 @@ android {
|
||||
|
||||
flavorDimensions "device_type"
|
||||
productFlavors {
|
||||
main {
|
||||
// Ensure that when starting from scratch, 'main' is selected, not 'banglejs'
|
||||
mainline {
|
||||
// Ensure that when starting from scratch, 'mainline' is selected, not 'banglejs'
|
||||
getIsDefault().set(true)
|
||||
// the default build product flavor
|
||||
dimension "device_type"
|
||||
@ -162,20 +164,20 @@ android {
|
||||
resValue "string", "about_activity_title", "@string/about_activity_title_main_nightly"
|
||||
resValue "string", "about_description", "@string/about_description_main_nightly"
|
||||
resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nightly"
|
||||
|
||||
|
||||
debuggable true
|
||||
|
||||
if (System.getProperty("nightly_store_file") != null) {
|
||||
signingConfig signingConfigs.nightly
|
||||
|
||||
//this was conflicting with regular debug type (it should not), so it is only available for CI builds:
|
||||
productFlavors.main.resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
|
||||
productFlavors.main.resValue "string", "app_name", "@string/application_name_main_nightly"
|
||||
productFlavors.main.resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_main_nightly"
|
||||
productFlavors.main.resValue "string", "about_activity_title", "@string/about_activity_title_main_nightly"
|
||||
productFlavors.main.resValue "string", "about_description", "@string/about_description_main_nightly"
|
||||
productFlavors.main.resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nightly"
|
||||
|
||||
productFlavors.mainline.resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
|
||||
productFlavors.mainline.resValue "string", "app_name", "@string/application_name_main_nightly"
|
||||
productFlavors.mainline.resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_main_nightly"
|
||||
productFlavors.mainline.resValue "string", "about_activity_title", "@string/about_activity_title_main_nightly"
|
||||
productFlavors.mainline.resValue "string", "about_description", "@string/about_description_main_nightly"
|
||||
productFlavors.mainline.resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nightly"
|
||||
|
||||
//keep the pebble provider for people who want this. In case of need we can create Banglejs Nopebble
|
||||
productFlavors.banglejs.resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
|
||||
productFlavors.banglejs.resValue "string", "app_name", "@string/application_name_banglejs_nightly"
|
||||
@ -222,10 +224,9 @@ android {
|
||||
|
||||
}
|
||||
|
||||
|
||||
lintOptions {
|
||||
lint {
|
||||
abortOnError ABORT_ON_CHECK_FAILURE
|
||||
lintConfig file("${project.rootDir}/app/src/main/lint.xml")
|
||||
lintConfig file("$rootDir/app/src/main/lint.xml")
|
||||
// If true, generate an HTML report (with issue explanations, sourcecode, etc)
|
||||
htmlReport true
|
||||
// Optional path to report (default will be lint-results.html in the builddir)
|
||||
@ -251,7 +252,7 @@ dependencies {
|
||||
// testImplementation "ch.qos.logback:logback-core:1.1.3"
|
||||
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
testImplementation "org.mockito:mockito-core:1.10.19"
|
||||
testImplementation "org.mockito:mockito-core:2.28.2"
|
||||
testImplementation "org.robolectric:robolectric:4.8.2"
|
||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
||||
testImplementation "com.google.code.gson:gson:2.8.9"
|
||||
@ -289,9 +290,15 @@ dependencies {
|
||||
implementation 'com.jaredrummler:colorpicker:1.0.2'
|
||||
// implementation project(":DaoCore")
|
||||
implementation 'com.github.wax911:android-emojify:0.1.7'
|
||||
implementation 'com.google.protobuf:protobuf-javalite:3.10.0'
|
||||
implementation 'com.google.protobuf:protobuf-javalite:3.21.7'
|
||||
implementation 'com.android.volley:volley:1.2.1'
|
||||
|
||||
// Bouncy Castle is included directly in GB, to avoid pulling the entire dependency
|
||||
// It's included in the org.bouncycastle.shaded package, to fix conflicts with
|
||||
// roboelectric
|
||||
//implementation 'org.bouncycastle:bcpkix-jdk18on:1.76'
|
||||
//implementation 'org.bouncycastle:bcprov-jdk18on:1.76'
|
||||
|
||||
// NON-FOSS dependencies
|
||||
// implementation('androidx.core:core-google-shortcuts:1.0.1') {
|
||||
// exclude group:'com.google.android.gms'
|
||||
@ -399,7 +406,7 @@ tasks.clean.dependsOn(tasks.cleanGenerated)
|
||||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = 'com.google.protobuf:protoc:3.10.0'
|
||||
artifact = 'com.google.protobuf:protoc:3.21.7'
|
||||
}
|
||||
generateProtoTasks {
|
||||
all().each { task ->
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="nodomain.freeyourgadget.gadgetbridge">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!--
|
||||
Comment in for testing Pebble Emulator
|
||||
@ -593,6 +592,10 @@
|
||||
android:name=".activities.ConfigureContacts"
|
||||
android:label="@string/title_activity_set_contacts"
|
||||
android:parentActivityName=".activities.ControlCenterv2" />
|
||||
<activity
|
||||
android:name=".activities.widgets.WidgetScreensListActivity"
|
||||
android:label="@string/menuitem_widgets"
|
||||
android:parentActivityName=".activities.ControlCenterv2" />
|
||||
<activity
|
||||
android:name=".activities.ConfigureWorldClocks"
|
||||
android:label="@string/pref_world_clocks_title"
|
||||
@ -618,6 +621,12 @@
|
||||
android:parentActivityName=".activities.ConfigureReminders"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".activities.widgets.WidgetScreenDetailsActivity"
|
||||
android:label="@string/widget_screen"
|
||||
android:parentActivityName=".activities.widgets.WidgetScreensListActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".activities.WorldClockDetails"
|
||||
android:label="@string/title_activity_world_clock_details"
|
||||
|
BIN
app/src/main/assets/fossil_hr/navigationApp.wapp
Normal file
BIN
app/src/main/assets/fossil_hr/navigationApp.wapp
Normal file
Binary file not shown.
122
app/src/main/assets/migrations/devicetype.json
Normal file
122
app/src/main/assets/migrations/devicetype.json
Normal file
@ -0,0 +1,122 @@
|
||||
{
|
||||
"by-id": {
|
||||
"-1": "UNKNOWN",
|
||||
"1": "PEBBLE",
|
||||
"10": "MIBAND",
|
||||
"11": "MIBAND2",
|
||||
"1001": "MIBAND2_HRX",
|
||||
"12": "AMAZFITBIP",
|
||||
"13": "AMAZFITCOR",
|
||||
"14": "MIBAND3",
|
||||
"15": "AMAZFITCOR2",
|
||||
"16": "MIBAND4",
|
||||
"17": "AMAZFITBIP_LITE",
|
||||
"18": "AMAZFITGTR",
|
||||
"19": "AMAZFITGTS",
|
||||
"20": "AMAZFITBIPS",
|
||||
"21": "AMAZFITGTR_LITE",
|
||||
"22": "AMAZFITTREX",
|
||||
"23": "MIBAND5",
|
||||
"24": "AMAZFITBAND5",
|
||||
"25": "AMAZFITBIPS_LITE",
|
||||
"26": "AMAZFITGTR2",
|
||||
"27": "AMAZFITGTS2",
|
||||
"28": "AMAZFITBIPU",
|
||||
"29": "AMAZFITVERGEL",
|
||||
"30": "AMAZFITBIPUPRO",
|
||||
"31": "AMAZFITNEO",
|
||||
"32": "AMAZFITGTS2_MINI",
|
||||
"33": "ZEPP_E",
|
||||
"34": "AMAZFITGTR2E",
|
||||
"35": "AMAZFITGTS2E",
|
||||
"36": "AMAZFITX",
|
||||
"37": "MIBAND6",
|
||||
"38": "AMAZFITTREXPRO",
|
||||
"39": "AMAZFITPOP",
|
||||
"10040": "AMAZFITPOPPRO",
|
||||
"10041": "MIBAND7",
|
||||
"10042": "AMAZFITGTS3",
|
||||
"10043": "AMAZFITGTR3",
|
||||
"10044": "AMAZFITGTR4",
|
||||
"10045": "AMAZFITBAND7",
|
||||
"10046": "AMAZFITGTS4",
|
||||
"10047": "AMAZFITGTS4MINI",
|
||||
"10048": "AMAZFITTREX2",
|
||||
"10049": "AMAZFITGTR3PRO",
|
||||
"10051": "AMAZFITBIP3PRO",
|
||||
"10050": "AMAZFITCHEETAHPRO",
|
||||
"10052": "AMAZFITCHEETAHSQUARE",
|
||||
"10053": "AMAZFITCHEETAHROUND",
|
||||
"10054": "AMAZFITBIP5",
|
||||
"10055": "AMAZFITTREXULTRA",
|
||||
"10056": "AMAZFITGTRMINI",
|
||||
"10057": "AMAZFITFALCON",
|
||||
"10058": "AMAZFITBALANCE",
|
||||
"40": "HPLUS",
|
||||
"41": "MAKIBESF68",
|
||||
"42": "EXRIZUK8",
|
||||
"43": "Q8",
|
||||
"44": "SG2",
|
||||
"50": "NO1F1",
|
||||
"60": "TECLASTH30",
|
||||
"61": "Y5",
|
||||
"70": "XWATCH",
|
||||
"80": "ZETIME",
|
||||
"90": "ID115",
|
||||
"100": "WATCH9",
|
||||
"102": "WATCHXPLUS",
|
||||
"110": "ROIDMI",
|
||||
"112": "ROIDMI3",
|
||||
"120": "CASIOGB6900",
|
||||
"121": "CASIOGBX100",
|
||||
"122": "CASIOGWB5600",
|
||||
"123": "CASIOGMWB5000",
|
||||
"131": "MISCALE2",
|
||||
"140": "BFH16",
|
||||
"150": "MAKIBESHR3",
|
||||
"160": "BANGLEJS",
|
||||
"170": "FOSSILQHYBRID",
|
||||
"180": "TLW64",
|
||||
"190": "PINETIME_JF",
|
||||
"200": "MIJIA_LYWSD02",
|
||||
"210": "LEFUN",
|
||||
"211": "BOHEMIC_SMART_BRACELET",
|
||||
"220": "SMAQ2OSS",
|
||||
"230": "FITPRO",
|
||||
"250": "ITAG",
|
||||
"251": "NUTMINI",
|
||||
"260": "VIVOMOVE_HR",
|
||||
"300": "VIBRATISSIMO",
|
||||
"310": "SONY_SWR12",
|
||||
"320": "LIVEVIEW",
|
||||
"330": "WASPOS",
|
||||
"350": "UM25",
|
||||
"400": "DOMYOS_T540",
|
||||
"410": "NOTHING_EAR1",
|
||||
"418": "GALAXY_BUDS_PRO",
|
||||
"419": "GALAXY_BUDS_LIVE",
|
||||
"420": "GALAXY_BUDS",
|
||||
"421": "GALAXY_BUDS2",
|
||||
"422": "GALAXY_BUDS2_PRO",
|
||||
"430": "SONY_WH_1000XM3",
|
||||
"431": "SONY_WF_SP800N",
|
||||
"432": "SONY_WH_1000XM4",
|
||||
"433": "SONY_WF_1000XM3",
|
||||
"434": "SONY_WH_1000XM2",
|
||||
"435": "SONY_WF_1000XM4",
|
||||
"436": "SONY_LINKBUDS_S",
|
||||
"437": "SONY_WH_1000XM5",
|
||||
"438": "SONY_WF_1000XM5",
|
||||
"440": "BOSE_QC35",
|
||||
"500": "VESC",
|
||||
"510": "BINARY_SENSOR",
|
||||
"520": "FLIPPER_ZERO",
|
||||
"530": "SUPER_CARS",
|
||||
"540": "ASTEROIDOS",
|
||||
"550": "SOFLOW_SO6",
|
||||
"560": "WITHINGS_STEEL_HR",
|
||||
"570": "SONY_WENA_3",
|
||||
"580": "FEMOMETER_VINCA2",
|
||||
"1000": "TEST"
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
/* Copyright (C) 2015-2021 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Martin, Matthieu Baerts, Normano64, odavo32nof, Pauli Salmenrinne,
|
||||
Pavel Elagin, Petr Vaněk, Saul Nunez, Taavi Eomäe
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
|
||||
Pfeiffer, Damien Gaignon, Daniel Dakhno, Daniele Gobbetti, Davis Mosenkovs,
|
||||
Dmitriy Bogdanov, Joel Beckmeyer, José Rebelo, Kornél Schmidt, Ludovic
|
||||
Jozeau, Martin, Martin.JM, mvn23, Normano64, odavo32nof, Pauli Salmenrinne,
|
||||
Pavel Elagin, Petr Vaněk, Saul Nunez, Taavi Eomäe, x29a
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -15,7 +17,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
@ -47,12 +49,14 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
@ -97,13 +101,13 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.MIBAND3;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.PEBBLE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.TLW64;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.WATCHXPLUS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.fromKey;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_HIGH_PRIORITY_ID;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_ID_ERROR;
|
||||
|
||||
import com.jakewharton.threetenabp.AndroidThreeTen;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Main Application class that initializes and provides access to certain things like
|
||||
@ -120,9 +124,9 @@ public class GBApplication extends Application {
|
||||
private static SharedPreferences sharedPrefs;
|
||||
private static final String PREFS_VERSION = "shared_preferences_version";
|
||||
//if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version
|
||||
private static final int CURRENT_PREFS_VERSION = 22;
|
||||
private static final int CURRENT_PREFS_VERSION = 28;
|
||||
|
||||
private static LimitedQueue mIDSenderLookup = new LimitedQueue(16);
|
||||
private static final LimitedQueue<Integer, String> mIDSenderLookup = new LimitedQueue<>(16);
|
||||
private static Prefs prefs;
|
||||
private static GBPrefs gbPrefs;
|
||||
private static LockHandler lockHandler;
|
||||
@ -225,6 +229,10 @@ public class GBApplication extends Application {
|
||||
migratePrefs(getPrefsFileVersion());
|
||||
}
|
||||
|
||||
// Uncomment the line below to force a device key migration, after you updated
|
||||
// the devicetype.json file
|
||||
//migrateDeviceTypes();
|
||||
|
||||
setupExceptionHandler();
|
||||
|
||||
Weather.getInstance().setCacheFile(getCacheDir(), prefs.getBoolean("cache_weather", true));
|
||||
@ -637,7 +645,7 @@ public class GBApplication extends Application {
|
||||
SharedPreferences deviceSpecificSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
if (deviceSpecificSharedPrefs != null) {
|
||||
SharedPreferences.Editor deviceSharedPrefsEdit = deviceSpecificSharedPrefs.edit();
|
||||
DeviceType deviceType = fromKey(dbDevice.getType());
|
||||
DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||
|
||||
if (deviceTypes.contains(deviceType)) {
|
||||
Log.i(TAG, "migrating global string preference " + globalPref + " for " + deviceType.name() + " " + dbDevice.getIdentifier() );
|
||||
@ -663,7 +671,7 @@ public class GBApplication extends Application {
|
||||
SharedPreferences deviceSpecificSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
if (deviceSpecificSharedPrefs != null) {
|
||||
SharedPreferences.Editor deviceSharedPrefsEdit = deviceSpecificSharedPrefs.edit();
|
||||
DeviceType deviceType = fromKey(dbDevice.getType());
|
||||
DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||
|
||||
if (deviceTypes.contains(deviceType)) {
|
||||
Log.i(TAG, "migrating global boolean preference " + globalPref + " for " + deviceType.name() + " " + dbDevice.getIdentifier() );
|
||||
@ -679,8 +687,42 @@ public class GBApplication extends Application {
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateDeviceTypes() {
|
||||
try (DBHandler db = acquireDB()) {
|
||||
final InputStream inputStream = getAssets().open("migrations/devicetype.json");
|
||||
final byte[] buffer = new byte[inputStream.available()];
|
||||
inputStream.read(buffer);
|
||||
inputStream.close();
|
||||
final JSONObject deviceMapping = new JSONObject(new String(buffer));
|
||||
final JSONObject deviceIdNameMapping = deviceMapping.getJSONObject("by-id");
|
||||
|
||||
final DaoSession daoSession = db.getDaoSession();
|
||||
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
|
||||
|
||||
for (Device dbDevice : activeDevices) {
|
||||
String deviceTypeName = dbDevice.getTypeName();
|
||||
if(deviceTypeName.isEmpty() || deviceTypeName.equals("UNKNOWN")){
|
||||
deviceTypeName = deviceIdNameMapping.optString(
|
||||
String.valueOf(dbDevice.getType()),
|
||||
"UNKNOWN"
|
||||
);
|
||||
dbDevice.setTypeName(deviceTypeName);
|
||||
daoSession.getDeviceDao().update(dbDevice);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "error acquiring DB lock");
|
||||
}
|
||||
}
|
||||
|
||||
private void migratePrefs(int oldVersion) {
|
||||
SharedPreferences.Editor editor = sharedPrefs.edit();
|
||||
|
||||
// this comes before all other migrations since the new column DeviceTypeName was added as non-null
|
||||
if (oldVersion < 25){
|
||||
migrateDeviceTypes();
|
||||
}
|
||||
|
||||
if (oldVersion == 0) {
|
||||
String legacyGender = sharedPrefs.getString("mi_user_gender", null);
|
||||
String legacyHeight = sharedPrefs.getString("mi_user_height_cm", null);
|
||||
@ -738,7 +780,7 @@ public class GBApplication extends Application {
|
||||
String newLanguage = null;
|
||||
Set<String> displayItems = null;
|
||||
|
||||
DeviceType deviceType = fromKey(dbDevice.getType());
|
||||
DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||
|
||||
if (deviceType == AMAZFITBIP || deviceType == AMAZFITCOR || deviceType == AMAZFITCOR2) {
|
||||
int oldLanguage = prefs.getInt("amazfitbip_language", -1);
|
||||
@ -836,7 +878,7 @@ public class GBApplication extends Application {
|
||||
for (Device dbDevice : activeDevices) {
|
||||
SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
|
||||
DeviceType deviceType = fromKey(dbDevice.getType());
|
||||
DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||
|
||||
if (deviceType == MIBAND) {
|
||||
int deviceTimeOffsetHours = deviceSharedPrefs.getInt("device_time_offset_hours",0);
|
||||
@ -857,7 +899,7 @@ public class GBApplication extends Application {
|
||||
SharedPreferences deviceSpecificSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
if (deviceSpecificSharedPrefs != null) {
|
||||
SharedPreferences.Editor deviceSharedPrefsEdit = deviceSpecificSharedPrefs.edit();
|
||||
DeviceType deviceType = fromKey(dbDevice.getType());
|
||||
DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||
|
||||
String newWearside = null;
|
||||
String newOrientation = null;
|
||||
@ -957,7 +999,7 @@ public class GBApplication extends Application {
|
||||
for (Device dbDevice : activeDevices) {
|
||||
SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
|
||||
DeviceType deviceType = fromKey(dbDevice.getType());
|
||||
DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||
|
||||
if (deviceType == GALAXY_BUDS) {
|
||||
GB.log("migrating Galaxy Buds volume", GB.INFO, null);
|
||||
@ -977,7 +1019,7 @@ public class GBApplication extends Application {
|
||||
for (Device dbDevice : activeDevices) {
|
||||
SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
|
||||
DeviceType deviceType = fromKey(dbDevice.getType());
|
||||
DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||
if (deviceType == WATCHXPLUS || deviceType == FITPRO || deviceType == LEFUN) {
|
||||
deviceSharedPrefsEdit.putBoolean("inactivity_warnings_enable", deviceSharedPrefs.getBoolean("pref_longsit_switch", false));
|
||||
deviceSharedPrefsEdit.remove("pref_longsit_switch");
|
||||
@ -1147,7 +1189,7 @@ public class GBApplication extends Application {
|
||||
|
||||
if (oldVersion < 16) {
|
||||
// If transliteration was enabled for a device, migrate it to the per-language setting
|
||||
final String defaultLanguagesIfEnabled = "extended_ascii,common_symbols,scandinavian,german,russian,hebrew,greek,ukranian,arabic,persian,latvian,lithuanian,polish,estonian,icelandic,czech,turkish,bengali,korean";
|
||||
final String defaultLanguagesIfEnabled = "extended_ascii,common_symbols,scandinavian,german,russian,hebrew,greek,ukranian,arabic,persian,latvian,lithuanian,polish,estonian,icelandic,czech,turkish,bengali,korean,hungarian";
|
||||
try (DBHandler db = acquireDB()) {
|
||||
final DaoSession daoSession = db.getDaoSession();
|
||||
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
|
||||
@ -1290,11 +1332,11 @@ public class GBApplication extends Application {
|
||||
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
|
||||
|
||||
for (Device dbDevice : activeDevices) {
|
||||
final DeviceType deviceType = fromKey(dbDevice.getType());
|
||||
final DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName());
|
||||
if (deviceType == MIBAND2) {
|
||||
final String name = dbDevice.getName();
|
||||
if ("Mi Band HRX".equalsIgnoreCase(name) || "Mi Band 2i".equalsIgnoreCase(name)) {
|
||||
dbDevice.setType(DeviceType.MIBAND2_HRX.getKey());
|
||||
dbDevice.setTypeName(DeviceType.MIBAND2_HRX.name());
|
||||
daoSession.getDeviceDao().update(dbDevice);
|
||||
}
|
||||
}
|
||||
@ -1304,6 +1346,107 @@ public class GBApplication extends Application {
|
||||
}
|
||||
}
|
||||
|
||||
if (oldVersion < 26) {
|
||||
try (DBHandler db = acquireDB()) {
|
||||
final DaoSession daoSession = db.getDaoSession();
|
||||
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
|
||||
|
||||
for (final Device dbDevice : activeDevices) {
|
||||
final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
|
||||
final String chartsTabsValue = deviceSharedPrefs.getString("charts_tabs", null);
|
||||
if (chartsTabsValue == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String newPrefValue;
|
||||
if (!StringUtils.isBlank(chartsTabsValue)) {
|
||||
newPrefValue = chartsTabsValue + ",spo2";
|
||||
} else {
|
||||
newPrefValue = "spo2";
|
||||
}
|
||||
|
||||
final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
|
||||
deviceSharedPrefsEdit.putString("charts_tabs", newPrefValue);
|
||||
deviceSharedPrefsEdit.apply();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "error acquiring DB lock");
|
||||
}
|
||||
}
|
||||
|
||||
if (oldVersion < 27) {
|
||||
try (DBHandler db = acquireDB()) {
|
||||
final DaoSession daoSession = db.getDaoSession();
|
||||
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
|
||||
|
||||
for (final Device dbDevice : activeDevices) {
|
||||
final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
|
||||
|
||||
for (final Map.Entry<String, ?> entry : deviceSharedPrefs.getAll().entrySet()) {
|
||||
final String key = entry.getKey();
|
||||
if (key.startsWith("huami_2021_known_config_")) {
|
||||
deviceSharedPrefsEdit.putString(
|
||||
key.replace("huami_2021_known_config_", "") + "_is_known",
|
||||
entry.getValue().toString()
|
||||
);
|
||||
} else if (key.endsWith("_huami_2021_possible_values")) {
|
||||
deviceSharedPrefsEdit.putString(
|
||||
key.replace("_huami_2021_possible_values", "") + "_possible_values",
|
||||
entry.getValue().toString()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
deviceSharedPrefsEdit.apply();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "error acquiring DB lock");
|
||||
}
|
||||
}
|
||||
|
||||
if (oldVersion < 28) {
|
||||
try (DBHandler db = acquireDB()) {
|
||||
final DaoSession daoSession = db.getDaoSession();
|
||||
final List<Device> activeDevices = DBHelper.getActiveDevices(daoSession);
|
||||
|
||||
for (final Device dbDevice : activeDevices) {
|
||||
final SharedPreferences deviceSharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier());
|
||||
final SharedPreferences.Editor deviceSharedPrefsEdit = deviceSharedPrefs.edit();
|
||||
boolean shouldApply = false;
|
||||
|
||||
if (!"UNKNOWN".equals(deviceSharedPrefs.getString("events_forwarding_fellsleep_action_selection", "UNKNOWN"))) {
|
||||
shouldApply = true;
|
||||
deviceSharedPrefsEdit.putStringSet(
|
||||
"events_forwarding_fellsleep_action_selections",
|
||||
Collections.singleton(deviceSharedPrefs.getString("events_forwarding_fellsleep_action_selection", "UNKNOWN"))
|
||||
);
|
||||
}
|
||||
if (!"UNKNOWN".equals(deviceSharedPrefs.getString("events_forwarding_wokeup_action_selection", "UNKNOWN"))) {
|
||||
shouldApply = true;
|
||||
deviceSharedPrefsEdit.putStringSet(
|
||||
"events_forwarding_wokeup_action_selections",
|
||||
Collections.singleton(deviceSharedPrefs.getString("events_forwarding_wokeup_action_selection", "UNKNOWN"))
|
||||
);
|
||||
}
|
||||
if (!"UNKNOWN".equals(deviceSharedPrefs.getString("events_forwarding_startnonwear_action_selection", "UNKNOWN"))) {
|
||||
shouldApply = true;
|
||||
deviceSharedPrefsEdit.putStringSet(
|
||||
"events_forwarding_startnonwear_action_selections",
|
||||
Collections.singleton(deviceSharedPrefs.getString("events_forwarding_startnonwear_action_selection", "UNKNOWN"))
|
||||
);
|
||||
}
|
||||
|
||||
if (shouldApply) {
|
||||
deviceSharedPrefsEdit.apply();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "error acquiring DB lock");
|
||||
}
|
||||
}
|
||||
|
||||
editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION));
|
||||
editor.apply();
|
||||
}
|
||||
@ -1340,7 +1483,7 @@ public class GBApplication extends Application {
|
||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
||||
}
|
||||
|
||||
public static LimitedQueue getIDSenderLookup() {
|
||||
public static LimitedQueue<Integer, String> getIDSenderLookup() {
|
||||
return mIDSenderLookup;
|
||||
}
|
||||
|
||||
@ -1421,6 +1564,10 @@ public class GBApplication extends Application {
|
||||
return BuildConfig.APPLICATION_ID.contains("nightly");
|
||||
}
|
||||
|
||||
public static boolean isDebug() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
try {
|
||||
return getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA).versionName;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2021 Andreas Shimokawa, Carsten Pfeiffer
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
public class GBException extends Exception {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Taavi Eomäe
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer, Taavi Eomäe
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2016-2021 Carsten Pfeiffer, Daniele Gobbetti, Pavel Elagin
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, José Rebelo, Pavel Elagin, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
import android.util.Log;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2021 Carsten Pfeiffer
|
||||
/* Copyright (C) 2015-2024 Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2016-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer
|
||||
/* Copyright (C) 2016-2024 0nse, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Dmitry Markin, Ganblejs, José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous
|
||||
/* Copyright (C) 2019-2024 Andreas Shimokawa, Carsten Pfeiffer, Ganblejs,
|
||||
José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -11,27 +12,9 @@
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, Lem Dulfo
|
||||
/* Copyright (C) 2020-2024 Petr Vaněk, Taavi Eomäe
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2023 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo,
|
||||
vanous, José Rebelo
|
||||
/* Copyright (C) 2020-2024 Andreas Shimokawa, José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_ACTIVETIME_MINUTES;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Carsten Pfeiffer, Daniele Gobbetti
|
||||
/* Copyright (C) 2015-2024 Carsten Pfeiffer, Daniele Gobbetti
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Lem Dulfo
|
||||
/* Copyright (C) 2017-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
|
||||
Pfeiffer, Daniele Gobbetti, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, walkjivefly
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer
|
||||
/* Copyright (C) 2017-2024 Andreas Shimokawa, Carsten Pfeiffer, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019-2023 Andreas Shimokawa, Cre3per, José Rebelo
|
||||
/* Copyright (C) 2023-2024 Andreas Shimokawa, Arjan Schrijver, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,11 +13,12 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.preference.EditTextPreference;
|
||||
@ -38,9 +39,12 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreferenceFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.dialogs.MaterialEditTextPreferenceDialogFragment;
|
||||
@ -199,7 +203,29 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragmentCompa
|
||||
}
|
||||
|
||||
if (getPreferenceKeysWithSummary().contains(key)) {
|
||||
final String summary = prefs.getString(key, preference.getSummary() != null ? preference.getSummary().toString() : "");
|
||||
final String summary;
|
||||
|
||||
// For multi select preferences, let's set the summary to the values, comma-delimited
|
||||
if (preference instanceof MultiSelectListPreference) {
|
||||
final Set<String> prefSetValue = prefs.getStringSet(key, Collections.emptySet());
|
||||
if (prefSetValue.isEmpty()) {
|
||||
summary = requireContext().getString(R.string.not_set);
|
||||
} else {
|
||||
final MultiSelectListPreference multiSelectListPreference = (MultiSelectListPreference) preference;
|
||||
final CharSequence[] entries = multiSelectListPreference.getEntries();
|
||||
final CharSequence[] entryValues = multiSelectListPreference.getEntryValues();
|
||||
final List<String> translatedEntries = new ArrayList<>();
|
||||
for (int i = 0; i < entryValues.length; i++) {
|
||||
if (prefSetValue.contains(entryValues[i].toString())) {
|
||||
translatedEntries.add(entries[i].toString());
|
||||
}
|
||||
}
|
||||
summary = TextUtils.join(", ", translatedEntries);
|
||||
}
|
||||
} else {
|
||||
summary = prefs.getString(key, preference.getSummary() != null ? preference.getSummary().toString() : "");
|
||||
}
|
||||
|
||||
preference.setSummary(summary);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Christian
|
||||
Fischer, Daniele Gobbetti, Lem Dulfo
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Christian
|
||||
Fischer, Daniele Gobbetti, José Rebelo, Lem Dulfo, Petr Vaněk, Taavi Eomäe
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019-2023 Andreas Shimokawa, José Rebelo
|
||||
/* Copyright (C) 2023-2024 José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2017-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti
|
||||
/* Copyright (C) 2017-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
|
||||
Pfeiffer, Daniele Gobbetti, José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.DatePickerDialog;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Dikay900, Pavel Elagin
|
||||
/* Copyright (C) 2020-2024 José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019-2020 vanous
|
||||
/* Copyright (C) 2020-2024 Daniel Dakhno, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.DatePickerDialog;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Dikay900, Pavel Elagin
|
||||
/* Copyright (C) 2020-2024 José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, Lem Dulfo
|
||||
/* Copyright (C) 2020-2024 Andreas Shimokawa, Arjan Schrijver, Daniel Dakhno,
|
||||
José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,9 +14,11 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.*;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
@ -86,7 +88,6 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryJsonSummary;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.SwipeEvents;
|
||||
@ -464,13 +465,13 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
|
||||
if (!show_raw_data) {
|
||||
//special casing here + imperial units handling
|
||||
switch (unit) {
|
||||
case "cm":
|
||||
case UNIT_CM:
|
||||
if (units.equals(UNIT_IMPERIAL)) {
|
||||
value = value * 0.0328084;
|
||||
unit = "ft";
|
||||
}
|
||||
break;
|
||||
case "meters_second":
|
||||
case UNIT_METERS_PER_SECOND:
|
||||
if (units.equals(UNIT_IMPERIAL)) {
|
||||
value = value * 2.236936D;
|
||||
unit = "mi_h";
|
||||
@ -479,7 +480,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
|
||||
unit = "km_h";
|
||||
}
|
||||
break;
|
||||
case "seconds_m":
|
||||
case UNIT_SECONDS_PER_M:
|
||||
if (units.equals(UNIT_IMPERIAL)) {
|
||||
value = value * (1609.344 / 60D);
|
||||
unit = "minutes_mi";
|
||||
@ -488,7 +489,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
|
||||
unit = "minutes_km";
|
||||
}
|
||||
break;
|
||||
case "seconds_km":
|
||||
case UNIT_SECONDS_PER_KM:
|
||||
if (units.equals(UNIT_IMPERIAL)) {
|
||||
value = value / 60D * 1.609344;
|
||||
unit = "minutes_mi";
|
||||
@ -497,7 +498,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
|
||||
unit = "minutes_km";
|
||||
}
|
||||
break;
|
||||
case "meters":
|
||||
case UNIT_METERS:
|
||||
if (units.equals(UNIT_IMPERIAL)) {
|
||||
value = value * 3.28084D;
|
||||
unit = "ft";
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Lem Dulfo
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniel
|
||||
Dakhno, Daniele Gobbetti, Dmitry Markin, Lem Dulfo, Taavi Eomäe
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,10 +14,11 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.InputFilter;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@ -132,10 +133,15 @@ public class AlarmDetails extends AbstractGBActivity {
|
||||
int snoozeVisibility = supportsSnoozing() ? View.VISIBLE : View.GONE;
|
||||
cbSnooze.setVisibility(snoozeVisibility);
|
||||
|
||||
int descriptionVisibility = supportsDescription() ? View.VISIBLE : View.GONE;
|
||||
title.setVisibility(descriptionVisibility);
|
||||
title.setVisibility(supportsTitle() ? View.VISIBLE : View.GONE);
|
||||
title.setText(alarm.getTitle());
|
||||
description.setVisibility(descriptionVisibility);
|
||||
|
||||
final int titleLimit = getAlarmTitleLimit();
|
||||
if (titleLimit > 0) {
|
||||
title.setFilters(new InputFilter[]{new InputFilter.LengthFilter(titleLimit)});
|
||||
}
|
||||
|
||||
description.setVisibility(supportsDescription() ? View.VISIBLE : View.GONE);
|
||||
description.setText(alarm.getDescription());
|
||||
|
||||
cbMonday.setChecked(alarm.getRepetition(Alarm.ALARM_MON));
|
||||
@ -145,7 +151,6 @@ public class AlarmDetails extends AbstractGBActivity {
|
||||
cbFriday.setChecked(alarm.getRepetition(Alarm.ALARM_FRI));
|
||||
cbSaturday.setChecked(alarm.getRepetition(Alarm.ALARM_SAT));
|
||||
cbSunday.setChecked(alarm.getRepetition(Alarm.ALARM_SUN));
|
||||
|
||||
}
|
||||
|
||||
private boolean supportsSmartWakeup() {
|
||||
@ -156,6 +161,22 @@ public class AlarmDetails extends AbstractGBActivity {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean supportsTitle() {
|
||||
if (device != null) {
|
||||
DeviceCoordinator coordinator = device.getDeviceCoordinator();
|
||||
return coordinator.supportsAlarmTitle(device);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getAlarmTitleLimit() {
|
||||
if (device != null) {
|
||||
DeviceCoordinator coordinator = device.getDeviceCoordinator();
|
||||
return coordinator.getAlarmTitleLimit(device);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean supportsDescription() {
|
||||
if (device != null) {
|
||||
DeviceCoordinator coordinator = device.getDeviceCoordinator();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, Lem Dulfo
|
||||
/* Copyright (C) 2015-2024 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, Lem Dulfo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,3 +1,19 @@
|
||||
/* Copyright (C) 2021-2024 Daniel Dakhno, José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.DatePickerDialog;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Dikay900, Pavel Elagin
|
||||
/* Copyright (C) 2021-2024 José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2017-2020 Carsten Pfeiffer, Daniele Gobbetti
|
||||
/* Copyright (C) 2017-2024 Carsten Pfeiffer, Daniele Gobbetti, José Rebelo,
|
||||
Ludovic Jozeau
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.Manifest;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Lem Dulfo, vanous
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Damien
|
||||
Gaignon, Daniel Dakhno, Daniele Gobbetti, Dmitry Markin, José Rebelo,
|
||||
Lem Dulfo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +15,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2023 José Rebelo
|
||||
/* Copyright (C) 2023-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 José Rebelo
|
||||
/* Copyright (C) 2021-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,16 +13,20 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@ -49,7 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Reminder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
|
||||
@ -61,12 +65,25 @@ public class ConfigureReminders extends AbstractGBActivity {
|
||||
private GBReminderListAdapter mGBReminderListAdapter;
|
||||
private GBDevice gbDevice;
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (DeviceService.ACTION_SAVE_REMINDERS.equals(intent.getAction())) {
|
||||
updateRemindersFromDB();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_configure_reminders);
|
||||
|
||||
IntentFilter filterLocal = new IntentFilter();
|
||||
filterLocal.addAction(DeviceService.ACTION_SAVE_REMINDERS);
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
|
||||
|
||||
gbDevice = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
||||
|
||||
mGBReminderListAdapter = new GBReminderListAdapter(this);
|
||||
@ -118,6 +135,12 @@ public class ConfigureReminders extends AbstractGBActivity {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2022 José Rebelo
|
||||
/* Copyright (C) 2022-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2023 José Rebelo
|
||||
/* Copyright (C) 2023-2024 Daniel Dakhno, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -1,5 +1,7 @@
|
||||
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Johannes Tysiak, Taavi Eomäe, vanous
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Andrzej Surowiec, Arjan
|
||||
Schrijver, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Ganblejs,
|
||||
gfwilliams, Gordon Williams, Johannes Tysiak, José Rebelo, marco.altomonte,
|
||||
Petr Vaněk, Taavi Eomäe
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +16,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2016-2020 Alberto, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, vanous
|
||||
/* Copyright (C) 2021-2024 Arjan Schrijver, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Frank Slezak, ivanovlev, Kasha, Lem Dulfo, Pavel Elagin, Steffen
|
||||
Liebergeld, vanous
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
|
||||
Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Dmitriy Bogdanov, Frank Slezak,
|
||||
Ganblejs, ivanovlev, José Rebelo, Kamalei Zestri, Kasha, Lem Dulfo, Pavel
|
||||
Elagin, Petr Vaněk, Steffen Liebergeld, Tim
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -15,7 +16,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import static android.content.Intent.EXTRA_SUBJECT;
|
||||
@ -63,6 +64,7 @@ import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
@ -157,7 +159,7 @@ public class DebugActivity extends AbstractGBActivity {
|
||||
};
|
||||
private Spinner sendTypeSpinner;
|
||||
private EditText editContent;
|
||||
public static final long SELECT_DEVICE = 999L;
|
||||
public static final long SELECT_DEVICE = -1;
|
||||
private long selectedTestDeviceKey = SELECT_DEVICE;
|
||||
private String selectedTestDeviceMAC;
|
||||
|
||||
@ -778,7 +780,7 @@ public class DebugActivity extends AbstractGBActivity {
|
||||
|
||||
final GBDevice device = devices.get(0);
|
||||
|
||||
final CompanionDeviceManager manager = (CompanionDeviceManager) GBApplication.getContext().getSystemService(Context.COMPANION_DEVICE_SERVICE);
|
||||
final CompanionDeviceManager manager = (CompanionDeviceManager) getSystemService(Context.COMPANION_DEVICE_SERVICE);
|
||||
|
||||
if (manager.getAssociations().contains(device.getAddress())) {
|
||||
GB.toast(device.getAliasOrName() + " already paired as companion", Toast.LENGTH_LONG, GB.INFO);
|
||||
@ -801,7 +803,7 @@ public class DebugActivity extends AbstractGBActivity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceFound(final IntentSender chooserLauncher) {
|
||||
public void onDeviceFound(@NonNull final IntentSender chooserLauncher) {
|
||||
GB.toast("Found device", Toast.LENGTH_SHORT, GB.INFO);
|
||||
|
||||
try {
|
||||
@ -1003,7 +1005,7 @@ public class DebugActivity extends AbstractGBActivity {
|
||||
if (deviceKey == SELECT_DEVICE) {
|
||||
return;
|
||||
}
|
||||
DeviceType deviceType = DeviceType.fromKey((int) deviceKey);
|
||||
DeviceType deviceType = DeviceType.values()[(int) deviceKey];
|
||||
try (
|
||||
DBHandler db = GBApplication.acquireDB()) {
|
||||
DaoSession daoSession = db.getDaoSession();
|
||||
@ -1153,7 +1155,7 @@ public class DebugActivity extends AbstractGBActivity {
|
||||
DeviceCoordinator coordinator = deviceType.getDeviceCoordinator();
|
||||
int icon = coordinator.getDefaultIconResource();
|
||||
String name = app.getString(coordinator.getDeviceNameResource()) + " (" + coordinator.getManufacturer() + ")";
|
||||
long deviceId = deviceType.getKey();
|
||||
long deviceId = deviceType.ordinal();
|
||||
newMap.put(name, new Pair(deviceId, icon));
|
||||
}
|
||||
TreeMap <String, Pair<Long, Integer>> sortedMap = new TreeMap<>(newMap);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Lem Dulfo, Uwe Hermann
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Davis Mosenkovs, Lem Dulfo, Taavi Eomäe, Uwe Hermann
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
@ -35,8 +35,10 @@ import androidx.core.app.NavUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
@ -51,6 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.GBWeb
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.JSInterface;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.WebViewSingleton;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
|
||||
@ -91,28 +94,22 @@ public class ExternalPebbleJSActivity extends AbstractGBActivity {
|
||||
DeviceManager deviceManager = ((GBApplication) getApplication()).getDeviceManager();
|
||||
List<GBDevice> deviceList = deviceManager.getDevices();
|
||||
for (GBDevice device : deviceList) {
|
||||
if (device.getState() == GBDevice.State.INITIALIZED) {
|
||||
if (device.getType().equals(DeviceType.PEBBLE)) {
|
||||
currentDevice = device;
|
||||
break;
|
||||
} else {
|
||||
LOG.error("attempting to load pebble configuration but a different device type is connected!!!");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
if (device.getState() == GBDevice.State.INITIALIZED && device.getType().equals(DeviceType.PEBBLE)) {
|
||||
currentDevice = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (currentDevice == null) {
|
||||
//then try to reconnect to last connected device
|
||||
String btDeviceAddress = GBApplication.getPrefs().getPreferences().getString("last_device_address", null);
|
||||
if (btDeviceAddress != null) {
|
||||
GBDevice candidate = DeviceHelper.getInstance().findAvailableDevice(btDeviceAddress, this);
|
||||
if(!candidate.isConnected() && candidate.getType() == DeviceType.PEBBLE){
|
||||
//then try to reconnect to one of last connected Pebble devices
|
||||
Set<String> lastDeviceAddresses = GBApplication.getPrefs().getStringSet(GBPrefs.LAST_DEVICE_ADDRESSES, Collections.emptySet());
|
||||
for (GBDevice device : deviceList) {
|
||||
if (!device.isConnected() && device.getType() == DeviceType.PEBBLE && lastDeviceAddresses.contains(device.getAddress())) {
|
||||
Intent intent = new Intent(this, DeviceCommunicationService.class)
|
||||
.setAction(ACTION_CONNECT)
|
||||
.putExtra(GBDevice.EXTRA_DEVICE, currentDevice);
|
||||
.putExtra(GBDevice.EXTRA_DEVICE, device);
|
||||
this.startService(intent);
|
||||
currentDevice = candidate;
|
||||
currentDevice = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -195,6 +192,9 @@ public class ExternalPebbleJSActivity extends AbstractGBActivity {
|
||||
webSettings.setDomStorageEnabled(true);
|
||||
//needed for localstorage
|
||||
webSettings.setDatabaseEnabled(true);
|
||||
// #3373 #3424 - Fix configuration for pebble apps
|
||||
// TODO: this should use a WebViewAssetLoader
|
||||
webSettings.setAllowFileAccess(true);
|
||||
|
||||
JSInterface gbJSInterface = new JSInterface(device, uuid);
|
||||
myWebView.addJavascriptInterface(gbJSInterface, "GBjs");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2018-2020 Andreas Shimokawa, Carsten Pfeiffer, Cre3per,
|
||||
Daniele Gobbetti
|
||||
/* Copyright (C) 2018-2024 Andreas Shimokawa, Anemograph, Carsten Pfeiffer,
|
||||
Cre3per, Daniele Gobbetti, Dmitriy Bogdanov, José Rebelo, Pauli Salmenrinne
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Lem Dulfo, Taavi Eomäe
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniel
|
||||
Dakhno, Daniele Gobbetti, José Rebelo, Lem Dulfo, Petr Vaněk, Taavi Eomäe
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import java.util.Locale;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, Lem Dulfo
|
||||
/* Copyright (C) 2021-2024 Gordon Williams, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.ClipData;
|
||||
|
@ -1,3 +1,19 @@
|
||||
/* Copyright (C) 2021-2024 Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.Dialog;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2020 Carsten Pfeiffer, Dikay900
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer, Dikay900
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2018-2020 abettenburg, AndrewBedscastle, Carsten Pfeiffer,
|
||||
/* Copyright (C) 2018-2024 abettenburg, AndrewBedscastle, Carsten Pfeiffer,
|
||||
Daniele Gobbetti
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2023 Andreas Shimokawa, Carsten Pfeiffer, Lem Dulfo,
|
||||
vanous, José Rebelo
|
||||
/* Copyright (C) 2021-2024 José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 vanous,
|
||||
/* Copyright (C) 2022-2024 Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 José Rebelo
|
||||
/* Copyright (C) 2021-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.DatePickerDialog;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Copyright (C) 2015-2023 0nse, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniel Dakhno, Daniele Gobbetti, Felix Konstantin Maurer, José Rebelo,
|
||||
Martin, Normano64, Pavel Elagin, Sebastian Kranz, vanous
|
||||
/* Copyright (C) 2015-2024 0nse, Andreas Shimokawa, Anemograph, Arjan
|
||||
Schrijver, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Felix Konstantin
|
||||
Maurer, José Rebelo, Martin, Normano64, Pavel Elagin, Petr Vaněk, Sebastian
|
||||
Kranz, Taavi Eomäe
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -15,7 +16,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.Manifest;
|
||||
|
@ -1,3 +1,20 @@
|
||||
/* Copyright (C) 2022-2024 Arjan Schrijver, Damien Gaignon, Daniel Dakhno,
|
||||
Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2023 José Rebelo
|
||||
/* Copyright (C) 2023-2024 José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Carsten Pfeiffer
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,3 +1,19 @@
|
||||
/* Copyright (C) 2022-2024 Ganblejs
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2019-2020 vanous
|
||||
/* Copyright (C) 2019-2024 Dmitry Markin, José Rebelo, Petr Vaněk,
|
||||
Taavi Eomäe
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -1,3 +1,19 @@
|
||||
/* Copyright (C) 2020-2024 Arjan Schrijver, Daniel Dakhno, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2022 José Rebelo
|
||||
/* Copyright (C) 2022-2024 Arjan Schrijver, Daniel Dakhno, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
|
@ -1,22 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2023 akasaka / Genjitsu Labs
|
||||
*
|
||||
* This file is part of Gadgetbridge.
|
||||
*
|
||||
* Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Gadgetbridge is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* Copyright (C) 2023-2024 akasaka / Genjitsu Labs
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.app_specific_notifications;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,22 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2023 akasaka / Genjitsu Labs
|
||||
*
|
||||
* This file is part of Gadgetbridge.
|
||||
*
|
||||
* Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Gadgetbridge is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* Copyright (C) 2023-2024 akasaka / Genjitsu Labs, Daniel Dakhno
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.app_specific_notifications;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Konrad Iturbe, Lem Dulfo
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
|
||||
Pfeiffer, Daniel Dakhno, Daniele Gobbetti, José Rebelo, Konrad Iturbe,
|
||||
TylerWilliamson
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +15,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_ACTION_DOWNLOADED_FILE;
|
||||
@ -74,7 +75,6 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GridAutoFitLayoutManager;
|
||||
@ -280,6 +280,11 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
||||
return cachedAppList;
|
||||
}
|
||||
|
||||
if (cachePath == null) {
|
||||
LOG.warn("Cached apps path is null");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
File[] files;
|
||||
if (uuids == null) {
|
||||
files = cachePath.listFiles();
|
||||
@ -544,6 +549,9 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
||||
if ((mGBDevice.getType() != DeviceType.FOSSILQHYBRID) || (!selectedApp.isOnDevice()) || ((selectedApp.getType() != GBDeviceApp.Type.WATCHFACE) && (selectedApp.getType() != GBDeviceApp.Type.APP_GENERIC))) {
|
||||
menu.removeItem(R.id.appmanager_app_download);
|
||||
}
|
||||
if (mGBDevice.getType() == DeviceType.FOSSILQHYBRID && selectedApp.getName().equals("workoutApp")) {
|
||||
menu.removeItem(R.id.appmanager_app_delete);
|
||||
}
|
||||
|
||||
if (mGBDevice.getType() == DeviceType.PEBBLE) {
|
||||
switch (selectedApp.getType()) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
|
||||
Pfeiffer, Daniele Gobbetti, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
|
||||
|
||||
import android.app.Activity;
|
||||
@ -45,6 +45,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractFragmentPagerAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBFragmentActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.FwAppInstallerActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
|
||||
@ -56,6 +57,8 @@ public class AppManagerActivity extends AbstractGBFragmentActivity {
|
||||
|
||||
private GBDevice mGBDevice = null;
|
||||
|
||||
private List<String> enabledTabsList;
|
||||
|
||||
public GBDevice getGBDevice() {
|
||||
return mGBDevice;
|
||||
}
|
||||
@ -75,6 +78,20 @@ public class AppManagerActivity extends AbstractGBFragmentActivity {
|
||||
throw new IllegalArgumentException("Must provide a device when invoking this activity");
|
||||
}
|
||||
|
||||
final DeviceCoordinator coordinator = mGBDevice.getDeviceCoordinator();
|
||||
|
||||
enabledTabsList = new ArrayList<>();
|
||||
|
||||
if (coordinator.supportsCachedAppManagement(mGBDevice)) {
|
||||
enabledTabsList.add("cache");
|
||||
}
|
||||
if (coordinator.supportsInstalledAppManagement(mGBDevice)) {
|
||||
enabledTabsList.add("apps");
|
||||
}
|
||||
if (coordinator.supportsWatchfaceManagement(mGBDevice)) {
|
||||
enabledTabsList.add("watchfaces");
|
||||
}
|
||||
|
||||
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||
assert fab != null;
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
@ -114,12 +131,12 @@ public class AppManagerActivity extends AbstractGBFragmentActivity {
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
// getItem is called to instantiate the fragment for the given page.
|
||||
switch (position) {
|
||||
case 0:
|
||||
switch (enabledTabsList.get(position)) {
|
||||
case "cache":
|
||||
return new AppManagerFragmentCache();
|
||||
case 1:
|
||||
case "apps":
|
||||
return new AppManagerFragmentInstalledApps();
|
||||
case 2:
|
||||
case "watchfaces":
|
||||
return new AppManagerFragmentInstalledWatchfaces();
|
||||
}
|
||||
return null;
|
||||
@ -127,19 +144,18 @@ public class AppManagerActivity extends AbstractGBFragmentActivity {
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 3;
|
||||
return enabledTabsList.toArray().length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
switch (enabledTabsList.get(position)) {
|
||||
case "cache":
|
||||
return getString(R.string.appmanager_cached_watchapps_watchfaces);
|
||||
case 1:
|
||||
case "apps":
|
||||
return getString(R.string.appmanager_installed_watchapps);
|
||||
case 2:
|
||||
case "watchfaces":
|
||||
return getString(R.string.appmanager_installed_watchfaces);
|
||||
case 3:
|
||||
}
|
||||
return super.getPageTitle(position);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2020 Andreas Shimokawa
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2016-2020 Andreas Shimokawa, Daniele Gobbetti
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver, Daniele
|
||||
Gobbetti
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2020 Andreas Shimokawa
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, Dikay900, Pavel Elagin, vanous, walkjivefly
|
||||
/* Copyright (C) 2023-2024 Daniel Dakhno, José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.util.TypedValue;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 0nse, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, Dikay900, Pavel Elagin, vanous, walkjivefly
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Dikay900, José Rebelo, Pavel Elagin, Petr Vaněk, walkjivefly
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, vanous, Vebryn
|
||||
/* Copyright (C) 2023-2024 José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 0nse, Alberto, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, Pavel Elagin, vanous
|
||||
/* Copyright (C) 2017-2024 Alberto, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, José Rebelo, Pavel Elagin, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.app.Activity;
|
||||
@ -371,14 +371,14 @@ public abstract class AbstractWeekChartFragment extends AbstractActivityChartFra
|
||||
|
||||
private ActivityAmounts getActivityAmountsForDay(DBHandler db, Calendar day, GBDevice device) {
|
||||
|
||||
LimitedQueue activityAmountCache = null;
|
||||
LimitedQueue<Integer, ActivityAmounts> activityAmountCache = null;
|
||||
ActivityAmounts amounts = null;
|
||||
|
||||
Activity activity = getActivity();
|
||||
int key = (int) (day.getTimeInMillis() / 1000) + (mOffsetHours * 3600);
|
||||
if (activity != null) {
|
||||
activityAmountCache = ((ActivityChartsActivity) activity).mActivityAmountCache;
|
||||
amounts = (ActivityAmounts) (activityAmountCache.lookup(key));
|
||||
amounts = activityAmountCache.lookup(key);
|
||||
}
|
||||
|
||||
if (amounts == null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Pavel Elagin, vanous, Vebryn
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, José Rebelo, Pavel Elagin, Petr Vaněk, Vebryn
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, vanous, Vebryn
|
||||
/* Copyright (C) 2023-2024 Daniel Dakhno, José Rebelo, Martin.JM
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.content.Context;
|
||||
@ -33,13 +32,13 @@ import nodomain.freeyourgadget.gadgetbridge.activities.AbstractFragmentPagerAdap
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
public class ActivityChartsActivity extends AbstractChartsActivity {
|
||||
LimitedQueue mActivityAmountCache = new LimitedQueue(60);
|
||||
LimitedQueue<Integer, ActivityAmounts> mActivityAmountCache = new LimitedQueue<>(60);
|
||||
|
||||
@Override
|
||||
protected AbstractFragmentPagerAdapter createFragmentPagerAdapter(final FragmentManager fragmentManager) {
|
||||
@ -94,6 +93,9 @@ public class ActivityChartsActivity extends AbstractChartsActivity {
|
||||
if (!coordinator.supportsPai()) {
|
||||
tabList.remove("pai");
|
||||
}
|
||||
if (!coordinator.supportsSpo2()) {
|
||||
tabList.remove("spo2");
|
||||
}
|
||||
if (!coordinator.supportsStepCounter()) {
|
||||
tabList.remove("stepsweek");
|
||||
}
|
||||
@ -145,6 +147,8 @@ public class ActivityChartsActivity extends AbstractChartsActivity {
|
||||
return new SpeedZonesFragment();
|
||||
case "livestats":
|
||||
return new LiveActivityFragment();
|
||||
case "spo2":
|
||||
return new Spo2ChartFragment();
|
||||
case "temperature":
|
||||
return new TemperatureChartFragment();
|
||||
}
|
||||
@ -186,13 +190,15 @@ public class ActivityChartsActivity extends AbstractChartsActivity {
|
||||
case "stress":
|
||||
return getString(R.string.menuitem_stress);
|
||||
case "pai":
|
||||
return getString(R.string.menuitem_pai);
|
||||
return getString(getDevice().getDeviceCoordinator().getPaiName());
|
||||
case "stepsweek":
|
||||
return getStepsTitle();
|
||||
case "speedzones":
|
||||
return getString(R.string.stats_title);
|
||||
case "livestats":
|
||||
return getString(R.string.liveactivity_live_activity);
|
||||
case "spo2":
|
||||
return getString(R.string.pref_header_spo2);
|
||||
case "temperature":
|
||||
return getString(R.string.temperature);
|
||||
}
|
||||
|
@ -1,3 +1,19 @@
|
||||
/* Copyright (C) 2020-2024 José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Dikay900, Pavel Elagin
|
||||
/* Copyright (C) 2020-2024 José Rebelo, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -1,3 +1,19 @@
|
||||
/* Copyright (C) 2021-2024 Arjan Schrijver, Daniel Dakhno, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.app.DatePickerDialog;
|
||||
|
@ -1,3 +1,19 @@
|
||||
/* Copyright (C) 2021-2024 Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Dikay900, Pavel Elagin
|
||||
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniele
|
||||
Gobbetti, Dikay900, José Rebelo, Pavel Elagin
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous
|
||||
/* Copyright (C) 2019-2024 Andreas Shimokawa, Petr Vaněk
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user