mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
Compare commits
94
Commits
v1.3.13
...
v2.3.0-rc0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
624898dd5e | ||
|
|
c6d6604399 | ||
|
|
7473704954 | ||
|
|
7a6b216bf6 | ||
|
|
1ef09124af | ||
|
|
6340f73d61 | ||
|
|
b9f4992a33 | ||
|
|
07a1fee013 | ||
|
|
63f37e51ad | ||
|
|
01ea08a5cb | ||
|
|
bddb20c5bb | ||
|
|
f9a97297da | ||
|
|
5fc2b56635 | ||
|
|
172953ccb3 | ||
|
|
d55300f53d | ||
|
|
c3d4500e3a | ||
|
|
cf72e28727 | ||
|
|
b488a1be16 | ||
|
|
805d0cb4b6 | ||
|
|
fa045c2504 | ||
|
|
23fd373a9b | ||
|
|
ab619cb073 | ||
|
|
2d96822014 | ||
|
|
887adc87de | ||
|
|
4219bd02c5 | ||
|
|
48544464ae | ||
|
|
9b4f2477e4 | ||
|
|
26e8840484 | ||
|
|
b6ef6d3ce9 | ||
|
|
cdfcd24049 | ||
|
|
95a8e0b125 | ||
|
|
84b7509f33 | ||
|
|
a53baec9dc | ||
|
|
4b4bc86cf7 | ||
|
|
4d3860089e | ||
|
|
758f55f13c | ||
|
|
1e191c3adc | ||
|
|
1ba2cf7c9d | ||
|
|
9ed1cc00d5 | ||
|
|
3be1173197 | ||
|
|
f6e69c62b1 | ||
|
|
6d9679a7fc | ||
|
|
6ea260a81f | ||
|
|
26da600761 | ||
|
|
33172a7aee | ||
|
|
7eb9f6ac95 | ||
|
|
fc06c285d5 | ||
|
|
ca2e4fec79 | ||
|
|
87ca90f6cc | ||
|
|
7dfea78c87 | ||
|
|
d7808009dc | ||
|
|
62afb7a130 | ||
|
|
87bef9cb9c | ||
|
|
3860cb21c6 | ||
|
|
bf4ad7886c | ||
|
|
1d51c207f4 | ||
|
|
2eb3f70e0c | ||
|
|
eb4d883194 | ||
|
|
3f5c9ff9de | ||
|
|
47039796de | ||
|
|
fd054abcca | ||
|
|
2861bfbd47 | ||
|
|
6ea3127f9c | ||
|
|
f7acb5e115 | ||
|
|
b1ad1f7699 | ||
|
|
ab713df3c0 | ||
|
|
e0d44f2f1c | ||
|
|
61463bc05f | ||
|
|
a219fc3527 | ||
|
|
1cd4028ce8 | ||
|
|
de9a30eb93 | ||
|
|
2210561af3 | ||
|
|
c5ddc474c4 | ||
|
|
688748da36 | ||
|
|
753d311593 | ||
|
|
5bae3d9931 | ||
|
|
a3495a8218 | ||
|
|
5fa68f77a2 | ||
|
|
dbba2e9791 | ||
|
|
6207f26a68 | ||
|
|
7fcd39822e | ||
|
|
d20f8a604f | ||
|
|
a742646127 | ||
|
|
f5078d5ef2 | ||
|
|
3784084abc | ||
|
|
2f463b7735 | ||
|
|
7be5625d66 | ||
|
|
aef14a9cd2 | ||
|
|
67648a04d3 | ||
|
|
58345e3194 | ||
|
|
4cb2ad9a5a | ||
|
|
27395d8e22 | ||
|
|
230c5ea180 | ||
|
|
4d4370ddce |
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
github:
|
||||||
|
- d4rken
|
||||||
custom:
|
custom:
|
||||||
- "https://www.buymeacoffee.com/tydarken"
|
- "https://www.buymeacoffee.com/tydarken"
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ jobs:
|
|||||||
tag_name: ${{ steps.tagger.outputs.tag }}
|
tag_name: ${{ steps.tagger.outputs.tag }}
|
||||||
name: ${{ steps.tagger.outputs.tag }}
|
name: ${{ steps.tagger.outputs.tag }}
|
||||||
generate_release_notes: true
|
generate_release_notes: true
|
||||||
files: app/build/outputs/apk/beta/*.apk
|
files: |
|
||||||
|
app/build/outputs/apk/foss/beta/*.apk
|
||||||
|
app-wear/build/outputs/apk/foss/beta/*.apk
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
@@ -80,7 +82,9 @@ jobs:
|
|||||||
tag_name: ${{ steps.tagger.outputs.tag }}
|
tag_name: ${{ steps.tagger.outputs.tag }}
|
||||||
name: ${{ steps.tagger.outputs.tag }}
|
name: ${{ steps.tagger.outputs.tag }}
|
||||||
generate_release_notes: true
|
generate_release_notes: true
|
||||||
files: app/build/outputs/apk/release/*.apk
|
files: |
|
||||||
|
app/build/outputs/apk/foss/release/*.apk
|
||||||
|
app-wear/build/outputs/apk/foss/release/*.apk
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -1,9 +1,6 @@
|
|||||||
.idea
|
|
||||||
.gradle
|
|
||||||
build/
|
|
||||||
/fastlane/report.xml
|
|
||||||
*.iml
|
*.iml
|
||||||
local.properties
|
.gradle
|
||||||
|
/local.properties
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/build
|
/build
|
||||||
/captures
|
/captures
|
||||||
@@ -14,3 +11,4 @@ local.properties
|
|||||||
!/.idea/codeStyles/**/*
|
!/.idea/codeStyles/**/*
|
||||||
*.jks
|
*.jks
|
||||||
.local/*
|
.local/*
|
||||||
|
/fastlane/report.xml
|
||||||
|
|||||||
Generated
+167
@@ -0,0 +1,167 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<option name="RIGHT_MARGIN" value="120" />
|
||||||
|
<JSON>
|
||||||
|
<option name="OBJECT_WRAPPING" value="1" />
|
||||||
|
<option name="ARRAY_WRAPPING" value="1" />
|
||||||
|
</JSON>
|
||||||
|
<JavaCodeStyleSettings>
|
||||||
|
<option name="DO_NOT_WRAP_AFTER_SINGLE_ANNOTATION" value="true" />
|
||||||
|
<option name="IMPORT_LAYOUT_TABLE">
|
||||||
|
<value>
|
||||||
|
<package name="android" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="com" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="junit" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="net" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="org" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="java" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="javax" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="" withSubpackages="true" static="true" />
|
||||||
|
<emptyLine />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</JavaCodeStyleSettings>
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</JetCodeStyleSettings>
|
||||||
|
<codeStyleSettings language="JAVA">
|
||||||
|
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
|
||||||
|
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
|
||||||
|
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
|
||||||
|
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
|
||||||
|
<option name="FIELD_ANNOTATION_WRAP" value="1" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="JSON">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="USE_TAB_CHARACTER" value="true" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="XML">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
</indentOptions>
|
||||||
|
<arrangement>
|
||||||
|
<rules>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:android</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:id</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>style</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
</rules>
|
||||||
|
</arrangement>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="kotlin">
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
<option name="METHOD_ANNOTATION_WRAP" value="1" />
|
||||||
|
<option name="CLASS_ANNOTATION_WRAP" value="1" />
|
||||||
|
<option name="FIELD_ANNOTATION_WRAP" value="1" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
||||||
Generated
+5
@@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
+37
-37
@@ -8,20 +8,20 @@ GEM
|
|||||||
artifactory (3.0.15)
|
artifactory (3.0.15)
|
||||||
atomos (0.1.3)
|
atomos (0.1.3)
|
||||||
aws-eventstream (1.2.0)
|
aws-eventstream (1.2.0)
|
||||||
aws-partitions (1.554.0)
|
aws-partitions (1.610.0)
|
||||||
aws-sdk-core (3.126.0)
|
aws-sdk-core (3.131.3)
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
aws-partitions (~> 1, >= 1.525.0)
|
aws-partitions (~> 1, >= 1.525.0)
|
||||||
aws-sigv4 (~> 1.1)
|
aws-sigv4 (~> 1.1)
|
||||||
jmespath (~> 1.0)
|
jmespath (~> 1, >= 1.6.1)
|
||||||
aws-sdk-kms (1.54.0)
|
aws-sdk-kms (1.58.0)
|
||||||
aws-sdk-core (~> 3, >= 3.126.0)
|
aws-sdk-core (~> 3, >= 3.127.0)
|
||||||
aws-sigv4 (~> 1.1)
|
aws-sigv4 (~> 1.1)
|
||||||
aws-sdk-s3 (1.112.0)
|
aws-sdk-s3 (1.114.0)
|
||||||
aws-sdk-core (~> 3, >= 3.126.0)
|
aws-sdk-core (~> 3, >= 3.127.0)
|
||||||
aws-sdk-kms (~> 1)
|
aws-sdk-kms (~> 1)
|
||||||
aws-sigv4 (~> 1.4)
|
aws-sigv4 (~> 1.4)
|
||||||
aws-sigv4 (1.4.0)
|
aws-sigv4 (1.5.1)
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
babosa (1.0.4)
|
babosa (1.0.4)
|
||||||
claide (1.1.0)
|
claide (1.1.0)
|
||||||
@@ -36,8 +36,8 @@ GEM
|
|||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
dotenv (2.7.6)
|
dotenv (2.7.6)
|
||||||
emoji_regex (3.2.3)
|
emoji_regex (3.2.3)
|
||||||
excon (0.91.0)
|
excon (0.92.4)
|
||||||
faraday (1.9.3)
|
faraday (1.10.0)
|
||||||
faraday-em_http (~> 1.0)
|
faraday-em_http (~> 1.0)
|
||||||
faraday-em_synchrony (~> 1.0)
|
faraday-em_synchrony (~> 1.0)
|
||||||
faraday-excon (~> 1.1)
|
faraday-excon (~> 1.1)
|
||||||
@@ -56,8 +56,8 @@ GEM
|
|||||||
faraday-em_synchrony (1.0.0)
|
faraday-em_synchrony (1.0.0)
|
||||||
faraday-excon (1.1.0)
|
faraday-excon (1.1.0)
|
||||||
faraday-httpclient (1.0.1)
|
faraday-httpclient (1.0.1)
|
||||||
faraday-multipart (1.0.3)
|
faraday-multipart (1.0.4)
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (~> 2)
|
||||||
faraday-net_http (1.0.1)
|
faraday-net_http (1.0.1)
|
||||||
faraday-net_http_persistent (1.2.0)
|
faraday-net_http_persistent (1.2.0)
|
||||||
faraday-patron (1.0.0)
|
faraday-patron (1.0.0)
|
||||||
@@ -66,7 +66,7 @@ GEM
|
|||||||
faraday_middleware (1.2.0)
|
faraday_middleware (1.2.0)
|
||||||
faraday (~> 1.0)
|
faraday (~> 1.0)
|
||||||
fastimage (2.2.6)
|
fastimage (2.2.6)
|
||||||
fastlane (2.204.3)
|
fastlane (2.208.0)
|
||||||
CFPropertyList (>= 2.3, < 4.0.0)
|
CFPropertyList (>= 2.3, < 4.0.0)
|
||||||
addressable (>= 2.8, < 3.0.0)
|
addressable (>= 2.8, < 3.0.0)
|
||||||
artifactory (~> 3.0)
|
artifactory (~> 3.0)
|
||||||
@@ -106,9 +106,9 @@ GEM
|
|||||||
xcpretty (~> 0.3.0)
|
xcpretty (~> 0.3.0)
|
||||||
xcpretty-travis-formatter (>= 0.0.3)
|
xcpretty-travis-formatter (>= 0.0.3)
|
||||||
gh_inspector (1.1.3)
|
gh_inspector (1.1.3)
|
||||||
google-apis-androidpublisher_v3 (0.16.0)
|
google-apis-androidpublisher_v3 (0.25.0)
|
||||||
google-apis-core (>= 0.4, < 2.a)
|
google-apis-core (>= 0.7, < 2.a)
|
||||||
google-apis-core (0.4.2)
|
google-apis-core (0.7.0)
|
||||||
addressable (~> 2.5, >= 2.5.1)
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
googleauth (>= 0.16.2, < 2.a)
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
httpclient (>= 2.8.1, < 3.a)
|
httpclient (>= 2.8.1, < 3.a)
|
||||||
@@ -117,19 +117,19 @@ GEM
|
|||||||
retriable (>= 2.0, < 4.a)
|
retriable (>= 2.0, < 4.a)
|
||||||
rexml
|
rexml
|
||||||
webrick
|
webrick
|
||||||
google-apis-iamcredentials_v1 (0.10.0)
|
google-apis-iamcredentials_v1 (0.13.0)
|
||||||
google-apis-core (>= 0.4, < 2.a)
|
google-apis-core (>= 0.7, < 2.a)
|
||||||
google-apis-playcustomapp_v1 (0.7.0)
|
google-apis-playcustomapp_v1 (0.10.0)
|
||||||
google-apis-core (>= 0.4, < 2.a)
|
google-apis-core (>= 0.7, < 2.a)
|
||||||
google-apis-storage_v1 (0.11.0)
|
google-apis-storage_v1 (0.18.0)
|
||||||
google-apis-core (>= 0.4, < 2.a)
|
google-apis-core (>= 0.7, < 2.a)
|
||||||
google-cloud-core (1.6.0)
|
google-cloud-core (1.6.0)
|
||||||
google-cloud-env (~> 1.0)
|
google-cloud-env (~> 1.0)
|
||||||
google-cloud-errors (~> 1.0)
|
google-cloud-errors (~> 1.0)
|
||||||
google-cloud-env (1.5.0)
|
google-cloud-env (1.6.0)
|
||||||
faraday (>= 0.17.3, < 2.0)
|
faraday (>= 0.17.3, < 3.0)
|
||||||
google-cloud-errors (1.2.0)
|
google-cloud-errors (1.2.0)
|
||||||
google-cloud-storage (1.36.1)
|
google-cloud-storage (1.37.0)
|
||||||
addressable (~> 2.8)
|
addressable (~> 2.8)
|
||||||
digest-crc (~> 0.4)
|
digest-crc (~> 0.4)
|
||||||
google-apis-iamcredentials_v1 (~> 0.1)
|
google-apis-iamcredentials_v1 (~> 0.1)
|
||||||
@@ -137,20 +137,20 @@ GEM
|
|||||||
google-cloud-core (~> 1.6)
|
google-cloud-core (~> 1.6)
|
||||||
googleauth (>= 0.16.2, < 2.a)
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
mini_mime (~> 1.0)
|
mini_mime (~> 1.0)
|
||||||
googleauth (1.1.0)
|
googleauth (1.2.0)
|
||||||
faraday (>= 0.17.3, < 2.0)
|
faraday (>= 0.17.3, < 3.a)
|
||||||
jwt (>= 1.4, < 3.0)
|
jwt (>= 1.4, < 3.0)
|
||||||
memoist (~> 0.16)
|
memoist (~> 0.16)
|
||||||
multi_json (~> 1.11)
|
multi_json (~> 1.11)
|
||||||
os (>= 0.9, < 2.0)
|
os (>= 0.9, < 2.0)
|
||||||
signet (>= 0.16, < 2.a)
|
signet (>= 0.16, < 2.a)
|
||||||
highline (2.0.3)
|
highline (2.0.3)
|
||||||
http-cookie (1.0.4)
|
http-cookie (1.0.5)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
jmespath (1.5.0)
|
jmespath (1.6.1)
|
||||||
json (2.6.1)
|
json (2.6.2)
|
||||||
jwt (2.3.0)
|
jwt (2.4.1)
|
||||||
memoist (0.16.2)
|
memoist (0.16.2)
|
||||||
mini_magick (4.11.0)
|
mini_magick (4.11.0)
|
||||||
mini_mime (1.1.2)
|
mini_mime (1.1.2)
|
||||||
@@ -161,9 +161,9 @@ GEM
|
|||||||
optparse (0.1.1)
|
optparse (0.1.1)
|
||||||
os (1.1.4)
|
os (1.1.4)
|
||||||
plist (3.6.0)
|
plist (3.6.0)
|
||||||
public_suffix (4.0.6)
|
public_suffix (4.0.7)
|
||||||
rake (13.0.6)
|
rake (13.0.6)
|
||||||
representable (3.1.1)
|
representable (3.2.0)
|
||||||
declarative (< 0.1.0)
|
declarative (< 0.1.0)
|
||||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||||
uber (< 0.2.0)
|
uber (< 0.2.0)
|
||||||
@@ -173,9 +173,9 @@ GEM
|
|||||||
ruby2_keywords (0.0.5)
|
ruby2_keywords (0.0.5)
|
||||||
rubyzip (2.3.2)
|
rubyzip (2.3.2)
|
||||||
security (0.1.3)
|
security (0.1.3)
|
||||||
signet (0.16.0)
|
signet (0.17.0)
|
||||||
addressable (~> 2.8)
|
addressable (~> 2.8)
|
||||||
faraday (>= 0.17.3, < 2.0)
|
faraday (>= 0.17.5, < 3.a)
|
||||||
jwt (>= 1.5, < 3.0)
|
jwt (>= 1.5, < 3.0)
|
||||||
multi_json (~> 1.10)
|
multi_json (~> 1.10)
|
||||||
simctl (1.6.8)
|
simctl (1.6.8)
|
||||||
@@ -192,11 +192,11 @@ GEM
|
|||||||
uber (0.1.0)
|
uber (0.1.0)
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.8)
|
unf_ext (0.0.8.2)
|
||||||
unicode-display_width (1.8.0)
|
unicode-display_width (1.8.0)
|
||||||
webrick (1.7.0)
|
webrick (1.7.0)
|
||||||
word_wrap (1.0.0)
|
word_wrap (1.0.0)
|
||||||
xcodeproj (1.21.0)
|
xcodeproj (1.22.0)
|
||||||
CFPropertyList (>= 2.3.3, < 4.0)
|
CFPropertyList (>= 2.3.3, < 4.0)
|
||||||
atomos (~> 0.1.3)
|
atomos (~> 0.1.3)
|
||||||
claide (>= 1.0.2, < 2.0)
|
claide (>= 1.0.2, < 2.0)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Companion App for AirPods (CAPod)
|
# Companion App for AirPods (CAPod)
|
||||||
[](https://github.com/d4rken-org/capod/releases/latest)
|
[](https://github.com/d4rken-org/capod/releases/latest)
|
||||||
[](https://github.com/d4rken/capod/actions/workflows/code-checks.yml)
|
[](https://github.com/d4rken/capod/actions/workflows/code-checks.yml)
|
||||||
[](https://crowdin.com/project/capod)
|
[](https://crowdin.com/project/capod)
|
||||||
[](https://github.com/d4rken-org/capod/releases/latest)
|
[](https://github.com/d4rken-org/capod/releases/latest)
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@ A companion app that adds support for AirPod specific features to Android:
|
|||||||
* Ear detection with automatic play/pause.
|
* Ear detection with automatic play/pause.
|
||||||
* Automatically connect phone & AirPods.
|
* Automatically connect phone & AirPods.
|
||||||
* Show popup when case is opened.
|
* Show popup when case is opened.
|
||||||
|
* Support for Wear OS
|
||||||
|
|
||||||
CAPod is ad-free. Some additional features require an in-app purchase.
|
CAPod is ad-free. Some additional features require an in-app purchase.
|
||||||
|
|
||||||
@@ -23,7 +24,8 @@ Currently supported models:
|
|||||||
* AirPods 1. Generation
|
* AirPods 1. Generation
|
||||||
* AirPods 2. Generation
|
* AirPods 2. Generation
|
||||||
* AirPods 3. Generation
|
* AirPods 3. Generation
|
||||||
* AirPods Pro
|
* AirPods Pro 1. Generation
|
||||||
|
* AirPods Pro 2. Generation
|
||||||
* AirPods Max
|
* AirPods Max
|
||||||
* Power Beats Pro
|
* Power Beats Pro
|
||||||
* Power Beats 3
|
* Power Beats 3
|
||||||
@@ -36,22 +38,23 @@ Currently supported models:
|
|||||||
|
|
||||||
* [Google Play](https://play.google.com/store/apps/details?id=eu.darken.capod)
|
* [Google Play](https://play.google.com/store/apps/details?id=eu.darken.capod)
|
||||||
* [GitHub](https://github.com/d4rken-org/capod/releases/latest)
|
* [GitHub](https://github.com/d4rken-org/capod/releases/latest)
|
||||||
|
* [IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/eu.darken.capod)
|
||||||
|
|
||||||
## Support the project
|
## Support the project
|
||||||
|
|
||||||
* Buy the CAPod Pro In-App purchase on [Google Play](https://play.google.com/store/apps/details?id=eu.darken.capod)
|
* Buy the CAPod Pro In-App purchase on [Google Play](https://play.google.com/store/apps/details?id=eu.darken.capod)
|
||||||
|
* [Sponsor development](https://github.com/sponsors/d4rken) on GitHub
|
||||||
* Help translate CAPod [on Crowdin](https://crowdin.com/project/capod)
|
* Help translate CAPod [on Crowdin](https://crowdin.com/project/capod)
|
||||||
|
|
||||||
## Get help
|
## Get help
|
||||||
|
|
||||||
* [Github Issues](https://github.com/d4rken-org/capod/issues)
|
* [Github Issues](https://github.com/d4rken-org/capod/issues)
|
||||||
* [Discord](https://discord.gg/vHubYPp)
|
* [Discord](https://discord.gg/vHubYPp)
|
||||||
* [Email](mailto:support@darken.eu)
|
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
<img src="https://github.com/d4rken-org/capod/raw/main/.assets/screenshots/1.png" width="200"><img src="https://github.com/d4rken-org/capod/raw/main/.assets/screenshots/2.png" width="200"><img src="https://github.com/d4rken-org/capod/raw/main/.assets/screenshots/3.png" width="200"><img src="https://github.com/d4rken-org/capod/raw/main/.assets/screenshots/4.png" width="200">
|
<img src="https://github.com/d4rken-org/capod/raw/main/.assets/screenshots/1.png" width="200"><img src="https://github.com/d4rken-org/capod/raw/main/.assets/screenshots/2.png" width="200"><img src="https://github.com/d4rken-org/capod/raw/main/.assets/screenshots/3.png" width="200"><img src="https://github.com/d4rken-org/capod/raw/main/.assets/screenshots/4.png" width="200">
|
||||||
|
<img src="https://raw.githubusercontent.com/d4rken-org/capod/main/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png" width="200">
|
||||||
## Thanks to
|
## Thanks to
|
||||||
|
|
||||||
* The [OpenPods](https://github.com/adolfintel/OpenPods) project,
|
* The [OpenPods](https://github.com/adolfintel/OpenPods) project,
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
plugins {
|
||||||
|
id("com.android.library")
|
||||||
|
id("kotlin-android")
|
||||||
|
id("kotlin-kapt")
|
||||||
|
id("kotlin-parcelize")
|
||||||
|
}
|
||||||
|
apply(plugin = "dagger.hilt.android.plugin")
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdk = ProjectConfig.compileSdk
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = ProjectConfig.minSdk
|
||||||
|
targetSdk = ProjectConfig.targetSdk
|
||||||
|
|
||||||
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
consumerProguardFiles("consumer-rules.pro")
|
||||||
|
|
||||||
|
buildConfigField("Long", "VERSION_CODE", "${ProjectConfig.Version.code}L")
|
||||||
|
buildConfigField("String", "VERSION_NAME", "\"${ProjectConfig.Version.name}\"")
|
||||||
|
buildConfigField("String", "APPLICATION_ID", "\"${ProjectConfig.packageName}\"")
|
||||||
|
buildConfigField("String", "GITSHA", "\"${lastCommitHash()}\"")
|
||||||
|
buildConfigField("String", "BUILDTIME", "\"${buildTime()}\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
viewBinding = true
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
isCoreLibraryDesugaringEnabled = true
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
freeCompilerArgs = freeCompilerArgs + listOf(
|
||||||
|
"-opt-in=kotlin.ExperimentalStdlibApi",
|
||||||
|
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||||
|
"-opt-in=kotlin.time.ExperimentalTime",
|
||||||
|
"-opt-in=kotlin.ExperimentalUnsignedTypes",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
flavorDimensions.add("version")
|
||||||
|
productFlavors {
|
||||||
|
create("foss") {
|
||||||
|
dimension = "version"
|
||||||
|
}
|
||||||
|
create("gplay") {
|
||||||
|
dimension = "version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
val customProguardRules = fileTree(File("../proguard")) {
|
||||||
|
include("*.pro")
|
||||||
|
}
|
||||||
|
debug {
|
||||||
|
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
|
||||||
|
proguardFiles(*customProguardRules.toList().toTypedArray())
|
||||||
|
proguardFiles("proguard-rules-debug.pro")
|
||||||
|
}
|
||||||
|
create("beta") {
|
||||||
|
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
|
||||||
|
proguardFiles(*customProguardRules.toList().toTypedArray())
|
||||||
|
}
|
||||||
|
release {
|
||||||
|
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
|
||||||
|
proguardFiles(*customProguardRules.toList().toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testOptions {
|
||||||
|
unitTests {
|
||||||
|
isIncludeAndroidResources = true
|
||||||
|
}
|
||||||
|
tasks.withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
|
||||||
|
|
||||||
|
addBaseAndroid()
|
||||||
|
addBaseAndroidUi()
|
||||||
|
addBaseKotlin()
|
||||||
|
addDagger()
|
||||||
|
addMoshi()
|
||||||
|
addBaseWorkManager()
|
||||||
|
addNavigation()
|
||||||
|
|
||||||
|
addTesting()
|
||||||
|
|
||||||
|
implementation("com.bugsnag:bugsnag-android:5.9.2")
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+21
@@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="eu.darken.capod.common">
|
||||||
|
|
||||||
|
</manifest>
|
||||||
+3
-3
@@ -1,7 +1,5 @@
|
|||||||
package eu.darken.capod.common
|
package eu.darken.capod.common
|
||||||
|
|
||||||
import eu.darken.capod.BuildConfig
|
|
||||||
|
|
||||||
|
|
||||||
// Can't be const because that prevents them from being mocked in tests
|
// Can't be const because that prevents them from being mocked in tests
|
||||||
@Suppress("MayBeConstant")
|
@Suppress("MayBeConstant")
|
||||||
@@ -34,12 +32,14 @@ object BuildConfigWrap {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
val APPLICATION_ID = BuildConfig.APPLICATION_ID
|
val APPLICATION_ID: String = BuildConfig.APPLICATION_ID
|
||||||
|
|
||||||
val VERSION_CODE: Long = BuildConfig.VERSION_CODE.toLong()
|
val VERSION_CODE: Long = BuildConfig.VERSION_CODE.toLong()
|
||||||
val VERSION_NAME: String = BuildConfig.VERSION_NAME
|
val VERSION_NAME: String = BuildConfig.VERSION_NAME
|
||||||
val GIT_SHA: String = BuildConfig.GITSHA
|
val GIT_SHA: String = BuildConfig.GITSHA
|
||||||
|
val BUILDTIME: String = BuildConfig.BUILDTIME
|
||||||
|
|
||||||
val VERSION_DESCRIPTION_LONG: String = "v$VERSION_NAME ($VERSION_CODE) [$GIT_SHA] ${FLAVOR}_$BUILD_TYPE"
|
val VERSION_DESCRIPTION_LONG: String = "v$VERSION_NAME ($VERSION_CODE) [$GIT_SHA] ${FLAVOR}_$BUILD_TYPE"
|
||||||
val VERSION_DESCRIPTION_SHORT: String = "v$VERSION_NAME [$GIT_SHA] $FLAVOR"
|
val VERSION_DESCRIPTION_SHORT: String = "v$VERSION_NAME [$GIT_SHA] $FLAVOR"
|
||||||
|
val VERSION_DESCRIPTION_TINY: String = "v$VERSION_NAME"
|
||||||
}
|
}
|
||||||
+2
-2
@@ -13,6 +13,6 @@ object BuildWrap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasApiLevel(level: Int): Boolean = BuildWrap.VERSION.SDK_INT >= level
|
fun hasApiLevel(level: Int): Boolean = BuildWrap.VersionWrap.SDK_INT >= level
|
||||||
|
|
||||||
fun withinApiLevel(start: Int, end: Int): Boolean = BuildWrap.VERSION.SDK_INT in start..end
|
fun withinApiLevel(start: Int, end: Int): Boolean = BuildWrap.VersionWrap.SDK_INT in start..end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package eu.darken.capod.common
|
||||||
|
|
||||||
|
object PrivacyPolicy {
|
||||||
|
const val URL = "https://github.com/d4rken-org/capod/blob/main/PRIVACY_POLICY.md"
|
||||||
|
}
|
||||||
+10
-4
@@ -3,14 +3,19 @@ package eu.darken.capod.common.bluetooth
|
|||||||
import android.bluetooth.le.ScanResult
|
import android.bluetooth.le.ScanResult
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.core.util.forEach
|
import androidx.core.util.forEach
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
data class BleScanResult(
|
data class BleScanResult(
|
||||||
val address: String,
|
@Json(name = "receivedAt") val receivedAt: Instant,
|
||||||
val rssi: Int,
|
@Json(name = "address") val address: String,
|
||||||
val generatedAtNanos: Long,
|
@Json(name = "rssi") val rssi: Int,
|
||||||
val manufacturerSpecificData: Map<Int, ByteArray>
|
@Json(name = "generatedAtNanos") val generatedAtNanos: Long,
|
||||||
|
@Json(name = "manufacturerSpecificData") val manufacturerSpecificData: Map<Int, ByteArray>
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
fun getManufacturerSpecificData(id: Int): ByteArray? = manufacturerSpecificData[id]
|
fun getManufacturerSpecificData(id: Int): ByteArray? = manufacturerSpecificData[id]
|
||||||
@@ -25,6 +30,7 @@ data class BleScanResult(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromScanResult(scanResult: ScanResult) = BleScanResult(
|
fun fromScanResult(scanResult: ScanResult) = BleScanResult(
|
||||||
|
receivedAt = Instant.now(),
|
||||||
address = scanResult.device.address,
|
address = scanResult.device.address,
|
||||||
rssi = scanResult.rssi,
|
rssi = scanResult.rssi,
|
||||||
generatedAtNanos = scanResult.timestampNanos,
|
generatedAtNanos = scanResult.timestampNanos,
|
||||||
+2
-3
@@ -10,7 +10,6 @@ import dagger.hilt.android.qualifiers.ApplicationContext
|
|||||||
import eu.darken.capod.common.debug.logging.Logging.Priority.*
|
import eu.darken.capod.common.debug.logging.Logging.Priority.*
|
||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.main.core.ScannerMode
|
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@@ -36,7 +35,7 @@ class BleScanner @Inject constructor(
|
|||||||
log(TAG, VERBOSE) { "scan(filters=$filters, scannerMode=$scannerMode, compatMode=$compatMode)" }
|
log(TAG, VERBOSE) { "scan(filters=$filters, scannerMode=$scannerMode, compatMode=$compatMode)" }
|
||||||
if (compatMode) log(TAG, WARN) { "Using compatibilityMode!" }
|
if (compatMode) log(TAG, WARN) { "Using compatibilityMode!" }
|
||||||
|
|
||||||
val adapter = bluetoothManager.adapter
|
val adapter = bluetoothManager.adapter ?: throw IllegalStateException("Bluetooth adapter unavailable")
|
||||||
|
|
||||||
val supportsOffloadFiltering = adapter.isOffloadedFilteringSupported.also {
|
val supportsOffloadFiltering = adapter.isOffloadedFilteringSupported.also {
|
||||||
log(TAG, if (it) DEBUG else WARN) { "isOffloadedFilteringSupported=$it" }
|
log(TAG, if (it) DEBUG else WARN) { "isOffloadedFilteringSupported=$it" }
|
||||||
@@ -46,7 +45,7 @@ class BleScanner @Inject constructor(
|
|||||||
log(TAG, if (it) DEBUG else WARN) { "isOffloadedScanBatchingSupported=$it" }
|
log(TAG, if (it) DEBUG else WARN) { "isOffloadedScanBatchingSupported=$it" }
|
||||||
} && !compatMode
|
} && !compatMode
|
||||||
|
|
||||||
val scanner = bluetoothManager.scanner
|
val scanner = bluetoothManager.scanner ?: throw IllegalStateException("BLE scanner unavailable")
|
||||||
|
|
||||||
val callback = object : ScanCallback() {
|
val callback = object : ScanCallback() {
|
||||||
var lastScanAt = System.currentTimeMillis()
|
var lastScanAt = System.currentTimeMillis()
|
||||||
+6
-6
@@ -20,7 +20,6 @@ import kotlinx.coroutines.channels.awaitClose
|
|||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@@ -31,12 +30,11 @@ class BluetoothManager2 @Inject constructor(
|
|||||||
private val dispatcherProvider: DispatcherProvider,
|
private val dispatcherProvider: DispatcherProvider,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val adapter: BluetoothAdapter
|
val adapter: BluetoothAdapter?
|
||||||
get() = manager.adapter
|
get() = manager.adapter
|
||||||
|
|
||||||
val scanner: BluetoothLeScanner
|
val scanner: BluetoothLeScanner?
|
||||||
get() = adapter.bluetoothLeScanner
|
get() = adapter?.bluetoothLeScanner
|
||||||
?: throw IllegalStateException("Bluetooth is disabled or permissiong missing")
|
|
||||||
|
|
||||||
val isBluetoothEnabled: Flow<Boolean> = callbackFlow {
|
val isBluetoothEnabled: Flow<Boolean> = callbackFlow {
|
||||||
send(manager.adapter?.isEnabled ?: false)
|
send(manager.adapter?.isEnabled ?: false)
|
||||||
@@ -159,7 +157,9 @@ class BluetoothManager2 @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bondedDevices(): Set<BluetoothDevice> = adapter.bondedDevices
|
fun bondedDevices(): Flow<Set<BluetoothDevice>> = flow {
|
||||||
|
emit(adapter?.bondedDevices ?: throw IllegalStateException("Bluetooth adapter unavailable"))
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun nudgeConnection(device: BluetoothDevice): Boolean = getBluetoothProfile().map { bluetoothProfile ->
|
suspend fun nudgeConnection(device: BluetoothDevice): Boolean = getBluetoothProfile().map { bluetoothProfile ->
|
||||||
try {
|
try {
|
||||||
+8
@@ -3,6 +3,7 @@ package eu.darken.capod.common.bluetooth
|
|||||||
import dagger.Reusable
|
import dagger.Reusable
|
||||||
import eu.darken.capod.common.SystemClockWrap
|
import eu.darken.capod.common.SystemClockWrap
|
||||||
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
||||||
|
import java.time.Instant
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ class FakeBleData @Inject constructor(
|
|||||||
val fakeDevices = mutableListOf<BleScanResult>()
|
val fakeDevices = mutableListOf<BleScanResult>()
|
||||||
// AirPods Gen1
|
// AirPods Gen1
|
||||||
BleScanResult(
|
BleScanResult(
|
||||||
|
receivedAt = Instant.now(),
|
||||||
address = "78:73:AF:B4:85:22",
|
address = "78:73:AF:B4:85:22",
|
||||||
rssi = Random.nextInt(100) * -1,
|
rssi = Random.nextInt(100) * -1,
|
||||||
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 100,
|
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 100,
|
||||||
@@ -32,6 +34,7 @@ class FakeBleData @Inject constructor(
|
|||||||
|
|
||||||
// AirPods Gen2
|
// AirPods Gen2
|
||||||
BleScanResult(
|
BleScanResult(
|
||||||
|
receivedAt = Instant.now(),
|
||||||
address = "78:73:FF:B4:85:5E",
|
address = "78:73:FF:B4:85:5E",
|
||||||
rssi = Random.nextInt(100) * -1,
|
rssi = Random.nextInt(100) * -1,
|
||||||
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 100,
|
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 100,
|
||||||
@@ -44,6 +47,7 @@ class FakeBleData @Inject constructor(
|
|||||||
|
|
||||||
// AirPods Gen3
|
// AirPods Gen3
|
||||||
BleScanResult(
|
BleScanResult(
|
||||||
|
receivedAt = Instant.now(),
|
||||||
address = "4E:9E:D1:49:D2:6D",
|
address = "4E:9E:D1:49:D2:6D",
|
||||||
rssi = Random.nextInt(15, 75) * -1,
|
rssi = Random.nextInt(15, 75) * -1,
|
||||||
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 200,
|
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 200,
|
||||||
@@ -55,6 +59,7 @@ class FakeBleData @Inject constructor(
|
|||||||
}
|
}
|
||||||
// AirPods Max
|
// AirPods Max
|
||||||
BleScanResult(
|
BleScanResult(
|
||||||
|
receivedAt = Instant.now(),
|
||||||
address = "7E:E5:C7:65:D2:B5",
|
address = "7E:E5:C7:65:D2:B5",
|
||||||
rssi = Random.nextInt(15, 75) * -1,
|
rssi = Random.nextInt(15, 75) * -1,
|
||||||
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 300,
|
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 300,
|
||||||
@@ -66,6 +71,7 @@ class FakeBleData @Inject constructor(
|
|||||||
}
|
}
|
||||||
// BeatsFlex
|
// BeatsFlex
|
||||||
BleScanResult(
|
BleScanResult(
|
||||||
|
receivedAt = Instant.now(),
|
||||||
address = "5E:9E:D1:49:D2:6D",
|
address = "5E:9E:D1:49:D2:6D",
|
||||||
rssi = Random.nextInt(15, 75) * -1,
|
rssi = Random.nextInt(15, 75) * -1,
|
||||||
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 400,
|
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 400,
|
||||||
@@ -78,6 +84,7 @@ class FakeBleData @Inject constructor(
|
|||||||
|
|
||||||
// Tws i99999
|
// Tws i99999
|
||||||
BleScanResult(
|
BleScanResult(
|
||||||
|
receivedAt = Instant.now(),
|
||||||
address = "5E:9E:D1:29:D2:6D",
|
address = "5E:9E:D1:29:D2:6D",
|
||||||
rssi = Random.nextInt(15, 75) * -1,
|
rssi = Random.nextInt(15, 75) * -1,
|
||||||
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 400,
|
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 400,
|
||||||
@@ -90,6 +97,7 @@ class FakeBleData @Inject constructor(
|
|||||||
|
|
||||||
// Unknown Device
|
// Unknown Device
|
||||||
BleScanResult(
|
BleScanResult(
|
||||||
|
receivedAt = Instant.now(),
|
||||||
address = "6E:9E:D1:49:D2:6D",
|
address = "6E:9E:D1:49:D2:6D",
|
||||||
rssi = Random.nextInt(15, 75) * -1,
|
rssi = Random.nextInt(15, 75) * -1,
|
||||||
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 500,
|
generatedAtNanos = SystemClockWrap.elapsedRealtimeNanos + 500,
|
||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
package eu.darken.capod.main.core
|
package eu.darken.capod.common.bluetooth
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import eu.darken.capod.R
|
import eu.darken.capod.common.R
|
||||||
|
|
||||||
@JsonClass(generateAdapter = false)
|
@JsonClass(generateAdapter = false)
|
||||||
enum class ScannerMode(
|
enum class ScannerMode(
|
||||||
+3
-4
@@ -6,7 +6,6 @@ import android.content.pm.PackageManager
|
|||||||
import com.bugsnag.android.Event
|
import com.bugsnag.android.Event
|
||||||
import com.bugsnag.android.OnErrorCallback
|
import com.bugsnag.android.OnErrorCallback
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import eu.darken.capod.BuildConfig
|
|
||||||
import eu.darken.capod.common.BuildConfigWrap
|
import eu.darken.capod.common.BuildConfigWrap
|
||||||
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
||||||
import eu.darken.capod.common.debug.logging.Logging.Priority.WARN
|
import eu.darken.capod.common.debug.logging.Logging.Priority.WARN
|
||||||
@@ -26,13 +25,13 @@ class BugsnagErrorHandler @Inject constructor(
|
|||||||
bugsnagLogger.injectLog(event)
|
bugsnagLogger.injectLog(event)
|
||||||
|
|
||||||
TAB_APP.also { tab ->
|
TAB_APP.also { tab ->
|
||||||
event.addMetadata(tab, "gitSha", BuildConfig.GITSHA)
|
event.addMetadata(tab, "gitSha", BuildConfigWrap.GIT_SHA)
|
||||||
event.addMetadata(tab, "buildTime", BuildConfig.BUILDTIME)
|
event.addMetadata(tab, "buildTime", BuildConfigWrap.BUILDTIME)
|
||||||
|
|
||||||
context.tryFormattedSignature()?.let { event.addMetadata(tab, "signatures", it) }
|
context.tryFormattedSignature()?.let { event.addMetadata(tab, "signatures", it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
return debugSettings.isAutoReportingEnabled.value && !BuildConfigWrap.DEBUG
|
return debugSettings.isAutoReportingEnabled.value && !eu.darken.capod.common.BuildConfigWrap.DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package eu.darken.capod.common.error
|
package eu.darken.capod.common.error
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.darken.capod.R
|
import eu.darken.capod.common.R
|
||||||
|
|
||||||
interface HasLocalizedError {
|
interface HasLocalizedError {
|
||||||
fun getLocalizedError(context: Context): LocalizedError
|
fun getLocalizedError(context: Context): LocalizedError
|
||||||
+9
-3
@@ -25,7 +25,8 @@ class DynamicStateFlow<T>(
|
|||||||
loggingTag: String? = null,
|
loggingTag: String? = null,
|
||||||
parentScope: CoroutineScope,
|
parentScope: CoroutineScope,
|
||||||
coroutineContext: CoroutineContext = parentScope.coroutineContext,
|
coroutineContext: CoroutineContext = parentScope.coroutineContext,
|
||||||
private val startValueProvider: suspend CoroutineScope.() -> T
|
private val onRelease: CoroutineScope.(T) -> Unit = {},
|
||||||
|
private val startValueProvider: suspend CoroutineScope.() -> T,
|
||||||
) {
|
) {
|
||||||
private val lTag = loggingTag?.let { "$it:DSFlow" }
|
private val lTag = loggingTag?.let { "$it:DSFlow" }
|
||||||
|
|
||||||
@@ -47,6 +48,12 @@ class DynamicStateFlow<T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invokeOnClose {
|
||||||
|
lTag?.let { log(it, VERBOSE) { "invokeOnClose executing..." } }
|
||||||
|
onRelease(currentValue)
|
||||||
|
lTag?.let { log(it, VERBOSE) { "internal channelFlow finished." } }
|
||||||
|
}
|
||||||
|
|
||||||
updateActions.collect { update ->
|
updateActions.collect { update ->
|
||||||
currentValue = valueGuard.withLock {
|
currentValue = valueGuard.withLock {
|
||||||
try {
|
try {
|
||||||
@@ -68,12 +75,11 @@ class DynamicStateFlow<T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lTag?.let { log(it, VERBOSE) { "internal channelFlow finished." } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val internalFlow = producer
|
private val internalFlow = producer
|
||||||
.onStart { lTag?.let { log(it, VERBOSE) { "Internal onStart" } } }
|
.onStart { lTag?.let { log(it, VERBOSE) { "Internal onStart" } } }
|
||||||
|
// .onEach { value -> lTag?.let { log(it, VERBOSE) { "New value: $value" } } }
|
||||||
.onCompletion { err ->
|
.onCompletion { err ->
|
||||||
when {
|
when {
|
||||||
err is CancellationException -> {
|
err is CancellationException -> {
|
||||||
+9
-1
@@ -7,6 +7,7 @@ import eu.darken.capod.common.debug.logging.log
|
|||||||
import eu.darken.capod.common.error.hasCause
|
import eu.darken.capod.common.error.hasCause
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ fun <T : Any?> Flow<T>.replayingShare(scope: CoroutineScope) = this.shareIn(
|
|||||||
started = SharingStarted.WhileSubscribed(replayExpiration = Duration.ZERO)
|
started = SharingStarted.WhileSubscribed(replayExpiration = Duration.ZERO)
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun <T> Flow<T>.withPrevious(): Flow<Pair<T?, T>> = this
|
fun <T> Flow<T>.withPrevious(): Flow<Pair<T?, T>> = this
|
||||||
.scan(Pair<T?, T?>(null, null)) { previous, current -> Pair(previous.second, current) }
|
.scan(Pair<T?, T?>(null, null)) { previous, current -> Pair(previous.second, current) }
|
||||||
.drop(1)
|
.drop(1)
|
||||||
.map {
|
.map {
|
||||||
@@ -71,4 +72,11 @@ fun <T> Flow<T>.setupCommonEventHandlers(tag: String, identifier: () -> String)
|
|||||||
log(tag, ERROR) { "${identifier()} failed: ${it.asLog()}" }
|
log(tag, ERROR) { "${identifier()} failed: ${it.asLog()}" }
|
||||||
throw it
|
throw it
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Flow<T>.throttleLatest(delayMillis: Long): Flow<T> = this
|
||||||
|
.conflate()
|
||||||
|
.transform {
|
||||||
|
emit(it)
|
||||||
|
delay(delayMillis)
|
||||||
}
|
}
|
||||||
+8
-2
@@ -6,8 +6,8 @@ import android.os.Build
|
|||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import eu.darken.capod.R
|
|
||||||
import eu.darken.capod.common.BuildConfigWrap
|
import eu.darken.capod.common.BuildConfigWrap
|
||||||
|
import eu.darken.capod.common.R
|
||||||
import eu.darken.capod.common.withinApiLevel
|
import eu.darken.capod.common.withinApiLevel
|
||||||
|
|
||||||
enum class Permission(
|
enum class Permission(
|
||||||
@@ -71,7 +71,13 @@ enum class Permission(
|
|||||||
isGranted = {
|
isGranted = {
|
||||||
android.provider.Settings.canDrawOverlays(it)
|
android.provider.Settings.canDrawOverlays(it)
|
||||||
},
|
},
|
||||||
)
|
),
|
||||||
|
POST_NOTIFICATIONS(
|
||||||
|
minApiLevel = Build.VERSION_CODES.S,
|
||||||
|
labelRes = R.string.permission_post_notifications_label,
|
||||||
|
descriptionRes = R.string.permission_post_notifications_description,
|
||||||
|
permissionId = "android.permission.POST_NOTIFICATIONS",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Permission.isRequired(context: Context): Boolean = when {
|
fun Permission.isRequired(context: Context): Boolean = when {
|
||||||
+1
-1
@@ -2,7 +2,7 @@ package eu.darken.capod.common.preferences
|
|||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import eu.darken.capod.common.debug.logging.Logging.Priority.*
|
import eu.darken.capod.common.debug.logging.Logging.Priority.VERBOSE
|
||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
+1
-1
@@ -9,5 +9,5 @@ class JavaInstantAdapter {
|
|||||||
fun toJson(obj: Instant): Long = obj.toEpochMilli()
|
fun toJson(obj: Instant): Long = obj.toEpochMilli()
|
||||||
|
|
||||||
@FromJson
|
@FromJson
|
||||||
fun fromJson(epochMillis: Long): Instant = Instant.ofEpochSecond(epochMillis)
|
fun fromJson(epochMillis: Long): Instant = Instant.ofEpochMilli(epochMillis)
|
||||||
}
|
}
|
||||||
+2
@@ -9,6 +9,8 @@ interface UpgradeRepo {
|
|||||||
|
|
||||||
fun launchBillingFlow(activity: Activity)
|
fun launchBillingFlow(activity: Activity)
|
||||||
|
|
||||||
|
fun getSponsorUrl(): String? = null
|
||||||
|
|
||||||
interface Info {
|
interface Info {
|
||||||
val type: Type
|
val type: Type
|
||||||
|
|
||||||
+2
-1
@@ -8,7 +8,8 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.lifecycle.DefaultLifecycleObserver
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import eu.darken.capod.common.debug.logging.Logging.Priority.*
|
import eu.darken.capod.common.debug.logging.Logging.Priority.VERBOSE
|
||||||
|
import eu.darken.capod.common.debug.logging.Logging.Priority.WARN
|
||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
+1
@@ -5,6 +5,7 @@ import android.content.SharedPreferences
|
|||||||
import androidx.preference.PreferenceDataStore
|
import androidx.preference.PreferenceDataStore
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import eu.darken.capod.common.bluetooth.ScannerMode
|
||||||
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
import eu.darken.capod.common.debug.autoreport.DebugSettings
|
||||||
import eu.darken.capod.common.preferences.PreferenceStoreMapper
|
import eu.darken.capod.common.preferences.PreferenceStoreMapper
|
||||||
import eu.darken.capod.common.preferences.Settings
|
import eu.darken.capod.common.preferences.Settings
|
||||||
+1
-1
@@ -3,7 +3,7 @@ package eu.darken.capod.main.core
|
|||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import eu.darken.capod.R
|
import eu.darken.capod.common.R
|
||||||
|
|
||||||
@JsonClass(generateAdapter = false)
|
@JsonClass(generateAdapter = false)
|
||||||
enum class MonitorMode(
|
enum class MonitorMode(
|
||||||
+1
-1
@@ -6,7 +6,7 @@ import eu.darken.capod.common.debug.logging.log
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.common.permissions.Permission
|
import eu.darken.capod.common.permissions.Permission
|
||||||
import eu.darken.capod.common.permissions.isRequired
|
import eu.darken.capod.common.permissions.isRequired
|
||||||
import eu.darken.capod.reaction.settings.ReactionSettings
|
import eu.darken.capod.reaction.core.ReactionSettings
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user