Compare commits
509 Commits
feature/ca
...
feature/ca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1cb75d45f | ||
|
|
1675c8ab79 | ||
|
|
986b9731a1 | ||
|
|
dc66b27c8a | ||
|
|
3924c65e8c | ||
|
|
df7da2d7f6 | ||
|
|
697f95f3e3 | ||
|
|
f0d7da7194 | ||
|
|
b641e83470 | ||
|
|
f22f9c2dcc | ||
|
|
9ef2c278f6 | ||
|
|
4a7cb4f129 | ||
|
|
3a47e8eea3 | ||
|
|
4defd9c420 | ||
|
|
3bbff120f0 | ||
|
|
bf07e9f079 | ||
|
|
72fdff96c8 | ||
|
|
4e21b60087 | ||
|
|
7c786e55a5 | ||
|
|
51294bbb14 | ||
|
|
5dcda4f37a | ||
|
|
33d725acb4 | ||
|
|
fb78ac1243 | ||
|
|
ccfa614dc7 | ||
|
|
bc7f614573 | ||
|
|
7700288dbe | ||
|
|
e2c62aa76b | ||
|
|
35bf858a83 | ||
|
|
870bfaf08c | ||
|
|
c4238fb19b | ||
|
|
ba7aeb358b | ||
|
|
6f3fd4d454 | ||
|
|
97547f334f | ||
|
|
1ab953d819 | ||
|
|
161c19b628 | ||
|
|
307d483a56 | ||
|
|
9612248695 | ||
|
|
1f63401e5b | ||
|
|
d35ec18a88 | ||
|
|
b93b1847c3 | ||
|
|
cd46ed565f | ||
|
|
4a0e4edef8 | ||
|
|
2ea7333daa | ||
|
|
fa7a66809d | ||
|
|
71884ab760 | ||
|
|
f31205c670 | ||
|
|
0091ae87ce | ||
|
|
c196dc563f | ||
|
|
2baf51616c | ||
|
|
b75e2ce26f | ||
|
|
15976a991b | ||
|
|
16ee7371e7 | ||
|
|
02f0c794c7 | ||
|
|
ad13b1e927 | ||
|
|
a354ea80ab | ||
|
|
9f65b8112a | ||
|
|
6ac5d957fe | ||
|
|
4258c55b88 | ||
|
|
969f29e2e9 | ||
|
|
68921d0f0b | ||
|
|
c4ac4ee173 | ||
|
|
659b4e2fcd | ||
|
|
24e5bda8d3 | ||
|
|
02b1ad8d7a | ||
|
|
47eeb01b75 | ||
|
|
4288814138 | ||
|
|
ac4458e106 | ||
|
|
3d24b2de10 | ||
|
|
ed994b23e9 | ||
|
|
8c4678aba5 | ||
|
|
3d5fb2dfea | ||
|
|
ef6238b593 | ||
|
|
bc9bec3d66 | ||
|
|
d16e199dd1 | ||
|
|
a9c2df2e83 | ||
|
|
4673a4b9f7 | ||
|
|
d4a5286895 | ||
|
|
1b4579346b | ||
|
|
0665b8dd3b | ||
|
|
4f367d3e88 | ||
|
|
853124e2ce | ||
|
|
5dcd6e5a0d | ||
|
|
6f25c8be0f | ||
|
|
1db4b1319e | ||
|
|
76a97fcb47 | ||
|
|
4baaa39f35 | ||
|
|
52f025ae5a | ||
|
|
14b805e883 | ||
|
|
433a7b15fe | ||
|
|
6c8cbbc34a | ||
|
|
d4fbb298c1 | ||
|
|
9d78bb508a | ||
|
|
2aeb5f03d6 | ||
|
|
6522403c37 | ||
|
|
f090ca7f75 | ||
|
|
ac8b950893 | ||
|
|
2f02a238df | ||
|
|
22f9e941aa | ||
|
|
0d5fa97800 | ||
|
|
b102deaee1 | ||
|
|
3a73dbf304 | ||
|
|
faabc068ca | ||
|
|
443a69b10d | ||
|
|
6881651ce7 | ||
|
|
04aadf48f2 | ||
|
|
fc7ff07f40 | ||
|
|
968b2ee460 | ||
|
|
890340de94 | ||
|
|
c0589da549 | ||
|
|
4ca1a7b29e | ||
|
|
5432f2590c | ||
|
|
60ccf5cf0a | ||
|
|
bc717f5b10 | ||
|
|
3aead05ad4 | ||
|
|
9ef43cc6d3 | ||
|
|
24df7d49d5 | ||
|
|
486eef21dd | ||
|
|
44a4d02815 | ||
|
|
336a8194bd | ||
|
|
ac7c1c8497 | ||
|
|
d72f66b9bf | ||
|
|
1d445b8b27 | ||
|
|
14175a9140 | ||
|
|
7859f4cd05 | ||
|
|
37622ba9ce | ||
|
|
7a6af89375 | ||
|
|
056bfaacfe | ||
|
|
6684311ec5 | ||
|
|
11943571ad | ||
|
|
f696fcd412 | ||
|
|
2919e109ca | ||
|
|
995f478708 | ||
|
|
04fdea0296 | ||
|
|
b112c3a0b2 | ||
|
|
47149dd394 | ||
|
|
d1e0c1ebad | ||
|
|
2ef9d87250 | ||
|
|
fb8764bcd7 | ||
|
|
d7f73e02c5 | ||
|
|
e897b3af57 | ||
|
|
e04fd8a004 | ||
|
|
ada70ae1b5 | ||
|
|
5fdec0900e | ||
|
|
56a93288c4 | ||
|
|
02e3421f98 | ||
|
|
df7b53e10f | ||
|
|
fdbf331432 | ||
|
|
aed86ac6f0 | ||
|
|
3a13d4d6c0 | ||
|
|
f5336564d0 | ||
|
|
1ce49c68fe | ||
|
|
d37e880993 | ||
|
|
6fdb81a01f | ||
|
|
f9d6827572 | ||
|
|
10bf72b9ff | ||
|
|
800f929a15 | ||
|
|
bfcff1e19f | ||
|
|
f373e7df3e | ||
|
|
3985de5b14 | ||
|
|
4d75621384 | ||
|
|
e175a721d4 | ||
|
|
d9784ebc31 | ||
|
|
f241092277 | ||
|
|
0702703d78 | ||
|
|
2c4504bad3 | ||
|
|
07ca5a8b77 | ||
|
|
798a43906f | ||
|
|
41cb0f2e09 | ||
|
|
e12c0fb81f | ||
|
|
ac39f119e2 | ||
|
|
016faf3df0 | ||
|
|
b2d6879282 | ||
|
|
6926a212f4 | ||
|
|
addb6e06bf | ||
|
|
8ea752fbf7 | ||
|
|
89afc05d5c | ||
|
|
936f39161b | ||
|
|
ee20ee0722 | ||
|
|
02f9f8c8ea | ||
|
|
de3a252884 | ||
|
|
5e7a00de3e | ||
|
|
2858aeb55e | ||
|
|
357104efa9 | ||
|
|
bb8027c7ef | ||
|
|
f9dd787009 | ||
|
|
9478258caa | ||
|
|
9432bf9f38 | ||
|
|
c935a00763 | ||
|
|
404c4a3fdd | ||
|
|
4fa8f6deb5 | ||
|
|
f55b05012d | ||
|
|
ae81fee449 | ||
|
|
ec8dda4501 | ||
|
|
269b0b36b0 | ||
|
|
c8ed7c364b | ||
|
|
356833e248 | ||
|
|
1aa80270b4 | ||
|
|
1fccecdbf6 | ||
|
|
8be396e801 | ||
|
|
6755ff836e | ||
|
|
a3fc9710f7 | ||
|
|
e005731ba6 | ||
|
|
18ae3f4f61 | ||
|
|
10dfe0327e | ||
|
|
1d1e921137 | ||
|
|
0985a4c968 | ||
|
|
8df589c103 | ||
|
|
3ac9c09338 | ||
|
|
71b6b2f451 | ||
|
|
d85940ded8 | ||
|
|
e9e491c0b0 | ||
|
|
c73562fb75 | ||
|
|
3feacb59c8 | ||
|
|
a033d711c1 | ||
|
|
ba31afda27 | ||
|
|
3029c37755 | ||
|
|
728d55ffa0 | ||
|
|
265e9a9f56 | ||
|
|
7fbe205902 | ||
|
|
9b84333868 | ||
|
|
9525893bf7 | ||
|
|
daf15dcc62 | ||
|
|
b3e2b69b70 | ||
|
|
32081b71f5 | ||
|
|
7849c34d1f | ||
|
|
24977ec613 | ||
|
|
786bbab0d5 | ||
|
|
1facb07c28 | ||
|
|
bba5aba22d | ||
|
|
d7b85d6eba | ||
|
|
6832bfb95c | ||
|
|
4c379b67a3 | ||
|
|
3a2ae1ce71 | ||
|
|
c80afaf9c0 | ||
|
|
31d22bac47 | ||
|
|
b5f6687925 | ||
|
|
b3f25af923 | ||
|
|
78c141e946 | ||
|
|
83d36ce736 | ||
|
|
b928357ff1 | ||
|
|
c074bc57bc | ||
|
|
0e80c88b7d | ||
|
|
5ffa5b01fc | ||
|
|
61d9929485 | ||
|
|
231f19d113 | ||
|
|
bb41f62db5 | ||
|
|
47edc3180b | ||
|
|
9939d99c4b | ||
|
|
8053e8bb05 | ||
|
|
b7e9380bc4 | ||
|
|
83600087e1 | ||
|
|
b3dd5a2279 | ||
|
|
f9a8e10a85 | ||
|
|
d982331e21 | ||
|
|
68dfab9a44 | ||
|
|
c4f736a3fb | ||
|
|
b5abc86428 | ||
|
|
6b356c4dfd | ||
|
|
9e6723be41 | ||
|
|
fe84dc4823 | ||
|
|
08023a104c | ||
|
|
fd97cc6e87 | ||
|
|
78e5f0f011 | ||
|
|
73944675fa | ||
|
|
c6ded3d505 | ||
|
|
45b97de615 | ||
|
|
ec11a5e8e3 | ||
|
|
d71d17e5af | ||
|
|
e49e485ba3 | ||
|
|
2d4fc2166a | ||
|
|
84ba4ea999 | ||
|
|
c38eb545b1 | ||
|
|
b2d4a5aab0 | ||
|
|
201995849c | ||
|
|
1fc2f81dab | ||
|
|
69ddc95c2c | ||
|
|
a6ac68499c | ||
|
|
c10d7cfee4 | ||
|
|
f933bdbc53 | ||
|
|
274bca84d9 | ||
|
|
1e286dbc7a | ||
|
|
724d872491 | ||
|
|
64d5f9190a | ||
|
|
f1ab6833d3 | ||
|
|
140395f3cd | ||
|
|
f922e028a7 | ||
|
|
9aac0c007e | ||
|
|
e682cae7e7 | ||
|
|
f14977ba24 | ||
|
|
e8290e2f78 | ||
|
|
197110cfaf | ||
|
|
f320ac066c | ||
|
|
78acb5e7ea | ||
|
|
a14e864731 | ||
|
|
a87da87aad | ||
|
|
8befbb5a62 | ||
|
|
28893bc50b | ||
|
|
b73ef28f12 | ||
|
|
a71dc7f481 | ||
|
|
de4e7c1822 | ||
|
|
62090475f9 | ||
|
|
3c8715a7c4 | ||
|
|
4e188503a2 | ||
|
|
6fb7e97f13 | ||
|
|
80c9c591fc | ||
|
|
992fb5fefe | ||
|
|
f7c76f7503 | ||
|
|
e94364ecf6 | ||
|
|
1fab3d3743 | ||
|
|
35477055a9 | ||
|
|
e585f1df29 | ||
|
|
6311d18751 | ||
|
|
d29eef51ca | ||
|
|
c9692ef27b | ||
|
|
c36d3e9011 | ||
|
|
9409bbb9b2 | ||
|
|
3497747015 | ||
|
|
6343da1410 | ||
|
|
78a0c60600 | ||
|
|
ea152234a9 | ||
|
|
03612fcf64 | ||
|
|
a6a67512f4 | ||
|
|
dc9e977d40 | ||
|
|
5657df8db2 | ||
|
|
6abfe6ddd7 | ||
|
|
ab7489a049 | ||
|
|
a6fd6ae135 | ||
|
|
b30d4a025f | ||
|
|
5b747bfc74 | ||
|
|
a410d19114 | ||
|
|
a8589cc5b0 | ||
|
|
b057c9f7a8 | ||
|
|
96e4a4933c | ||
|
|
630064500d | ||
|
|
9543294996 | ||
|
|
56e9cc3406 | ||
|
|
be569cbe72 | ||
|
|
99f0817bdb | ||
|
|
220cd35d82 | ||
|
|
07f4ef1697 | ||
|
|
f20732ddc2 | ||
|
|
b1e0dc5843 | ||
|
|
285eb25706 | ||
|
|
ec556511e6 | ||
|
|
85c3d9f65f | ||
|
|
a7ebadf269 | ||
|
|
94c09d46c2 | ||
|
|
889fbc688d | ||
|
|
85d971242e | ||
|
|
23f82197c6 | ||
|
|
b4b16e2f37 | ||
|
|
2d838a8a23 | ||
|
|
7dab63cfe8 | ||
|
|
6548751bb0 | ||
|
|
65c158391f | ||
|
|
556fc4d31e | ||
|
|
c673f08aec | ||
|
|
818024d8dd | ||
|
|
cb3b893f72 | ||
|
|
f482b4bfe9 | ||
|
|
333c47339d | ||
|
|
a9283bfec8 | ||
|
|
f6f08d176c | ||
|
|
4c9f29e949 | ||
|
|
4ff5136652 | ||
|
|
56835b4f2d | ||
|
|
c43f734101 | ||
|
|
d4e1850d8c | ||
|
|
0b08072dfc | ||
|
|
66cdd63496 | ||
|
|
8b502b605c | ||
|
|
936a86acd7 | ||
|
|
64fc052c55 | ||
|
|
9897b8bfcd | ||
|
|
bcb50a9dd1 | ||
|
|
0b0775a86e | ||
|
|
73253f5f64 | ||
|
|
591b1cd9bf | ||
|
|
47a5d18ee0 | ||
|
|
b3f43804b0 | ||
|
|
139ec08d9d | ||
|
|
bc8846c351 | ||
|
|
85066f8ae6 | ||
|
|
1aec319e1c | ||
|
|
9848a94853 | ||
|
|
18ed3b44b4 | ||
|
|
a4043cc0e5 | ||
|
|
2b94d0c147 | ||
|
|
7e6395192b | ||
|
|
31db1cae7c | ||
|
|
f2c80a92c4 | ||
|
|
2cd107b400 | ||
|
|
eef4f42203 | ||
|
|
7eba69f574 | ||
|
|
cd226125cd | ||
|
|
1f543b4aa5 | ||
|
|
bd752824d9 | ||
|
|
a67dcbbf66 | ||
|
|
e0c77d3399 | ||
|
|
caf3ab5ce1 | ||
|
|
e549636645 | ||
|
|
3e2c3f40c7 | ||
|
|
40e20ead44 | ||
|
|
dfeba71abe | ||
|
|
2c0ec28803 | ||
|
|
2e1795dc6f | ||
|
|
74b06a4997 | ||
|
|
346610dd04 | ||
|
|
37cdc7116d | ||
|
|
d403f4ef01 | ||
|
|
cd1be782fa | ||
|
|
7f7eed1dec | ||
|
|
4843d574ca | ||
|
|
67059f3d71 | ||
|
|
0f0291074e | ||
|
|
4e143abfb9 | ||
|
|
558c5fba56 | ||
|
|
e50df3ea6d | ||
|
|
4383b11947 | ||
|
|
22209efc37 | ||
|
|
c3b5bb409b | ||
|
|
15f4d3326b | ||
|
|
a9ab9cb249 | ||
|
|
ac2e7cde41 | ||
|
|
e65404a466 | ||
|
|
3d47d1b4db | ||
|
|
d1749ab610 | ||
|
|
806c264686 | ||
|
|
34a9cb5a74 | ||
|
|
64fad2e871 | ||
|
|
961c69b525 | ||
|
|
c70f393559 | ||
|
|
9abdc174f4 | ||
|
|
2e5bfa1d9c | ||
|
|
9c89c26097 | ||
|
|
e3b6a5d389 | ||
|
|
0fb54efde5 | ||
|
|
a4a3f32dba | ||
|
|
03a1e29e0c | ||
|
|
eda9ff272b | ||
|
|
b3728e06ac | ||
|
|
33cbd85e19 | ||
|
|
8cb1f3f387 | ||
|
|
3f0c6fcec5 | ||
|
|
797cf893da | ||
|
|
a3564b70e1 | ||
|
|
43004307b8 | ||
|
|
acd1e4ced3 | ||
|
|
6717070f93 | ||
|
|
387499ae49 | ||
|
|
8ab140c55d | ||
|
|
914abb95dd | ||
|
|
5360c0f0f7 | ||
|
|
243d803b51 | ||
|
|
b343fe3835 | ||
|
|
3c42c1120f | ||
|
|
ad840dcef6 | ||
|
|
f73072d95e | ||
|
|
95cb9b5079 | ||
|
|
c6684d3c9b | ||
|
|
5c5989d8c0 | ||
|
|
60e92d30b0 | ||
|
|
8bf8e3f86b | ||
|
|
891ee2d06b | ||
|
|
b450bc7ae8 | ||
|
|
4ca1e0d5db | ||
|
|
859213dd9e | ||
|
|
ad2857791d | ||
|
|
497827f2e2 | ||
|
|
967e333022 | ||
|
|
8df1406006 | ||
|
|
4af42fafdc | ||
|
|
a9e6a452c1 | ||
|
|
a4a4632397 | ||
|
|
421f39e414 | ||
|
|
f8121e2dc4 | ||
|
|
b1784fc51c | ||
|
|
96db0d7de7 | ||
|
|
3837ed9cb1 | ||
|
|
2be789a43c | ||
|
|
fd8d96169a | ||
|
|
1562dc32c1 | ||
|
|
38f377ca09 | ||
|
|
cc28bba884 | ||
|
|
beb3081918 | ||
|
|
1b3c9106b5 | ||
|
|
385b91761b | ||
|
|
43600756c0 | ||
|
|
3c3e0633ad | ||
|
|
f819ad6917 | ||
|
|
e7ad396fc6 | ||
|
|
b1cb4d4257 | ||
|
|
100bd4b062 | ||
|
|
7da09d9b37 | ||
|
|
f46eb07228 | ||
|
|
7627b5eb25 | ||
|
|
c710448c6b | ||
|
|
1ad270b1d6 | ||
|
|
099e253b2b | ||
|
|
66de4a5b91 | ||
|
|
41437d91d5 | ||
|
|
d33d5a6efa | ||
|
|
4f9248d040 | ||
|
|
f40c0e41f3 | ||
|
|
deeb03ff2b | ||
|
|
5c2a09e243 | ||
|
|
2473c999db | ||
|
|
ea2cc265e3 | ||
|
|
a0cd2d42cf |
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@@ -1,6 +1,7 @@
|
|||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
|
||||||
github: LucasGGamerM
|
github: LucasGGamerM
|
||||||
|
custom: ["https://liberapay.com/LucasGGamerM/donate", liberapay.com]
|
||||||
patreon: # mastodon
|
patreon: # mastodon
|
||||||
open_collective: # Replace with a single Open Collective username e.g., user1
|
open_collective: # Replace with a single Open Collective username e.g., user1
|
||||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
|||||||
22
.github/workflows/nightly-builds.yml
vendored
22
.github/workflows/nightly-builds.yml
vendored
@@ -10,6 +10,28 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout Appkit Repo
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: grishka/appkit
|
||||||
|
|
||||||
|
- name: set up JDK 17
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
java-version: '17'
|
||||||
|
distribution: 'corretto'
|
||||||
|
cache: gradle
|
||||||
|
|
||||||
|
- name: Comment out signing config in appkits gradle file
|
||||||
|
run: |
|
||||||
|
sed -i 's/sign publishing\.publications\.release/\/\/ sign publishing.publications.release/' appkit/maven-push.gradle
|
||||||
|
|
||||||
|
- name: Grant execute permission for gradlew for Appkit
|
||||||
|
run: chmod +x gradlew
|
||||||
|
|
||||||
|
- name: Compile appkit
|
||||||
|
run: ./gradlew publishToMavenLocal
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: set up JDK 17
|
- name: set up JDK 17
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v3
|
||||||
|
|||||||
4
FAQ.md
4
FAQ.md
@@ -3,3 +3,7 @@
|
|||||||
Q: What are the main differences between Moshidon and Megalodon?
|
Q: What are the main differences between Moshidon and Megalodon?
|
||||||
|
|
||||||
A: There are many, but the most outstanding differences are: the ability to have other server's local timeline inside the app. It can be acessed in the "Add community" option in the top right corner of the Edit timelines screen. Other outstanding features that Moshidon has are some quality of life improvements, such as notification actions and allowing for unlisted replies by default. Most other features are pretty minor, such as profile notes directly available in the person's profile. Other features are quite minor usability and visibility improvements. All of which can be found in the settings page.
|
A: There are many, but the most outstanding differences are: the ability to have other server's local timeline inside the app. It can be acessed in the "Add community" option in the top right corner of the Edit timelines screen. Other outstanding features that Moshidon has are some quality of life improvements, such as notification actions and allowing for unlisted replies by default. Most other features are pretty minor, such as profile notes directly available in the person's profile. Other features are quite minor usability and visibility improvements. All of which can be found in the settings page.
|
||||||
|
|
||||||
|
Q: Will there ever be a versjon of Moshidon for iOS?
|
||||||
|
|
||||||
|
A: No. As android and iOS apps do not share code, it is incredibly hard to port.
|
||||||
|
|||||||
@@ -19,6 +19,10 @@
|
|||||||
<a href="https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.moshinda"><img height="50" alt="Get it on IzzyOnDroid" src="img/izzy-badge.png"></a>
|
<a href="https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.moshinda"><img height="50" alt="Get it on IzzyOnDroid" src="img/izzy-badge.png"></a>
|
||||||
|
|
||||||
## Help out the project by donating at: https://github.com/sponsors/LucasGGamerM!
|
## Help out the project by donating at: https://github.com/sponsors/LucasGGamerM!
|
||||||
|
### We also support LiberaPay at: https://liberapay.com/LucasGGamerM/donate!
|
||||||
|
|
||||||
|
### You can also donate some Monero through this wallet address as well:
|
||||||
|
4886mdarcyB6Yf8Qc6vDJBK1fz6ibHFLZUmHb4GZZz9yLGNhcG3XC64e5UZ8dVQYTLZb82W6P9WhteowW4STJEec97Gf22j
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -191,6 +195,8 @@ This project is released under the [GPL-3 License](./LICENSE).
|
|||||||
|
|
||||||
[Official matrix chatroom:](https://matrix.to/#/#moshidon:floss.social) https://matrix.to/#/#moshidon:floss.social
|
[Official matrix chatroom:](https://matrix.to/#/#moshidon:floss.social) https://matrix.to/#/#moshidon:floss.social
|
||||||
|
|
||||||
|
[Moshidon roadmap](https://github.com/users/LucasGGamerM/projects/1)
|
||||||
|
|
||||||
<a rel="me" href="https://floss.social/@moshidon">@moshidon<wbr>@floss.social</a>
|
<a rel="me" href="https://floss.social/@moshidon">@moshidon<wbr>@floss.social</a>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ buildscript {
|
|||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.0.0'
|
classpath 'com.android.tools.build:gradle:8.0.0'
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ android {
|
|||||||
versionName "1.3.0+fork.100.moshinda"
|
versionName "1.3.0+fork.100.moshinda"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
resourceConfigurations += ['ar-rSA', 'ar-rDZ', 'be-rBY', 'bn-rBD', 'bs-rBA', 'ca-rES', 'cs-rCZ', 'da-rDK', 'de-rDE', 'el-rGR', 'es-rES', 'eu-rES', 'fa-rIR', 'fi-rFI', 'fil-rPH', 'fr-rFR', 'ga-rIE', 'gd-rGB', 'gl-rES', 'hi-rIN', 'hr-rHR', 'hu-rHU', 'hy-rAM', 'ig-rNG', 'in-rID', 'is-rIS', 'it-rIT', 'iw-rIL', 'ja-rJP', 'kab', 'ko-rKR', 'my-rMM', 'nl-rNL', 'no-rNO', 'oc-rFR', 'pl-rPL', 'pt-rBR', 'pt-rPT', 'ro-rRO', 'ru-rRU', 'si-rLK', 'sl-rSI', 'sv-rSE', 'th-rTH', 'tr-rTR', 'uk-rUA', 'ur-rIN', 'vi-rVN', 'zh-rCN', 'zh-rTW']
|
resourceConfigurations += ['ar-rSA', 'ar-rDZ', 'be-rBY', 'bn-rBD', 'bs-rBA', 'ca-rES', 'cs-rCZ', 'da-rDK', 'de-rDE', 'el-rGR', 'es-rES', 'eu-rES', 'fa-rIR', 'fi-rFI', 'fil-rPH', 'fr-rFR', 'ga-rIE', 'gd-rGB', 'gl-rES', 'hi-rIN', 'hr-rHR', 'hu-rHU', 'hy-rAM', 'ig-rNG', 'in-rID', 'is-rIS', 'it-rIT', 'iw-rIL', 'ja-rJP', 'kab', 'ko-rKR', 'my-rMM', 'nl-rNL', 'no-rNO', 'oc-rFR', 'pl-rPL', 'pt-rBR', 'pt-rPT', 'ro-rRO', 'ru-rRU', 'si-rLK', 'sl-rSI', 'sv-rSE', 'th-rTH', 'tr-rTR', 'uk-rUA', 'ur-rIN', 'vi-rVN', 'zh-rCN', 'zh-rTW']
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
nightly{
|
nightly{
|
||||||
@@ -62,7 +62,6 @@ android {
|
|||||||
initWith release
|
initWith release
|
||||||
}
|
}
|
||||||
nightly{
|
nightly{
|
||||||
initWith release
|
|
||||||
if(System.getenv("CURRENT_DATE") != null){
|
if(System.getenv("CURRENT_DATE") != null){
|
||||||
versionNameSuffix '-nightly+@' + System.getenv("CURRENT_DATE")
|
versionNameSuffix '-nightly+@' + System.getenv("CURRENT_DATE")
|
||||||
} else {
|
} else {
|
||||||
@@ -71,6 +70,7 @@ android {
|
|||||||
versionNameSuffix '-nightly+@' + properties.getProperty('CURRENT_DATE')
|
versionNameSuffix '-nightly+@' + properties.getProperty('CURRENT_DATE')
|
||||||
}
|
}
|
||||||
applicationIdSuffix '.nightly'
|
applicationIdSuffix '.nightly'
|
||||||
|
|
||||||
signingConfig signingConfigs.nightly
|
signingConfig signingConfigs.nightly
|
||||||
manifestPlaceholders = [oAuthScheme:"moshidon-android-nightly-auth"]
|
manifestPlaceholders = [oAuthScheme:"moshidon-android-nightly-auth"]
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ dependencies {
|
|||||||
implementation 'me.grishka.litex:dynamicanimation:1.1.0-alpha03'
|
implementation 'me.grishka.litex:dynamicanimation:1.1.0-alpha03'
|
||||||
implementation 'me.grishka.litex:viewpager:1.0.0'
|
implementation 'me.grishka.litex:viewpager:1.0.0'
|
||||||
implementation 'me.grishka.litex:viewpager2:1.0.0'
|
implementation 'me.grishka.litex:viewpager2:1.0.0'
|
||||||
implementation 'me.grishka.appkit:appkit:1.2.7'
|
implementation 'me.grishka.appkit:appkit:1.2.8'
|
||||||
implementation 'com.google.code.gson:gson:2.9.0'
|
implementation 'com.google.code.gson:gson:2.9.0'
|
||||||
implementation 'org.jsoup:jsoup:1.14.3'
|
implementation 'org.jsoup:jsoup:1.14.3'
|
||||||
implementation 'com.squareup:otto:1.3.8'
|
implementation 'com.squareup:otto:1.3.8'
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||||
|
import org.joinmastodon.android.events.StatusUpdatedEvent;
|
||||||
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.joinmastodon.android.model.StatusContext;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ThreadFragmentTest {
|
||||||
|
|
||||||
|
private Status fakeStatus(String id, String inReplyTo) {
|
||||||
|
Status status = Status.ofFake(id, null, null);
|
||||||
|
status.inReplyToId = inReplyTo;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ThreadFragment.NeighborAncestryInfo fakeInfo(Status s, Status d, Status a) {
|
||||||
|
return new ThreadFragment.NeighborAncestryInfo(s, d, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapNeighborhoodAncestry() {
|
||||||
|
StatusContext context = new StatusContext();
|
||||||
|
context.ancestors = List.of(
|
||||||
|
fakeStatus("oldest ancestor", null),
|
||||||
|
fakeStatus("younger ancestor", "oldest ancestor")
|
||||||
|
);
|
||||||
|
Status mainStatus = fakeStatus("main status", "younger ancestor");
|
||||||
|
context.descendants = List.of(
|
||||||
|
fakeStatus("first reply", "main status"),
|
||||||
|
fakeStatus("reply to first reply", "first reply"),
|
||||||
|
fakeStatus("third level reply", "reply to first reply"),
|
||||||
|
fakeStatus("another reply", "main status")
|
||||||
|
);
|
||||||
|
|
||||||
|
List<ThreadFragment.NeighborAncestryInfo> neighbors =
|
||||||
|
ThreadFragment.mapNeighborhoodAncestry(mainStatus, context);
|
||||||
|
|
||||||
|
assertEquals(List.of(
|
||||||
|
fakeInfo(context.ancestors.get(0), context.ancestors.get(1), null),
|
||||||
|
fakeInfo(context.ancestors.get(1), mainStatus, context.ancestors.get(0)),
|
||||||
|
fakeInfo(mainStatus, context.descendants.get(0), context.ancestors.get(1)),
|
||||||
|
fakeInfo(context.descendants.get(0), context.descendants.get(1), mainStatus),
|
||||||
|
fakeInfo(context.descendants.get(1), context.descendants.get(2), context.descendants.get(0)),
|
||||||
|
fakeInfo(context.descendants.get(2), null, context.descendants.get(1)),
|
||||||
|
fakeInfo(context.descendants.get(3), null, null)
|
||||||
|
), neighbors);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void maybeApplyMainStatus() {
|
||||||
|
ThreadFragment fragment = new ThreadFragment();
|
||||||
|
fragment.contextInitiallyRendered = true;
|
||||||
|
fragment.mainStatus = Status.ofFake("123456", "original text", Instant.EPOCH);
|
||||||
|
|
||||||
|
Status update1 = Status.ofFake("123456", "updated text", Instant.EPOCH);
|
||||||
|
update1.editedAt = Instant.ofEpochSecond(1);
|
||||||
|
fragment.updatedStatus = update1;
|
||||||
|
StatusUpdatedEvent event1 = (StatusUpdatedEvent) fragment.maybeApplyMainStatus();
|
||||||
|
assertEquals("fired update event", update1, event1.status);
|
||||||
|
assertEquals("updated main status", update1, fragment.mainStatus);
|
||||||
|
|
||||||
|
Status update2 = Status.ofFake("123456", "updated text", Instant.EPOCH);
|
||||||
|
update2.favouritesCount = 123;
|
||||||
|
fragment.updatedStatus = update2;
|
||||||
|
StatusCountersUpdatedEvent event2 = (StatusCountersUpdatedEvent) fragment.maybeApplyMainStatus();
|
||||||
|
assertEquals("only fired counter update event", update2.id, event2.id);
|
||||||
|
assertEquals("updated counter is correct", 123, event2.favorites);
|
||||||
|
assertEquals("updated main status", update2, fragment.mainStatus);
|
||||||
|
|
||||||
|
Status update3 = Status.ofFake("123456", "whatever", Instant.EPOCH);
|
||||||
|
fragment.contextInitiallyRendered = false;
|
||||||
|
fragment.updatedStatus = update3;
|
||||||
|
assertNull("no update when context hasn't been rendered", fragment.maybeApplyMainStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sortStatusContext() {
|
||||||
|
StatusContext context = new StatusContext();
|
||||||
|
context.ancestors = List.of(
|
||||||
|
fakeStatus("younger ancestor", "oldest ancestor"),
|
||||||
|
fakeStatus("oldest ancestor", null)
|
||||||
|
);
|
||||||
|
context.descendants = List.of(
|
||||||
|
fakeStatus("reply to first reply", "first reply"),
|
||||||
|
fakeStatus("third level reply", "reply to first reply"),
|
||||||
|
fakeStatus("first reply", "main status"),
|
||||||
|
fakeStatus("another reply", "main status")
|
||||||
|
);
|
||||||
|
|
||||||
|
ThreadFragment.sortStatusContext(
|
||||||
|
fakeStatus("main status", "younger ancestor"),
|
||||||
|
context
|
||||||
|
);
|
||||||
|
List<Status> expectedAncestors = List.of(
|
||||||
|
fakeStatus("oldest ancestor", null),
|
||||||
|
fakeStatus("younger ancestor", "oldest ancestor")
|
||||||
|
);
|
||||||
|
List<Status> expectedDescendants = List.of(
|
||||||
|
fakeStatus("first reply", "main status"),
|
||||||
|
fakeStatus("reply to first reply", "first reply"),
|
||||||
|
fakeStatus("third level reply", "reply to first reply"),
|
||||||
|
fakeStatus("another reply", "main status")
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: ??? i have no idea how this code works. it certainly doesn't return what i'd expect
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package org.joinmastodon.android.test;
|
package org.joinmastodon.android.test;
|
||||||
|
|
||||||
|
import android.app.Instrumentation;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
|
||||||
@@ -12,10 +14,10 @@ import org.joinmastodon.android.GlobalUserPreferences;
|
|||||||
import org.joinmastodon.android.MainActivity;
|
import org.joinmastodon.android.MainActivity;
|
||||||
import org.joinmastodon.android.MastodonApp;
|
import org.joinmastodon.android.MastodonApp;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.instance.GetInstance;
|
import org.joinmastodon.android.api.requests.instance.GetInstance;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.statuses.GetStatusByID;
|
import org.joinmastodon.android.api.requests.statuses.GetStatusByID;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSession;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||||
import org.joinmastodon.android.fragments.onboarding.InstanceRulesFragment;
|
import org.joinmastodon.android.fragments.onboarding.InstanceRulesFragment;
|
||||||
@@ -30,9 +32,12 @@ import org.parceler.Parcels;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.BrokenBarrierException;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.CyclicBarrier;
|
import java.util.concurrent.CyclicBarrier;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import androidx.test.core.app.ActivityScenario;
|
||||||
import androidx.test.espresso.PerformException;
|
import androidx.test.espresso.PerformException;
|
||||||
import androidx.test.espresso.UiController;
|
import androidx.test.espresso.UiController;
|
||||||
import androidx.test.espresso.ViewAction;
|
import androidx.test.espresso.ViewAction;
|
||||||
@@ -42,15 +47,18 @@ import androidx.test.ext.junit.rules.ActivityScenarioRule;
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import androidx.test.filters.LargeTest;
|
import androidx.test.filters.LargeTest;
|
||||||
import androidx.test.platform.app.InstrumentationRegistry;
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
|
import androidx.test.runner.screenshot.ScreenCapture;
|
||||||
import androidx.test.runner.screenshot.Screenshot;
|
import androidx.test.runner.screenshot.Screenshot;
|
||||||
import me.grishka.appkit.api.Callback;
|
import me.grishka.appkit.api.Callback;
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
import okio.BufferedSink;
|
import okio.BufferedSink;
|
||||||
import okio.Okio;
|
import okio.Okio;
|
||||||
|
import okio.Sink;
|
||||||
import okio.Source;
|
import okio.Source;
|
||||||
|
|
||||||
import static androidx.test.espresso.Espresso.*;
|
import static androidx.test.espresso.Espresso.*;
|
||||||
import static androidx.test.espresso.action.ViewActions.*;
|
import static androidx.test.espresso.action.ViewActions.*;
|
||||||
|
import static androidx.test.espresso.assertion.ViewAssertions.*;
|
||||||
import static androidx.test.espresso.matcher.ViewMatchers.*;
|
import static androidx.test.espresso.matcher.ViewMatchers.*;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package org.joinmastodon.android.ui.utils;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
|
import org.joinmastodon.android.model.Account;
|
||||||
|
import org.joinmastodon.android.model.Instance;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class UiUtilsTest {
|
||||||
|
@BeforeClass
|
||||||
|
public static void createDummySession() {
|
||||||
|
Instance dummyInstance = new Instance();
|
||||||
|
dummyInstance.uri = "test.tld";
|
||||||
|
Account dummyAccount = new Account();
|
||||||
|
dummyAccount.id = "123456";
|
||||||
|
AccountSessionManager.getInstance().addAccount(dummyInstance, null, dummyAccount, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void cleanUp() {
|
||||||
|
AccountSessionManager.getInstance().removeAccount("test.tld_123456");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseFediverseHandle() {
|
||||||
|
assertEquals(
|
||||||
|
Optional.of(Pair.create("megalodon", Optional.of("floss.social"))),
|
||||||
|
UiUtils.parseFediverseHandle("megalodon@floss.social")
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Optional.of(Pair.create("megalodon", Optional.of("floss.social"))),
|
||||||
|
UiUtils.parseFediverseHandle("@megalodon@floss.social")
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Optional.of(Pair.create("megalodon", Optional.empty())),
|
||||||
|
UiUtils.parseFediverseHandle("@megalodon")
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Optional.of(Pair.create("megalodon", Optional.of("floss.social"))),
|
||||||
|
UiUtils.parseFediverseHandle("mailto:megalodon@floss.social")
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Optional.empty(),
|
||||||
|
UiUtils.parseFediverseHandle("megalodon")
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Optional.empty(),
|
||||||
|
UiUtils.parseFediverseHandle("this is not a fedi handle")
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
Optional.empty(),
|
||||||
|
UiUtils.parseFediverseHandle("not@a-domain")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void acctMatches() {
|
||||||
|
assertTrue("local account, domain not specified", UiUtils.acctMatches(
|
||||||
|
"test.tld_123456",
|
||||||
|
"someone",
|
||||||
|
"someone",
|
||||||
|
null
|
||||||
|
));
|
||||||
|
|
||||||
|
assertTrue("domain not specified", UiUtils.acctMatches(
|
||||||
|
"test.tld_123456",
|
||||||
|
"someone@somewhere.social",
|
||||||
|
"someone",
|
||||||
|
null
|
||||||
|
));
|
||||||
|
|
||||||
|
assertTrue("local account, domain specified, different casing", UiUtils.acctMatches(
|
||||||
|
"test.tld_123456",
|
||||||
|
"SomeOne",
|
||||||
|
"someone",
|
||||||
|
"Test.TLD"
|
||||||
|
));
|
||||||
|
|
||||||
|
assertFalse("username doesn't match", UiUtils.acctMatches(
|
||||||
|
"test.tld_123456",
|
||||||
|
"someone-else@somewhere.social",
|
||||||
|
"someone",
|
||||||
|
"somewhere.social"
|
||||||
|
));
|
||||||
|
|
||||||
|
assertFalse("domain doesn't match", UiUtils.acctMatches(
|
||||||
|
"test.tld_123456",
|
||||||
|
"someone@somewhere.social",
|
||||||
|
"someone",
|
||||||
|
"somewhere.else"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package org.joinmastodon.android.utils;
|
||||||
|
|
||||||
|
import static org.joinmastodon.android.model.Filter.FilterAction.*;
|
||||||
|
import static org.joinmastodon.android.model.Filter.FilterContext.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.model.Filter;
|
||||||
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StatusFilterPredicateTest {
|
||||||
|
|
||||||
|
private static final Filter hideMeFilter = new Filter(), warnMeFilter = new Filter();
|
||||||
|
private static final List<Filter> allFilters = List.of(hideMeFilter, warnMeFilter);
|
||||||
|
|
||||||
|
private static final Status
|
||||||
|
hideInHomePublic = Status.ofFake(null, "hide me, please", Instant.now()),
|
||||||
|
warnInHomePublic = Status.ofFake(null, "display me with a warning", Instant.now());
|
||||||
|
|
||||||
|
static {
|
||||||
|
hideMeFilter.phrase = "hide me";
|
||||||
|
hideMeFilter.filterAction = HIDE;
|
||||||
|
hideMeFilter.context = EnumSet.of(PUBLIC, HOME);
|
||||||
|
|
||||||
|
warnMeFilter.phrase = "warning";
|
||||||
|
warnMeFilter.filterAction = WARN;
|
||||||
|
warnMeFilter.context = EnumSet.of(PUBLIC, HOME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHide() {
|
||||||
|
assertFalse("should not pass because matching filter applies to given context",
|
||||||
|
new StatusFilterPredicate(allFilters, HOME).test(hideInHomePublic));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHideRegardlessOfContext() {
|
||||||
|
assertTrue("filters without context should always pass",
|
||||||
|
new StatusFilterPredicate(allFilters, null).test(hideInHomePublic));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHideInDifferentContext() {
|
||||||
|
assertTrue("should pass because matching filter does not apply to given context",
|
||||||
|
new StatusFilterPredicate(allFilters, THREAD).test(hideInHomePublic));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHideWithWarningText() {
|
||||||
|
assertTrue("should pass because matching filter is for warnings",
|
||||||
|
new StatusFilterPredicate(allFilters, HOME).test(warnInHomePublic));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWarn() {
|
||||||
|
assertFalse("should not pass because filter applies to given context",
|
||||||
|
new StatusFilterPredicate(allFilters, HOME, WARN).test(warnInHomePublic));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWarnRegardlessOfContext() {
|
||||||
|
assertTrue("filters without context should always pass",
|
||||||
|
new StatusFilterPredicate(allFilters, null, WARN).test(warnInHomePublic));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWarnInDifferentContext() {
|
||||||
|
assertTrue("should pass because filter does not apply to given context",
|
||||||
|
new StatusFilterPredicate(allFilters, THREAD, WARN).test(warnInHomePublic));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWarnWithHideText() {
|
||||||
|
assertTrue("should pass because matching filter is for hiding",
|
||||||
|
new StatusFilterPredicate(allFilters, HOME, WARN).test(hideInHomePublic));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28"/>
|
||||||
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
|
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
|
||||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
|
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
|
||||||
@@ -40,6 +41,22 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".PanicResponderActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleInstance"
|
||||||
|
android:noHistory="true"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="info.guardianproject.panic.action.TRIGGER" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".ExitActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay" />
|
||||||
<activity android:name=".OAuthActivity" android:exported="true" android:configChanges="orientation|screenSize" android:launchMode="singleTask">
|
<activity android:name=".OAuthActivity" android:exported="true" android:configChanges="orientation|screenSize" android:launchMode="singleTask">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW"/>
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
# lists.d Mastodon Blocklist (c) 2022 Greyhat Academy LICENSED UNDER: CC-BY-NC-SA 4.0
|
|
||||||
# https://raw.githubusercontent.com/greyhat-academy/lists.d/main/mastodon.domains.block.list.tsv
|
|
||||||
# This list contains domains of toxic mastodon instances
|
|
||||||
# Last-Modified: 1672044500
|
|
||||||
|
|
||||||
# gab - a neonazi social network
|
|
||||||
gab.ai
|
|
||||||
gab.com
|
|
||||||
gab.protohype.net
|
|
||||||
|
|
||||||
# consequence-free speech
|
|
||||||
social.unzensiert.to
|
|
||||||
freeatlantis.com
|
|
||||||
|
|
||||||
# reactionary bigotry and hatespeech against marginalized groups
|
|
||||||
poa.st
|
|
||||||
freespeechextremist.com
|
|
||||||
rdrama.cc
|
|
||||||
outpoa.st
|
|
||||||
anime.website
|
|
||||||
gameliberty.club
|
|
||||||
social.byoblu.com
|
|
||||||
yggdrasil.social
|
|
||||||
smuglo.li
|
|
||||||
dogeposting.social
|
|
||||||
unsafe.space
|
|
||||||
freezepeach.xyz
|
|
||||||
|
|
||||||
# + CSAM
|
|
||||||
rojogato.com
|
|
||||||
|
|
||||||
# antivaxxer shitposting & fearmongering
|
|
||||||
shadowsocial.org
|
|
||||||
|
|
||||||
# Kiwifarms
|
|
||||||
kiwifarms.net
|
|
||||||
kiwifarms.cc
|
|
||||||
kiwifarms.is
|
|
||||||
kiwifarms.pleroma.net
|
|
||||||
|
|
||||||
|
|
||||||
# https://mastodon.art/@Curator/109649354849593592
|
|
||||||
|
|
||||||
poa.st antisemitic racist homophobic
|
|
||||||
nicecrew.digital antisemitic
|
|
||||||
beefyboys.win antisemitic racist homophobic harassment
|
|
||||||
cawfee.club antisemitic racist homophobic
|
|
||||||
comfyboy.club antisemitic racist homophobic
|
|
||||||
freespeechextremist.com racist homophobic
|
|
||||||
cum.salon racist misogynist
|
|
||||||
bae.st racist
|
|
||||||
natehiggers.online racist
|
|
||||||
rapemeat.solutions misogynist
|
|
||||||
rapist.town misogynist
|
|
||||||
rapefeminists.network misogynist
|
|
||||||
kiwifarms.cc harassment
|
|
||||||
noagendasocial.com noagenda
|
|
||||||
posting.lolicon.rocks underage
|
|
||||||
urchan.org harassment homophobic racist
|
|
||||||
ryona.agency harassment
|
|
||||||
yggdrasil.social antisemitic homophobic racist
|
|
||||||
genderheretics.xyz transphobic
|
|
||||||
baraag.net underage
|
|
||||||
lolison.top underage
|
|
||||||
shota.house underage
|
|
||||||
shota.social underage
|
|
||||||
aethy.com underage
|
|
||||||
taullo.social underage
|
|
||||||
childpawn.shop underage
|
|
||||||
posting.lolicon.rocks underage
|
|
||||||
loli.best underage
|
|
||||||
gothloli.club underage
|
|
||||||
smuglo.li underage
|
|
||||||
youjo.love underage
|
|
||||||
pedo.school underage
|
|
||||||
lolison.network underage
|
|
||||||
freak.university underage
|
|
||||||
mirr0r.city underage
|
|
||||||
xhais.love underage
|
|
||||||
refusal.biz underage
|
|
||||||
refusal.llc underage
|
|
||||||
mirr0r.city underage
|
|
||||||
nnia.space underage
|
|
||||||
ignorelist.com malicious
|
|
||||||
repl.co malicious
|
|
||||||
|
|
||||||
# custom
|
|
||||||
|
|
||||||
pawoo.net csam
|
|
||||||
|
171
mastodon/src/main/assets/blocks.txt
Normal file
171
mastodon/src/main/assets/blocks.txt
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
13bells.com
|
||||||
|
4aem.com
|
||||||
|
aethy.com
|
||||||
|
anime.website
|
||||||
|
annihilation.social
|
||||||
|
anon-kenkai.com
|
||||||
|
asbestos.cafe
|
||||||
|
bae.st
|
||||||
|
bajax.us
|
||||||
|
banepo.st
|
||||||
|
baraag.net
|
||||||
|
beefyboys.win
|
||||||
|
beepboop.ga
|
||||||
|
berserker.town
|
||||||
|
bikeshed.party
|
||||||
|
boks.moe
|
||||||
|
brainsoap.net
|
||||||
|
breastmilk.club
|
||||||
|
brighteon.social
|
||||||
|
cawfee.club
|
||||||
|
clew.lol
|
||||||
|
clubcyberia.co
|
||||||
|
collapsitarian.io
|
||||||
|
comfyboy.club
|
||||||
|
contrapointsfan.club
|
||||||
|
cum.camp
|
||||||
|
cum.salon
|
||||||
|
cybercriminal.eu
|
||||||
|
darknight-coffee.org
|
||||||
|
dembased.xyz
|
||||||
|
desupost.soy
|
||||||
|
detroitriotcity.com
|
||||||
|
eatthebugs.social
|
||||||
|
eientei.org
|
||||||
|
elementality.org
|
||||||
|
eveningzoo.club
|
||||||
|
firedragonstudios.com
|
||||||
|
firefaithfellowship.com
|
||||||
|
fluf.club
|
||||||
|
foxfam.club
|
||||||
|
freak.university
|
||||||
|
freeatlantis.com
|
||||||
|
freecumextremist.com
|
||||||
|
freedomstrike.org
|
||||||
|
freesoftwareextremist.com
|
||||||
|
freespeech.group
|
||||||
|
freespeechextremist.com
|
||||||
|
freetalklive.com
|
||||||
|
froth.zone
|
||||||
|
fulltermprivacy.com
|
||||||
|
gameliberty.club
|
||||||
|
gearlandia.haus
|
||||||
|
genderheretics.xyz
|
||||||
|
geofront.rocks
|
||||||
|
gleasonator.com
|
||||||
|
glee.li
|
||||||
|
glindr.org
|
||||||
|
goyim.app
|
||||||
|
goyslop.cafe
|
||||||
|
haeder.net
|
||||||
|
handholding.io
|
||||||
|
hidamari.apartments
|
||||||
|
hitchhiker.social
|
||||||
|
hunk.city
|
||||||
|
iddqd.social
|
||||||
|
intkos.link
|
||||||
|
justicewarrior.social
|
||||||
|
kawa-kun.com
|
||||||
|
kitsunemimi.club
|
||||||
|
kiwifarms.cc
|
||||||
|
kompost.cz
|
||||||
|
kurosawa.moe
|
||||||
|
leafposter.club
|
||||||
|
leftychan.net
|
||||||
|
lewdieheaven.com
|
||||||
|
liberdon.com
|
||||||
|
ligma.pro
|
||||||
|
lizards.live
|
||||||
|
lolicon.rocks
|
||||||
|
lolison.top
|
||||||
|
lovingexpressions.net
|
||||||
|
lucasvl.nl
|
||||||
|
mahodou.moe
|
||||||
|
makemysarcophagus.com
|
||||||
|
maladaptive.art
|
||||||
|
masochi.st
|
||||||
|
mastinator.com
|
||||||
|
merovingian.club
|
||||||
|
midwaytrades.com
|
||||||
|
mirr0r.city
|
||||||
|
moa.st
|
||||||
|
mouse.services
|
||||||
|
mugicha.club
|
||||||
|
narrativerry.xyz
|
||||||
|
natehiggers.online
|
||||||
|
neckbeard.xyz
|
||||||
|
needs.vodka
|
||||||
|
neenster.org
|
||||||
|
nicecrew.digital
|
||||||
|
nnia.space
|
||||||
|
noagendasocial.com
|
||||||
|
noagendasocial.nl
|
||||||
|
noagendatube.com
|
||||||
|
nobodyhasthe.biz
|
||||||
|
nukem.biz
|
||||||
|
obo.sh
|
||||||
|
onionfarms.org
|
||||||
|
outpoa.st
|
||||||
|
pawlicker.com
|
||||||
|
pawoo.net
|
||||||
|
pedo.school
|
||||||
|
piazza.today
|
||||||
|
pibvt.net
|
||||||
|
pieville.net
|
||||||
|
pisskey.io
|
||||||
|
plagu.ee
|
||||||
|
pmth.us
|
||||||
|
poa.st
|
||||||
|
poast.org
|
||||||
|
poast.tv
|
||||||
|
poster.place
|
||||||
|
prospeech.space
|
||||||
|
quodverum.com
|
||||||
|
rakket.app
|
||||||
|
rapemeat.solutions
|
||||||
|
rdrama.cc
|
||||||
|
rebelbase.site
|
||||||
|
retardedniggers.forsale
|
||||||
|
rojogato.com
|
||||||
|
ryona.agency
|
||||||
|
schwartzwelt.xyz
|
||||||
|
seal.cafe
|
||||||
|
shigusegubu.club
|
||||||
|
shitpost.cloud
|
||||||
|
shitposter.club
|
||||||
|
shota.house
|
||||||
|
silliness.observer
|
||||||
|
skinheads.eu
|
||||||
|
skinheads.io
|
||||||
|
skinheads.social
|
||||||
|
skinheads.uk
|
||||||
|
skippers-bin.com
|
||||||
|
skyshanty.xyz
|
||||||
|
slash.cl
|
||||||
|
sleepy.cafe
|
||||||
|
smuglo.li
|
||||||
|
sneed.social
|
||||||
|
sonichu.com
|
||||||
|
spinster.xyz
|
||||||
|
springbo.cc
|
||||||
|
starnix.network
|
||||||
|
stereophonic.space
|
||||||
|
strelizia.net
|
||||||
|
syspxl.xyz
|
||||||
|
tastingtraffic.net
|
||||||
|
teci.world
|
||||||
|
theapex.social
|
||||||
|
thepostearthdestination.com
|
||||||
|
tkammer.de
|
||||||
|
trumpislovetrumpis.life
|
||||||
|
truthsocial.co.in
|
||||||
|
urchan.org
|
||||||
|
varishangout.net
|
||||||
|
whinge.house
|
||||||
|
whinge.town
|
||||||
|
wideboys.org
|
||||||
|
wolfgirl.bar
|
||||||
|
xn--p1abe3d.xn--80asehdb
|
||||||
|
yggdrasil.social
|
||||||
|
youjo.love
|
||||||
|
zztails.gay
|
||||||
@@ -1,5 +1,62 @@
|
|||||||
package org.joinmastodon.android;
|
package org.joinmastodon.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.ShortcutInfo;
|
||||||
|
import android.content.pm.ShortcutManager;
|
||||||
|
import android.graphics.drawable.Icon;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.browser.customtabs.CustomTabsIntent;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.MastodonAPIController;
|
||||||
|
import org.joinmastodon.android.api.PushSubscriptionManager;
|
||||||
|
import org.joinmastodon.android.api.requests.accounts.GetOwnAccount;
|
||||||
|
import org.joinmastodon.android.api.requests.accounts.GetPreferences;
|
||||||
|
import org.joinmastodon.android.api.requests.accounts.GetWordFilters;
|
||||||
|
import org.joinmastodon.android.api.requests.instance.GetCustomEmojis;
|
||||||
|
import org.joinmastodon.android.api.requests.instance.GetInstance;
|
||||||
|
import org.joinmastodon.android.api.requests.oauth.CreateOAuthApp;
|
||||||
|
import org.joinmastodon.android.api.session.AccountActivationInfo;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
|
import org.joinmastodon.android.events.EmojiUpdatedEvent;
|
||||||
|
import org.joinmastodon.android.model.Account;
|
||||||
|
import org.joinmastodon.android.model.Application;
|
||||||
|
import org.joinmastodon.android.model.Emoji;
|
||||||
|
import org.joinmastodon.android.model.EmojiCategory;
|
||||||
|
import org.joinmastodon.android.model.Filter;
|
||||||
|
import org.joinmastodon.android.model.Instance;
|
||||||
|
import org.joinmastodon.android.model.Preferences;
|
||||||
|
import org.joinmastodon.android.model.Token;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import me.grishka.appkit.api.Callback;
|
||||||
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
|
||||||
public class DomainManager {
|
public class DomainManager {
|
||||||
private static final String TAG="DomainManager";
|
private static final String TAG="DomainManager";
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.joinmastodon.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class ExitActivity extends Activity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
finishAndRemoveTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void exit(Context context) {
|
||||||
|
Intent intent = new Intent(context, ExitActivity.class);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
package org.joinmastodon.android;
|
package org.joinmastodon.android;
|
||||||
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.assist.AssistContent;
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Pair;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSession;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||||
import org.joinmastodon.android.ui.AccountSwitcherSheet;
|
import org.joinmastodon.android.ui.AccountSwitcherSheet;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
@@ -19,6 +20,8 @@ import org.jsoup.internal.StringUtil;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import me.grishka.appkit.FragmentStackActivity;
|
import me.grishka.appkit.FragmentStackActivity;
|
||||||
@@ -30,22 +33,51 @@ public class ExternalShareActivity extends FragmentStackActivity{
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
if(savedInstanceState==null){
|
if(savedInstanceState==null){
|
||||||
|
|
||||||
String text = getIntent().getStringExtra(Intent.EXTRA_TEXT);
|
Optional<String> text = Optional.ofNullable(getIntent().getStringExtra(Intent.EXTRA_TEXT));
|
||||||
boolean isMastodonURL = UiUtils.looksLikeMastodonUrl(text);
|
Optional<Pair<String, Optional<String>>> fediHandle = text.flatMap(UiUtils::parseFediverseHandle);
|
||||||
|
boolean isFediUrl = text.map(UiUtils::looksLikeMastodonUrl).orElse(false);
|
||||||
|
boolean isOpenable = isFediUrl || fediHandle.isPresent();
|
||||||
|
|
||||||
List<AccountSession> sessions=AccountSessionManager.getInstance().getLoggedInAccounts();
|
List<AccountSession> sessions=AccountSessionManager.getInstance().getLoggedInAccounts();
|
||||||
if(sessions.isEmpty()){
|
if (sessions.isEmpty()){
|
||||||
Toast.makeText(this, R.string.err_not_logged_in, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, R.string.err_not_logged_in, Toast.LENGTH_SHORT).show();
|
||||||
finish();
|
finish();
|
||||||
}else if(sessions.size()==1 && !isMastodonURL){
|
} else if (isOpenable || sessions.size() > 1) {
|
||||||
|
AccountSwitcherSheet sheet = new AccountSwitcherSheet(this, null, true, isOpenable);
|
||||||
|
sheet.setOnClick((accountId, open) -> {
|
||||||
|
if (open && text.isPresent()) {
|
||||||
|
BiConsumer<Class<? extends Fragment>, Bundle> callback = (clazz, args) -> {
|
||||||
|
if (clazz == null) {
|
||||||
|
Toast.makeText(this, R.string.sk_open_in_app_failed, Toast.LENGTH_SHORT).show();
|
||||||
|
// TODO: do something about the window getting leaked
|
||||||
|
sheet.dismiss();
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
args.putString("fromExternalShare", clazz.getSimpleName());
|
||||||
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
|
intent.putExtras(args);
|
||||||
|
finish();
|
||||||
|
startActivity(intent);
|
||||||
|
};
|
||||||
|
|
||||||
|
fediHandle
|
||||||
|
.<MastodonAPIRequest<?>>map(handle ->
|
||||||
|
UiUtils.lookupAccountHandle(this, accountId, handle, callback))
|
||||||
|
.or(() ->
|
||||||
|
UiUtils.lookupURL(this, accountId, text.get(), callback))
|
||||||
|
.ifPresent(req ->
|
||||||
|
req.wrapProgress(this, R.string.loading, true, d -> {
|
||||||
|
UiUtils.transformDialogForLookup(this, accountId, isFediUrl ? text.get() : null, d);
|
||||||
|
d.setOnDismissListener((ev) -> finish());
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
openComposeFragment(accountId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sheet.show();
|
||||||
|
} else if (sessions.size() == 1) {
|
||||||
openComposeFragment(sessions.get(0).getID());
|
openComposeFragment(sessions.get(0).getID());
|
||||||
}else{
|
|
||||||
new AccountSwitcherSheet(this, false, false, isMastodonURL, accountSession -> {
|
|
||||||
if(accountSession!=null)
|
|
||||||
openComposeFragment(accountSession.getID());
|
|
||||||
else
|
|
||||||
UiUtils.openURL(this, AccountSessionManager.getInstance().getLastActiveAccountID(), text);
|
|
||||||
}).show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,11 +140,4 @@ public class ExternalShareActivity extends FragmentStackActivity{
|
|||||||
return null;
|
return null;
|
||||||
return new ArrayList<>(l);
|
return new ArrayList<>(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onProvideAssistContent(AssistContent outContent) {
|
|
||||||
super.onProvideAssistContent(outContent);
|
|
||||||
|
|
||||||
outContent.setWebUri(Uri.parse(DomainManager.getInstance().getCurrentDomain()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import android.os.Build;
|
|||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.model.ContentType;
|
||||||
import org.joinmastodon.android.model.TimelineDefinition;
|
import org.joinmastodon.android.model.TimelineDefinition;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
@@ -30,14 +31,14 @@ public class GlobalUserPreferences{
|
|||||||
public static boolean alwaysExpandContentWarnings;
|
public static boolean alwaysExpandContentWarnings;
|
||||||
public static boolean disableMarquee;
|
public static boolean disableMarquee;
|
||||||
public static boolean disableSwipe;
|
public static boolean disableSwipe;
|
||||||
public static boolean disableDividers;
|
public static boolean showDividers;
|
||||||
public static boolean voteButtonForSingleChoice;
|
public static boolean voteButtonForSingleChoice;
|
||||||
public static boolean uniformNotificationIcon;
|
|
||||||
public static boolean enableDeleteNotifications;
|
public static boolean enableDeleteNotifications;
|
||||||
|
public static boolean translateButtonOpenedOnly;
|
||||||
|
public static boolean uniformNotificationIcon;
|
||||||
public static boolean relocatePublishButton;
|
public static boolean relocatePublishButton;
|
||||||
public static boolean reduceMotion;
|
public static boolean reduceMotion;
|
||||||
public static boolean keepOnlyLatestNotification;
|
public static boolean keepOnlyLatestNotification;
|
||||||
public static boolean enableFabAutoHide;
|
|
||||||
public static boolean disableAltTextReminder;
|
public static boolean disableAltTextReminder;
|
||||||
public static boolean showAltIndicator;
|
public static boolean showAltIndicator;
|
||||||
public static boolean showNoAltIndicator;
|
public static boolean showNoAltIndicator;
|
||||||
@@ -48,23 +49,28 @@ public class GlobalUserPreferences{
|
|||||||
public static boolean spectatorMode;
|
public static boolean spectatorMode;
|
||||||
public static boolean autoHideFab;
|
public static boolean autoHideFab;
|
||||||
public static boolean defaultToUnlistedReplies;
|
public static boolean defaultToUnlistedReplies;
|
||||||
public static boolean disableDoubleTapToSwipe;
|
public static boolean doubleTapToSwipe;
|
||||||
public static boolean compactReblogReplyLine;
|
public static boolean compactReblogReplyLine;
|
||||||
public static boolean confirmBeforeReblog;
|
public static boolean confirmBeforeReblog;
|
||||||
public static boolean replyLineAboveHeader;
|
public static boolean replyLineAboveHeader;
|
||||||
public static boolean swapBookmarkWithBoostAction;
|
public static boolean swapBookmarkWithBoostAction;
|
||||||
public static boolean loadRemoteAccountFollowers;
|
public static boolean loadRemoteAccountFollowers;
|
||||||
public static boolean mentionRebloggerAutomatically;
|
public static boolean mentionRebloggerAutomatically;
|
||||||
|
public static boolean allowRemoteLoading;
|
||||||
|
public static AutoRevealMode autoRevealEqualSpoilers;
|
||||||
public static String publishButtonText;
|
public static String publishButtonText;
|
||||||
public static ThemePreference theme;
|
public static ThemePreference theme;
|
||||||
public static ColorPreference color;
|
public static ColorPreference color;
|
||||||
|
|
||||||
private final static Type recentLanguagesType = new TypeToken<Map<String, List<String>>>() {}.getType();
|
private final static Type recentLanguagesType = new TypeToken<Map<String, List<String>>>() {}.getType();
|
||||||
private final static Type pinnedTimelinesType = new TypeToken<Map<String, List<TimelineDefinition>>>() {}.getType();
|
private final static Type pinnedTimelinesType = new TypeToken<Map<String, List<TimelineDefinition>>>() {}.getType();
|
||||||
|
private final static Type accountsDefaultContentTypesType = new TypeToken<Map<String, ContentType>>() {}.getType();
|
||||||
public static Map<String, List<String>> recentLanguages;
|
public static Map<String, List<String>> recentLanguages;
|
||||||
public static Map<String, List<TimelineDefinition>> pinnedTimelines;
|
public static Map<String, List<TimelineDefinition>> pinnedTimelines;
|
||||||
public static Set<String> accountsWithLocalOnlySupport;
|
public static Set<String> accountsWithLocalOnlySupport;
|
||||||
public static Set<String> accountsInGlitchMode;
|
public static Set<String> accountsInGlitchMode;
|
||||||
|
public static Set<String> accountsWithContentTypesEnabled;
|
||||||
|
public static Map<String, ContentType> accountsDefaultContentTypes;
|
||||||
|
|
||||||
private final static Type recentEmojisType = new TypeToken<Map<String, Integer>>() {}.getType();
|
private final static Type recentEmojisType = new TypeToken<Map<String, Integer>>() {}.getType();
|
||||||
public static Map<String, Integer> recentEmojis;
|
public static Map<String, Integer> recentEmojis;
|
||||||
@@ -74,7 +80,6 @@ public class GlobalUserPreferences{
|
|||||||
*/
|
*/
|
||||||
public static String replyVisibility;
|
public static String replyVisibility;
|
||||||
|
|
||||||
|
|
||||||
public static SharedPreferences getPrefs(){
|
public static SharedPreferences getPrefs(){
|
||||||
return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE);
|
return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE);
|
||||||
}
|
}
|
||||||
@@ -85,6 +90,16 @@ public class GlobalUserPreferences{
|
|||||||
catch (JsonSyntaxException ignored) { return orElse; }
|
catch (JsonSyntaxException ignored) { return orElse; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void removeAccount(String accountId) {
|
||||||
|
recentLanguages.remove(accountId);
|
||||||
|
pinnedTimelines.remove(accountId);
|
||||||
|
accountsInGlitchMode.remove(accountId);
|
||||||
|
accountsWithLocalOnlySupport.remove(accountId);
|
||||||
|
accountsWithContentTypesEnabled.remove(accountId);
|
||||||
|
accountsDefaultContentTypes.remove(accountId);
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
public static void load(){
|
public static void load(){
|
||||||
SharedPreferences prefs=getPrefs();
|
SharedPreferences prefs=getPrefs();
|
||||||
playGifs=prefs.getBoolean("playGifs", true);
|
playGifs=prefs.getBoolean("playGifs", true);
|
||||||
@@ -99,13 +114,14 @@ public class GlobalUserPreferences{
|
|||||||
alwaysExpandContentWarnings=prefs.getBoolean("alwaysExpandContentWarnings", false);
|
alwaysExpandContentWarnings=prefs.getBoolean("alwaysExpandContentWarnings", false);
|
||||||
disableMarquee=prefs.getBoolean("disableMarquee", false);
|
disableMarquee=prefs.getBoolean("disableMarquee", false);
|
||||||
disableSwipe=prefs.getBoolean("disableSwipe", false);
|
disableSwipe=prefs.getBoolean("disableSwipe", false);
|
||||||
disableDividers=prefs.getBoolean("disableDividers", true);
|
showDividers =prefs.getBoolean("showDividers", false);
|
||||||
relocatePublishButton=prefs.getBoolean("relocatePublishButton", true);
|
relocatePublishButton=prefs.getBoolean("relocatePublishButton", true);
|
||||||
voteButtonForSingleChoice=prefs.getBoolean("voteButtonForSingleChoice", true);
|
voteButtonForSingleChoice=prefs.getBoolean("voteButtonForSingleChoice", true);
|
||||||
enableDeleteNotifications=prefs.getBoolean("enableDeleteNotifications", false);
|
enableDeleteNotifications=prefs.getBoolean("enableDeleteNotifications", false);
|
||||||
|
translateButtonOpenedOnly=prefs.getBoolean("translateButtonOpenedOnly", false);
|
||||||
|
uniformNotificationIcon=prefs.getBoolean("uniformNotificationIcon", false);
|
||||||
reduceMotion=prefs.getBoolean("reduceMotion", false);
|
reduceMotion=prefs.getBoolean("reduceMotion", false);
|
||||||
keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false);
|
keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false);
|
||||||
enableFabAutoHide=prefs.getBoolean("enableFabAutoHide", true);
|
|
||||||
disableAltTextReminder=prefs.getBoolean("disableAltTextReminder", false);
|
disableAltTextReminder=prefs.getBoolean("disableAltTextReminder", false);
|
||||||
showAltIndicator=prefs.getBoolean("showAltIndicator", true);
|
showAltIndicator=prefs.getBoolean("showAltIndicator", true);
|
||||||
showNoAltIndicator=prefs.getBoolean("showNoAltIndicator", true);
|
showNoAltIndicator=prefs.getBoolean("showNoAltIndicator", true);
|
||||||
@@ -117,7 +133,7 @@ public class GlobalUserPreferences{
|
|||||||
autoHideFab=prefs.getBoolean("autoHideFab", true);
|
autoHideFab=prefs.getBoolean("autoHideFab", true);
|
||||||
compactReblogReplyLine=prefs.getBoolean("compactReblogReplyLine", true);
|
compactReblogReplyLine=prefs.getBoolean("compactReblogReplyLine", true);
|
||||||
defaultToUnlistedReplies=prefs.getBoolean("defaultToUnlistedReplies", false);
|
defaultToUnlistedReplies=prefs.getBoolean("defaultToUnlistedReplies", false);
|
||||||
disableDoubleTapToSwipe=prefs.getBoolean("disableDoubleTapToSwipe", false);
|
doubleTapToSwipe =prefs.getBoolean("doubleTapToSwipe", true);
|
||||||
replyLineAboveHeader=prefs.getBoolean("replyLineAboveHeader", true);
|
replyLineAboveHeader=prefs.getBoolean("replyLineAboveHeader", true);
|
||||||
compactReblogReplyLine=prefs.getBoolean("compactReblogReplyLine", true);
|
compactReblogReplyLine=prefs.getBoolean("compactReblogReplyLine", true);
|
||||||
confirmBeforeReblog=prefs.getBoolean("confirmBeforeReblog", false);
|
confirmBeforeReblog=prefs.getBoolean("confirmBeforeReblog", false);
|
||||||
@@ -133,6 +149,10 @@ public class GlobalUserPreferences{
|
|||||||
accountsWithLocalOnlySupport=prefs.getStringSet("accountsWithLocalOnlySupport", new HashSet<>());
|
accountsWithLocalOnlySupport=prefs.getStringSet("accountsWithLocalOnlySupport", new HashSet<>());
|
||||||
accountsInGlitchMode=prefs.getStringSet("accountsInGlitchMode", new HashSet<>());
|
accountsInGlitchMode=prefs.getStringSet("accountsInGlitchMode", new HashSet<>());
|
||||||
replyVisibility=prefs.getString("replyVisibility", null);
|
replyVisibility=prefs.getString("replyVisibility", null);
|
||||||
|
accountsWithContentTypesEnabled=prefs.getStringSet("accountsWithContentTypesEnabled", new HashSet<>());
|
||||||
|
accountsDefaultContentTypes=fromJson(prefs.getString("accountsDefaultContentTypes", null), accountsDefaultContentTypesType, new HashMap<>());
|
||||||
|
allowRemoteLoading=prefs.getBoolean("allowRemoteLoading", true);
|
||||||
|
autoRevealEqualSpoilers=AutoRevealMode.valueOf(prefs.getString("autoRevealEqualSpoilers", AutoRevealMode.THREADS.name()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
|
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
|
||||||
@@ -159,13 +179,12 @@ public class GlobalUserPreferences{
|
|||||||
.putBoolean("alwaysExpandContentWarnings", alwaysExpandContentWarnings)
|
.putBoolean("alwaysExpandContentWarnings", alwaysExpandContentWarnings)
|
||||||
.putBoolean("disableMarquee", disableMarquee)
|
.putBoolean("disableMarquee", disableMarquee)
|
||||||
.putBoolean("disableSwipe", disableSwipe)
|
.putBoolean("disableSwipe", disableSwipe)
|
||||||
.putBoolean("disableDividers", disableDividers)
|
.putBoolean("showDividers", showDividers)
|
||||||
.putBoolean("relocatePublishButton", relocatePublishButton)
|
.putBoolean("relocatePublishButton", relocatePublishButton)
|
||||||
.putBoolean("uniformNotificationIcon", uniformNotificationIcon)
|
.putBoolean("uniformNotificationIcon", uniformNotificationIcon)
|
||||||
.putBoolean("enableDeleteNotifications", enableDeleteNotifications)
|
.putBoolean("enableDeleteNotifications", enableDeleteNotifications)
|
||||||
.putBoolean("reduceMotion", reduceMotion)
|
.putBoolean("reduceMotion", reduceMotion)
|
||||||
.putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification)
|
.putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification)
|
||||||
.putBoolean("enableFabAutoHide", enableFabAutoHide)
|
|
||||||
.putBoolean("disableAltTextReminder", disableAltTextReminder)
|
.putBoolean("disableAltTextReminder", disableAltTextReminder)
|
||||||
.putBoolean("showAltIndicator", showAltIndicator)
|
.putBoolean("showAltIndicator", showAltIndicator)
|
||||||
.putBoolean("showNoAltIndicator", showNoAltIndicator)
|
.putBoolean("showNoAltIndicator", showNoAltIndicator)
|
||||||
@@ -174,10 +193,11 @@ public class GlobalUserPreferences{
|
|||||||
.putBoolean("collapseLongPosts", collapseLongPosts)
|
.putBoolean("collapseLongPosts", collapseLongPosts)
|
||||||
.putBoolean("spectatorMode", spectatorMode)
|
.putBoolean("spectatorMode", spectatorMode)
|
||||||
.putBoolean("autoHideFab", autoHideFab)
|
.putBoolean("autoHideFab", autoHideFab)
|
||||||
|
.putBoolean("compactReblogReplyLine", compactReblogReplyLine)
|
||||||
.putString("publishButtonText", publishButtonText)
|
.putString("publishButtonText", publishButtonText)
|
||||||
.putBoolean("bottomEncoding", bottomEncoding)
|
.putBoolean("bottomEncoding", bottomEncoding)
|
||||||
.putBoolean("defaultToUnlistedReplies", defaultToUnlistedReplies)
|
.putBoolean("defaultToUnlistedReplies", defaultToUnlistedReplies)
|
||||||
.putBoolean("disableDoubleTapToSwipe", disableDoubleTapToSwipe)
|
.putBoolean("doubleTapToSwipe", doubleTapToSwipe)
|
||||||
.putBoolean("compactReblogReplyLine", compactReblogReplyLine)
|
.putBoolean("compactReblogReplyLine", compactReblogReplyLine)
|
||||||
.putBoolean("replyLineAboveHeader", replyLineAboveHeader)
|
.putBoolean("replyLineAboveHeader", replyLineAboveHeader)
|
||||||
.putBoolean("confirmBeforeReblog", confirmBeforeReblog)
|
.putBoolean("confirmBeforeReblog", confirmBeforeReblog)
|
||||||
@@ -192,6 +212,10 @@ public class GlobalUserPreferences{
|
|||||||
.putStringSet("accountsWithLocalOnlySupport", accountsWithLocalOnlySupport)
|
.putStringSet("accountsWithLocalOnlySupport", accountsWithLocalOnlySupport)
|
||||||
.putStringSet("accountsInGlitchMode", accountsInGlitchMode)
|
.putStringSet("accountsInGlitchMode", accountsInGlitchMode)
|
||||||
.putString("replyVisibility", replyVisibility)
|
.putString("replyVisibility", replyVisibility)
|
||||||
|
.putStringSet("accountsWithContentTypesEnabled", accountsWithContentTypesEnabled)
|
||||||
|
.putString("accountsDefaultContentTypes", gson.toJson(accountsDefaultContentTypes))
|
||||||
|
.putBoolean("allowRemoteLoading", allowRemoteLoading)
|
||||||
|
.putString("autoRevealEqualSpoilers", autoRevealEqualSpoilers.name())
|
||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,5 +236,10 @@ public class GlobalUserPreferences{
|
|||||||
LIGHT,
|
LIGHT,
|
||||||
DARK
|
DARK
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
public enum AutoRevealMode {
|
||||||
|
NEVER,
|
||||||
|
THREADS,
|
||||||
|
DISCUSSIONS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,18 +1,28 @@
|
|||||||
package org.joinmastodon.android;
|
package org.joinmastodon.android;
|
||||||
|
|
||||||
|
import static org.joinmastodon.android.fragments.ComposeFragment.CAMERA_PERMISSION_CODE;
|
||||||
|
import static org.joinmastodon.android.fragments.ComposeFragment.CAMERA_PIC_REQUEST_CODE;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.assist.AssistContent;
|
import android.app.assist.AssistContent;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.MediaStore;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.ObjectValidationException;
|
import org.joinmastodon.android.api.ObjectValidationException;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSession;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
|
import org.joinmastodon.android.events.PictureTakenEvent;
|
||||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||||
import org.joinmastodon.android.fragments.HomeFragment;
|
import org.joinmastodon.android.fragments.HomeFragment;
|
||||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||||
@@ -22,13 +32,13 @@ import org.joinmastodon.android.fragments.onboarding.CustomWelcomeFragment;
|
|||||||
import org.joinmastodon.android.model.Notification;
|
import org.joinmastodon.android.model.Notification;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
||||||
|
import org.joinmastodon.android.utils.ProvidesAssistContent;
|
||||||
import org.parceler.Parcels;
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import me.grishka.appkit.FragmentStackActivity;
|
import me.grishka.appkit.FragmentStackActivity;
|
||||||
|
|
||||||
public class MainActivity extends FragmentStackActivity{
|
public class MainActivity extends FragmentStackActivity implements ProvidesAssistContent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState){
|
protected void onCreate(@Nullable Bundle savedInstanceState){
|
||||||
UiUtils.setUserPreferredTheme(this);
|
UiUtils.setUserPreferredTheme(this);
|
||||||
@@ -38,10 +48,18 @@ public class MainActivity extends FragmentStackActivity{
|
|||||||
if(AccountSessionManager.getInstance().getLoggedInAccounts().isEmpty()){
|
if(AccountSessionManager.getInstance().getLoggedInAccounts().isEmpty()){
|
||||||
showFragmentClearingBackStack(new CustomWelcomeFragment());
|
showFragmentClearingBackStack(new CustomWelcomeFragment());
|
||||||
}else{
|
}else{
|
||||||
AccountSessionManager.getInstance().maybeUpdateLocalInfo();
|
|
||||||
AccountSession session;
|
AccountSession session;
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
Intent intent=getIntent();
|
Intent intent=getIntent();
|
||||||
|
if(intent.hasExtra("fromExternalShare")) {
|
||||||
|
AccountSessionManager.getInstance()
|
||||||
|
.setLastActiveAccountID(intent.getStringExtra("account"));
|
||||||
|
AccountSessionManager.getInstance().maybeUpdateLocalInfo(
|
||||||
|
AccountSessionManager.getInstance().getLastActiveAccount());
|
||||||
|
showFragmentForExternalShare(intent.getExtras());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean fromNotification = intent.getBooleanExtra("fromNotification", false);
|
boolean fromNotification = intent.getBooleanExtra("fromNotification", false);
|
||||||
boolean hasNotification = intent.hasExtra("notification");
|
boolean hasNotification = intent.hasExtra("notification");
|
||||||
if(fromNotification){
|
if(fromNotification){
|
||||||
@@ -55,6 +73,7 @@ public class MainActivity extends FragmentStackActivity{
|
|||||||
}else{
|
}else{
|
||||||
session=AccountSessionManager.getInstance().getLastActiveAccount();
|
session=AccountSessionManager.getInstance().getLastActiveAccount();
|
||||||
}
|
}
|
||||||
|
AccountSessionManager.getInstance().maybeUpdateLocalInfo(session);
|
||||||
args.putString("account", session.getID());
|
args.putString("account", session.getID());
|
||||||
Fragment fragment=session.activated ? new HomeFragment() : new AccountActivationFragment();
|
Fragment fragment=session.activated ? new HomeFragment() : new AccountActivationFragment();
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
@@ -78,12 +97,12 @@ public class MainActivity extends FragmentStackActivity{
|
|||||||
@Override
|
@Override
|
||||||
protected void onNewIntent(Intent intent){
|
protected void onNewIntent(Intent intent){
|
||||||
super.onNewIntent(intent);
|
super.onNewIntent(intent);
|
||||||
if(intent.getBooleanExtra("fromNotification", false)){
|
AccountSessionManager.getInstance().maybeUpdateLocalInfo();
|
||||||
|
if (intent.hasExtra("fromExternalShare")) showFragmentForExternalShare(intent.getExtras());
|
||||||
|
else if (intent.getBooleanExtra("fromNotification", false)) {
|
||||||
String accountID=intent.getStringExtra("accountID");
|
String accountID=intent.getStringExtra("accountID");
|
||||||
AccountSession accountSession;
|
|
||||||
try{
|
try{
|
||||||
accountSession=AccountSessionManager.getInstance().getAccount(accountID);
|
AccountSessionManager.getInstance().getAccount(accountID);
|
||||||
DomainManager.getInstance().setCurrentDomain(accountSession.domain);
|
|
||||||
}catch(IllegalStateException x){
|
}catch(IllegalStateException x){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -107,23 +126,24 @@ public class MainActivity extends FragmentStackActivity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void showFragmentForNotification(Notification notification, String accountID){
|
private void showFragmentForNotification(Notification notification, String accountID){
|
||||||
Fragment fragment;
|
|
||||||
Bundle args=new Bundle();
|
|
||||||
args.putString("account", accountID);
|
|
||||||
args.putBoolean("_can_go_back", true);
|
|
||||||
try{
|
try{
|
||||||
notification.postprocess();
|
notification.postprocess();
|
||||||
}catch(ObjectValidationException x){
|
}catch(ObjectValidationException x){
|
||||||
Log.w("MainActivity", x);
|
Log.w("MainActivity", x);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(notification.status!=null){
|
UiUtils.showFragmentForNotification(this, notification, accountID, null);
|
||||||
fragment=new ThreadFragment();
|
}
|
||||||
args.putParcelable("status", Parcels.wrap(notification.status));
|
|
||||||
}else{
|
private void showFragmentForExternalShare(Bundle args) {
|
||||||
fragment=new ProfileFragment();
|
String className = args.getString("fromExternalShare");
|
||||||
args.putParcelable("profileAccount", Parcels.wrap(notification.account));
|
Fragment fragment = switch (className) {
|
||||||
}
|
case "ThreadFragment" -> new ThreadFragment();
|
||||||
|
case "ProfileFragment" -> new ProfileFragment();
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
if (fragment == null) return;
|
||||||
|
args.putBoolean("_can_go_back", true);
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
showFragment(fragment);
|
showFragment(fragment);
|
||||||
}
|
}
|
||||||
@@ -157,25 +177,61 @@ public class MainActivity extends FragmentStackActivity{
|
|||||||
(fragmentContainers.get(fragmentContainers.size() - 1)).getId()
|
(fragmentContainers.get(fragmentContainers.size() - 1)).getId()
|
||||||
);
|
);
|
||||||
Bundle currentArgs = currentFragment.getArguments();
|
Bundle currentArgs = currentFragment.getArguments();
|
||||||
if (this.fragmentContainers.size() == 1
|
if (fragmentContainers.size() != 1
|
||||||
&& currentArgs != null
|
|| currentArgs == null
|
||||||
&& currentArgs.getBoolean("_can_go_back", false)
|
|| !currentArgs.getBoolean("_can_go_back", false)) {
|
||||||
&& currentArgs.containsKey("account")) {
|
super.onBackPressed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentArgs.getBoolean("_finish_on_back", false)) {
|
||||||
|
finish();
|
||||||
|
} else if (currentArgs.containsKey("account")) {
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString("account", currentArgs.getString("account"));
|
args.putString("account", currentArgs.getString("account"));
|
||||||
args.putString("tab", "notifications");
|
if (getIntent().getBooleanExtra("fromNotification", false)) {
|
||||||
|
args.putString("tab", "notifications");
|
||||||
|
}
|
||||||
Fragment fragment=new HomeFragment();
|
Fragment fragment=new HomeFragment();
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
showFragmentClearingBackStack(fragment);
|
showFragmentClearingBackStack(fragment);
|
||||||
} else {
|
|
||||||
super.onBackPressed();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public void onProvideAssistContent(AssistContent outContent) {
|
|
||||||
super.onProvideAssistContent(outContent);
|
|
||||||
|
|
||||||
outContent.setWebUri(Uri.parse(DomainManager.getInstance().getCurrentDomain()));
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data){
|
||||||
|
if(requestCode==CAMERA_PIC_REQUEST_CODE && resultCode== Activity.RESULT_OK){
|
||||||
|
Bitmap image = (Bitmap) data.getExtras().get("data");
|
||||||
|
String path = MediaStore.Images.Media.insertImage(this.getContentResolver(), image, null, null);
|
||||||
|
E.post(new PictureTakenEvent(Uri.parse(path)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
|
||||||
|
if (requestCode == CAMERA_PERMISSION_CODE && (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
|
||||||
|
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||||
|
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST_CODE);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, R.string.permission_required, Toast.LENGTH_SHORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Fragment getCurrentFragment() {
|
||||||
|
for (int i = fragmentContainers.size() - 1; i >= 0; i--) {
|
||||||
|
FrameLayout fl = fragmentContainers.get(i);
|
||||||
|
if (fl.getVisibility() == View.VISIBLE) {
|
||||||
|
return getFragmentManager().findFragmentById(fl.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProvideAssistContent(AssistContent assistContent) {
|
||||||
|
super.onProvideAssistContent(assistContent);
|
||||||
|
Fragment fragment = getCurrentFragment();
|
||||||
|
if (fragment != null) callFragmentToProvideAssistContent(fragment, assistContent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import android.content.Intent;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.accounts.GetOwnAccount;
|
import org.joinmastodon.android.api.requests.accounts.GetOwnAccount;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.oauth.GetOauthToken;
|
import org.joinmastodon.android.api.requests.oauth.GetOauthToken;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
import org.joinmastodon.android.model.Application;
|
import org.joinmastodon.android.model.Application;
|
||||||
import org.joinmastodon.android.model.Instance;
|
import org.joinmastodon.android.model.Instance;
|
||||||
@@ -60,6 +61,9 @@ public class OAuthActivity extends Activity{
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(Token token){
|
public void onSuccess(Token token){
|
||||||
new GetOwnAccount()
|
new GetOwnAccount()
|
||||||
|
// in case the instance (looking at pixelfed) wants to redirect to a
|
||||||
|
// website, we need to pass a context so we can launch a browser
|
||||||
|
.setContext(OAuthActivity.this)
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Account account){
|
public void onSuccess(Account account){
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.joinmastodon.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.requests.oauth.RevokeOauthToken;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
|
|
||||||
|
import me.grishka.appkit.api.Callback;
|
||||||
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
|
||||||
|
|
||||||
|
public class PanicResponderActivity extends Activity {
|
||||||
|
public static final String PANIC_TRIGGER_ACTION = "info.guardianproject.panic.action.TRIGGER";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
final Intent intent = getIntent();
|
||||||
|
if (intent != null && PANIC_TRIGGER_ACTION.equals(intent.getAction())) {
|
||||||
|
AccountSessionManager.getInstance().getLoggedInAccounts().forEach(accountSession -> logOut(accountSession.getID()));
|
||||||
|
ExitActivity.exit(this);
|
||||||
|
}
|
||||||
|
finishAndRemoveTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logOut(String accountID){
|
||||||
|
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||||
|
new RevokeOauthToken(session.app.clientId, session.app.clientSecret, session.token.accessToken)
|
||||||
|
.setCallback(new Callback<>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Object result){
|
||||||
|
onLoggedOut(accountID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse error){
|
||||||
|
onLoggedOut(accountID);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.exec(accountID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onLoggedOut(String accountID){
|
||||||
|
AccountSessionManager.getInstance().removeAccount(accountID);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,29 +12,34 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.opengl.Visibility;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIController;
|
import org.joinmastodon.android.api.MastodonAPIController;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.accounts.SetAccountFollowed;
|
import org.joinmastodon.android.api.requests.accounts.SetAccountFollowed;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.notifications.GetNotificationByID;
|
import org.joinmastodon.android.api.requests.notifications.GetNotificationByID;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.statuses.CreateStatus;
|
import org.joinmastodon.android.api.requests.statuses.CreateStatus;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.statuses.SetStatusBookmarked;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusBookmarked;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.statuses.SetStatusFavorited;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusFavorited;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.statuses.SetStatusReblogged;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusReblogged;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSession;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.events.NotificationReceivedEvent;
|
import org.joinmastodon.android.events.NotificationReceivedEvent;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
import org.joinmastodon.android.model.Mention;
|
||||||
import org.joinmastodon.android.model.NotificationAction;
|
import org.joinmastodon.android.model.NotificationAction;
|
||||||
import org.joinmastodon.android.model.Preferences;
|
import org.joinmastodon.android.model.Preferences;
|
||||||
import org.joinmastodon.android.model.PushNotification;
|
import org.joinmastodon.android.model.PushNotification;
|
||||||
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.joinmastodon.android.model.StatusPrivacy;
|
||||||
import org.joinmastodon.android.model.StatusPrivacy;
|
import org.joinmastodon.android.model.StatusPrivacy;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.parceler.Parcels;
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -54,7 +59,7 @@ public class PushNotificationReceiver extends BroadcastReceiver{
|
|||||||
private static final String ACTION_KEY_TEXT_REPLY = "ACTION_KEY_TEXT_REPLY";
|
private static final String ACTION_KEY_TEXT_REPLY = "ACTION_KEY_TEXT_REPLY";
|
||||||
|
|
||||||
private static final int SUMMARY_ID = 791;
|
private static final int SUMMARY_ID = 791;
|
||||||
private static int notificationId;
|
private static int notificationId = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent){
|
public void onReceive(Context context, Intent intent){
|
||||||
@@ -295,27 +300,60 @@ public class PushNotificationReceiver extends BroadcastReceiver{
|
|||||||
}
|
}
|
||||||
CharSequence input = remoteInput.getCharSequence(ACTION_KEY_TEXT_REPLY);
|
CharSequence input = remoteInput.getCharSequence(ACTION_KEY_TEXT_REPLY);
|
||||||
|
|
||||||
|
// copied from ComposeFragment - TODO: generalize?
|
||||||
|
ArrayList<String> mentions=new ArrayList<>();
|
||||||
|
Status status = notification.status;
|
||||||
|
String ownID=AccountSessionManager.getInstance().getAccount(accountID).self.id;
|
||||||
|
if(!status.account.id.equals(ownID))
|
||||||
|
mentions.add('@'+status.account.acct);
|
||||||
|
for(Mention mention:status.mentions){
|
||||||
|
if(mention.id.equals(ownID))
|
||||||
|
continue;
|
||||||
|
String m='@'+mention.acct;
|
||||||
|
if(!mentions.contains(m))
|
||||||
|
mentions.add(m);
|
||||||
|
}
|
||||||
|
String initialText=mentions.isEmpty() ? "" : TextUtils.join(" ", mentions)+" ";
|
||||||
|
|
||||||
CreateStatus.Request req=new CreateStatus.Request();
|
CreateStatus.Request req=new CreateStatus.Request();
|
||||||
req.status = input.toString() + "\n\n" + "@" + notification.status.account.acct;
|
req.status = initialText + input.toString();
|
||||||
req.language = notification.status.language;
|
req.language = preferences.postingDefaultLanguage;
|
||||||
req.visibility = (notification.status.visibility == StatusPrivacy.PUBLIC && GlobalUserPreferences.defaultToUnlistedReplies ? StatusPrivacy.UNLISTED : notification.status.visibility);
|
req.visibility = preferences.postingDefaultVisibility;
|
||||||
req.inReplyToId = notification.status.id;
|
req.inReplyToId = notification.status.id;
|
||||||
if(!notification.status.spoilerText.isEmpty() && GlobalUserPreferences.prefixRepliesWithRe && !notification.status.spoilerText.startsWith("re: ")){
|
if(!notification.status.spoilerText.isEmpty() && GlobalUserPreferences.prefixRepliesWithRe && !notification.status.spoilerText.startsWith("re: ")){
|
||||||
req.spoilerText = "re: " + notification.status.spoilerText;
|
req.spoilerText = "re: " + notification.status.spoilerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
new CreateStatus(req, UUID.randomUUID().toString()).exec(accountID);
|
new CreateStatus(req, UUID.randomUUID().toString()).setCallback(new Callback<>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Status status) {
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
Notification.Builder builder = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O ?
|
||||||
|
new Notification.Builder(context, accountID+"_"+notification.type) :
|
||||||
|
new Notification.Builder(context)
|
||||||
|
.setPriority(Notification.PRIORITY_DEFAULT)
|
||||||
|
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
|
||||||
|
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
notification.status = status;
|
||||||
Notification.Builder builder = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O ?
|
Intent contentIntent=new Intent(context, MainActivity.class);
|
||||||
new Notification.Builder(context, accountID+"_"+notification.type) :
|
contentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
new Notification.Builder(context)
|
contentIntent.putExtra("fromNotification", true);
|
||||||
.setPriority(Notification.PRIORITY_DEFAULT)
|
contentIntent.putExtra("accountID", accountID);
|
||||||
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
|
contentIntent.putExtra("notification", Parcels.wrap(notification));
|
||||||
|
|
||||||
Notification repliedNotification = builder.setSmallIcon(R.drawable.ic_ntf_logo)
|
Notification repliedNotification = builder.setSmallIcon(R.drawable.ic_ntf_logo)
|
||||||
.setContentText(context.getString(R.string.mo_notification_action_replied, notification.status.account.getDisplayUsername()))
|
.setContentTitle(context.getString(R.string.sk_notification_action_replied, notification.status.account.displayName))
|
||||||
.build();
|
.setContentText(status.getStrippedText())
|
||||||
notificationManager.notify(accountID, notificationId, repliedNotification);
|
.setCategory(Notification.CATEGORY_SOCIAL)
|
||||||
|
.setContentIntent(PendingIntent.getActivity(context, notificationId, contentIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT))
|
||||||
|
.build();
|
||||||
|
notificationManager.notify(accountID, notificationId, repliedNotification);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse errorResponse) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}).exec(accountID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,10 +11,10 @@ import android.util.Log;
|
|||||||
|
|
||||||
import org.joinmastodon.android.BuildConfig;
|
import org.joinmastodon.android.BuildConfig;
|
||||||
import org.joinmastodon.android.MastodonApp;
|
import org.joinmastodon.android.MastodonApp;
|
||||||
import org.joinmastodon.android.api.adapter.ApiAdapter;
|
import org.joinmastodon.android.api.requests.notifications.GetNotifications;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.notifications.GetNotifications;
|
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSession;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.model.CacheablePaginatedResponse;
|
import org.joinmastodon.android.model.CacheablePaginatedResponse;
|
||||||
import org.joinmastodon.android.model.Filter;
|
import org.joinmastodon.android.model.Filter;
|
||||||
import org.joinmastodon.android.model.Instance;
|
import org.joinmastodon.android.model.Instance;
|
||||||
@@ -36,7 +36,7 @@ import me.grishka.appkit.utils.WorkerThread;
|
|||||||
|
|
||||||
public class CacheController{
|
public class CacheController{
|
||||||
private static final String TAG="CacheController";
|
private static final String TAG="CacheController";
|
||||||
private static final int DB_VERSION=3;
|
private static final int DB_VERSION=4;
|
||||||
private static final WorkerThread databaseThread=new WorkerThread("databaseThread");
|
private static final WorkerThread databaseThread=new WorkerThread("databaseThread");
|
||||||
private static final Handler uiHandler=new Handler(Looper.getMainLooper());
|
private static final Handler uiHandler=new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ public class CacheController{
|
|||||||
List<Filter> filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(Filter.FilterContext.HOME)).collect(Collectors.toList());
|
List<Filter> filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(Filter.FilterContext.HOME)).collect(Collectors.toList());
|
||||||
if(!forceReload){
|
if(!forceReload){
|
||||||
SQLiteDatabase db=getOrOpenDatabase();
|
SQLiteDatabase db=getOrOpenDatabase();
|
||||||
try(Cursor cursor=db.query("home_timeline", new String[]{"json", "flags"}, maxID==null ? null : "`id`<?", maxID==null ? null : new String[]{maxID}, null, null, "`id` DESC", count+"")){
|
try(Cursor cursor=db.query("home_timeline", new String[]{"json", "flags"}, maxID==null ? null : "`id`<?", maxID==null ? null : new String[]{maxID}, null, null, "`time` DESC", count+"")){
|
||||||
if(cursor.getCount()==count){
|
if(cursor.getCount()==count){
|
||||||
ArrayList<Status> result=new ArrayList<>();
|
ArrayList<Status> result=new ArrayList<>();
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
@@ -73,10 +73,8 @@ public class CacheController{
|
|||||||
int flags=cursor.getInt(1);
|
int flags=cursor.getInt(1);
|
||||||
status.hasGapAfter=((flags & POST_FLAG_GAP_AFTER)!=0);
|
status.hasGapAfter=((flags & POST_FLAG_GAP_AFTER)!=0);
|
||||||
newMaxID=status.id;
|
newMaxID=status.id;
|
||||||
for(Filter filter:filters){
|
if (!new StatusFilterPredicate(filters, Filter.FilterContext.HOME).test(status))
|
||||||
if(filter.matches(status))
|
continue outer;
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
result.add(status);
|
result.add(status);
|
||||||
}while(cursor.moveToNext());
|
}while(cursor.moveToNext());
|
||||||
String _newMaxID=newMaxID;
|
String _newMaxID=newMaxID;
|
||||||
@@ -87,12 +85,11 @@ public class CacheController{
|
|||||||
Log.w(TAG, "getHomeTimeline: corrupted status object in database", x);
|
Log.w(TAG, "getHomeTimeline: corrupted status object in database", x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ApiAdapter apiAdapter = new ApiAdapter(ApiAdapter.ServerType.MASTODON);
|
new GetHomeTimeline(maxID, null, count, null)
|
||||||
apiAdapter.getHomeTimeline(maxID, null, count, null)
|
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<Status> result){
|
public void onSuccess(List<Status> result){
|
||||||
callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(new StatusFilterPredicate(filters)).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false));
|
callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(new StatusFilterPredicate(filters, Filter.FilterContext.HOME)).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false));
|
||||||
putHomeTimeline(result, maxID==null);
|
putHomeTimeline(result, maxID==null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +112,7 @@ public class CacheController{
|
|||||||
runOnDbThread((db)->{
|
runOnDbThread((db)->{
|
||||||
if(clear)
|
if(clear)
|
||||||
db.delete("home_timeline", null, null);
|
db.delete("home_timeline", null, null);
|
||||||
ContentValues values=new ContentValues(3);
|
ContentValues values=new ContentValues(4);
|
||||||
for(Status s:posts){
|
for(Status s:posts){
|
||||||
values.put("id", s.id);
|
values.put("id", s.id);
|
||||||
values.put("json", MastodonAPIController.gson.toJson(s));
|
values.put("json", MastodonAPIController.gson.toJson(s));
|
||||||
@@ -123,6 +120,7 @@ public class CacheController{
|
|||||||
if(s.hasGapAfter)
|
if(s.hasGapAfter)
|
||||||
flags|=POST_FLAG_GAP_AFTER;
|
flags|=POST_FLAG_GAP_AFTER;
|
||||||
values.put("flags", flags);
|
values.put("flags", flags);
|
||||||
|
values.put("time", s.createdAt.getEpochSecond());
|
||||||
db.insertWithOnConflict("home_timeline", null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
db.insertWithOnConflict("home_timeline", null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -137,7 +135,7 @@ public class CacheController{
|
|||||||
if(!forceReload){
|
if(!forceReload){
|
||||||
SQLiteDatabase db=getOrOpenDatabase();
|
SQLiteDatabase db=getOrOpenDatabase();
|
||||||
String table=onlyPosts ? "notifications_posts" : onlyMentions ? "notifications_mentions" : "notifications_all";
|
String table=onlyPosts ? "notifications_posts" : onlyMentions ? "notifications_mentions" : "notifications_all";
|
||||||
try(Cursor cursor=db.query(table, new String[]{"json"}, maxID==null ? null : "`id`<?", maxID==null ? null : new String[]{maxID}, null, null, "`id` DESC", count+"")){
|
try(Cursor cursor=db.query(table, new String[]{"json"}, maxID==null ? null : "`id`<?", maxID==null ? null : new String[]{maxID}, null, null, "`time` DESC", count+"")){
|
||||||
if(cursor.getCount()==count){
|
if(cursor.getCount()==count){
|
||||||
ArrayList<Notification> result=new ArrayList<>();
|
ArrayList<Notification> result=new ArrayList<>();
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
@@ -148,10 +146,8 @@ public class CacheController{
|
|||||||
ntf.postprocess();
|
ntf.postprocess();
|
||||||
newMaxID=ntf.id;
|
newMaxID=ntf.id;
|
||||||
if(ntf.status!=null){
|
if(ntf.status!=null){
|
||||||
for(Filter filter:filters){
|
if (!new StatusFilterPredicate(filters, Filter.FilterContext.NOTIFICATIONS).test(ntf.status))
|
||||||
if(filter.matches(ntf.status))
|
continue outer;
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result.add(ntf);
|
result.add(ntf);
|
||||||
}while(cursor.moveToNext());
|
}while(cursor.moveToNext());
|
||||||
@@ -164,17 +160,13 @@ public class CacheController{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instance instance=AccountSessionManager.getInstance().getInstanceInfo(accountSession.domain);
|
Instance instance=AccountSessionManager.getInstance().getInstanceInfo(accountSession.domain);
|
||||||
new GetNotifications(maxID, count, onlyPosts ? EnumSet.of(Notification.Type.STATUS) : onlyMentions ? EnumSet.of(Notification.Type.MENTION): EnumSet.allOf(Notification.Type.class), instance.pleroma != null)
|
new GetNotifications(maxID, count, onlyPosts ? EnumSet.of(Notification.Type.STATUS) : onlyMentions ? EnumSet.of(Notification.Type.MENTION): EnumSet.allOf(Notification.Type.class), instance.isAkkoma())
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<Notification> result){
|
public void onSuccess(List<Notification> result){
|
||||||
callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(ntf->{
|
callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(ntf->{
|
||||||
if(ntf.status!=null){
|
if(ntf.status!=null){
|
||||||
for(Filter filter:filters){
|
return new StatusFilterPredicate(filters, Filter.FilterContext.NOTIFICATIONS).test(ntf.status);
|
||||||
if(filter.matches(ntf.status)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false));
|
}).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false));
|
||||||
@@ -201,7 +193,7 @@ public class CacheController{
|
|||||||
String table=onlyPosts ? "notifications_posts" : onlyMentions ? "notifications_mentions" : "notifications_all";
|
String table=onlyPosts ? "notifications_posts" : onlyMentions ? "notifications_mentions" : "notifications_all";
|
||||||
if(clear)
|
if(clear)
|
||||||
db.delete(table, null, null);
|
db.delete(table, null, null);
|
||||||
ContentValues values=new ContentValues(3);
|
ContentValues values=new ContentValues(4);
|
||||||
for(Notification n:notifications){
|
for(Notification n:notifications){
|
||||||
if(n.type==null){
|
if(n.type==null){
|
||||||
continue;
|
continue;
|
||||||
@@ -209,6 +201,7 @@ public class CacheController{
|
|||||||
values.put("id", n.id);
|
values.put("id", n.id);
|
||||||
values.put("json", MastodonAPIController.gson.toJson(n));
|
values.put("json", MastodonAPIController.gson.toJson(n));
|
||||||
values.put("type", n.type.ordinal());
|
values.put("type", n.type.ordinal());
|
||||||
|
values.put("time", n.createdAt.getEpochSecond());
|
||||||
db.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
db.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -305,21 +298,24 @@ public class CacheController{
|
|||||||
CREATE TABLE `home_timeline` (
|
CREATE TABLE `home_timeline` (
|
||||||
`id` VARCHAR(25) NOT NULL PRIMARY KEY,
|
`id` VARCHAR(25) NOT NULL PRIMARY KEY,
|
||||||
`json` TEXT NOT NULL,
|
`json` TEXT NOT NULL,
|
||||||
`flags` INTEGER NOT NULL DEFAULT 0
|
`flags` INTEGER NOT NULL DEFAULT 0,
|
||||||
|
`time` INTEGER NOT NULL
|
||||||
)""");
|
)""");
|
||||||
db.execSQL("""
|
db.execSQL("""
|
||||||
CREATE TABLE `notifications_all` (
|
CREATE TABLE `notifications_all` (
|
||||||
`id` VARCHAR(25) NOT NULL PRIMARY KEY,
|
`id` VARCHAR(25) NOT NULL PRIMARY KEY,
|
||||||
`json` TEXT NOT NULL,
|
`json` TEXT NOT NULL,
|
||||||
`flags` INTEGER NOT NULL DEFAULT 0,
|
`flags` INTEGER NOT NULL DEFAULT 0,
|
||||||
`type` INTEGER NOT NULL
|
`type` INTEGER NOT NULL,
|
||||||
|
`time` INTEGER NOT NULL
|
||||||
)""");
|
)""");
|
||||||
db.execSQL("""
|
db.execSQL("""
|
||||||
CREATE TABLE `notifications_mentions` (
|
CREATE TABLE `notifications_mentions` (
|
||||||
`id` VARCHAR(25) NOT NULL PRIMARY KEY,
|
`id` VARCHAR(25) NOT NULL PRIMARY KEY,
|
||||||
`json` TEXT NOT NULL,
|
`json` TEXT NOT NULL,
|
||||||
`flags` INTEGER NOT NULL DEFAULT 0,
|
`flags` INTEGER NOT NULL DEFAULT 0,
|
||||||
`type` INTEGER NOT NULL
|
`type` INTEGER NOT NULL,
|
||||||
|
`time` INTEGER NOT NULL
|
||||||
)""");
|
)""");
|
||||||
createRecentSearchesTable(db);
|
createRecentSearchesTable(db);
|
||||||
createPostsNotificationsTable(db);
|
createPostsNotificationsTable(db);
|
||||||
@@ -327,12 +323,16 @@ public class CacheController{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
|
||||||
if(oldVersion==1){
|
if(oldVersion<2){
|
||||||
createRecentSearchesTable(db);
|
createRecentSearchesTable(db);
|
||||||
}
|
}
|
||||||
if(oldVersion==2){
|
if(oldVersion<3){
|
||||||
|
// MEGALODON-SPECIFIC
|
||||||
createPostsNotificationsTable(db);
|
createPostsNotificationsTable(db);
|
||||||
}
|
}
|
||||||
|
if(oldVersion<4){
|
||||||
|
addTimeColumns(db);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createRecentSearchesTable(SQLiteDatabase db){
|
private void createRecentSearchesTable(SQLiteDatabase db){
|
||||||
@@ -350,9 +350,21 @@ public class CacheController{
|
|||||||
`id` VARCHAR(25) NOT NULL PRIMARY KEY,
|
`id` VARCHAR(25) NOT NULL PRIMARY KEY,
|
||||||
`json` TEXT NOT NULL,
|
`json` TEXT NOT NULL,
|
||||||
`flags` INTEGER NOT NULL DEFAULT 0,
|
`flags` INTEGER NOT NULL DEFAULT 0,
|
||||||
`type` INTEGER NOT NULL
|
`type` INTEGER NOT NULL,
|
||||||
|
`time` INTEGER NOT NULL
|
||||||
)""");
|
)""");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addTimeColumns(SQLiteDatabase db){
|
||||||
|
db.execSQL("DELETE FROM `home_timeline`");
|
||||||
|
db.execSQL("DELETE FROM `notifications_all`");
|
||||||
|
db.execSQL("DELETE FROM `notifications_mentions`");
|
||||||
|
db.execSQL("DELETE FROM `notifications_posts`");
|
||||||
|
db.execSQL("ALTER TABLE `home_timeline` ADD `time` INTEGER NOT NULL DEFAULT 0");
|
||||||
|
db.execSQL("ALTER TABLE `notifications_all` ADD `time` INTEGER NOT NULL DEFAULT 0");
|
||||||
|
db.execSQL("ALTER TABLE `notifications_mentions` ADD `time` INTEGER NOT NULL DEFAULT 0");
|
||||||
|
db.execSQL("ALTER TABLE `notifications_posts` ADD `time` INTEGER NOT NULL DEFAULT 0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ import org.joinmastodon.android.BuildConfig;
|
|||||||
import org.joinmastodon.android.MastodonApp;
|
import org.joinmastodon.android.MastodonApp;
|
||||||
import org.joinmastodon.android.api.gson.IsoInstantTypeAdapter;
|
import org.joinmastodon.android.api.gson.IsoInstantTypeAdapter;
|
||||||
import org.joinmastodon.android.api.gson.IsoLocalDateTypeAdapter;
|
import org.joinmastodon.android.api.gson.IsoLocalDateTypeAdapter;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSession;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -28,6 +29,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -51,7 +53,9 @@ public class MastodonAPIController{
|
|||||||
.registerTypeAdapter(Status.class, new Status.StatusDeserializer())
|
.registerTypeAdapter(Status.class, new Status.StatusDeserializer())
|
||||||
.create();
|
.create();
|
||||||
private static WorkerThread thread=new WorkerThread("MastodonAPIController");
|
private static WorkerThread thread=new WorkerThread("MastodonAPIController");
|
||||||
private static OkHttpClient httpClient=new OkHttpClient.Builder().build();
|
private static OkHttpClient httpClient=new OkHttpClient.Builder()
|
||||||
|
.readTimeout(5, TimeUnit.MINUTES)
|
||||||
|
.build();
|
||||||
|
|
||||||
private AccountSession session;
|
private AccountSession session;
|
||||||
private static List<String> badDomains = new ArrayList<>();
|
private static List<String> badDomains = new ArrayList<>();
|
||||||
@@ -60,7 +64,7 @@ public class MastodonAPIController{
|
|||||||
thread.start();
|
thread.start();
|
||||||
try {
|
try {
|
||||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(
|
final BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||||
MastodonApp.context.getAssets().open("blocks.tsv")
|
MastodonApp.context.getAssets().open("blocks.txt")
|
||||||
));
|
));
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
@@ -91,7 +95,7 @@ public class MastodonAPIController{
|
|||||||
Request.Builder builder=new Request.Builder()
|
Request.Builder builder=new Request.Builder()
|
||||||
.url(req.getURL().toString())
|
.url(req.getURL().toString())
|
||||||
.method(req.getMethod(), req.getRequestBody())
|
.method(req.getMethod(), req.getRequestBody())
|
||||||
.header("User-Agent", "MastodonAndroid/"+BuildConfig.VERSION_NAME);
|
.header("User-Agent", "MoshidonAndroid/"+BuildConfig.VERSION_NAME);
|
||||||
|
|
||||||
String token=null;
|
String token=null;
|
||||||
if(session!=null)
|
if(session!=null)
|
||||||
@@ -158,6 +162,11 @@ public class MastodonAPIController{
|
|||||||
respObj=gson.fromJson(reader, req.respClass);
|
respObj=gson.fromJson(reader, req.respClass);
|
||||||
}
|
}
|
||||||
}catch(JsonIOException|JsonSyntaxException x){
|
}catch(JsonIOException|JsonSyntaxException x){
|
||||||
|
if (req.context != null && response.body().contentType().subtype().equals("html")) {
|
||||||
|
UiUtils.launchWebBrowser(req.context, response.request().url().toString());
|
||||||
|
req.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(BuildConfig.DEBUG)
|
if(BuildConfig.DEBUG)
|
||||||
Log.w(TAG, "["+(session==null ? "no-auth" : session.getID())+"] "+response+" error parsing or reading body", x);
|
Log.w(TAG, "["+(session==null ? "no-auth" : session.getID())+"] "+response+" error parsing or reading body", x);
|
||||||
req.onError(x.getLocalizedMessage(), response.code(), x);
|
req.onError(x.getLocalizedMessage(), response.code(), x);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.joinmastodon.android.api;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
@@ -9,8 +10,8 @@ import android.util.Pair;
|
|||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.BuildConfig;
|
import org.joinmastodon.android.BuildConfig;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSession;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.model.BaseModel;
|
import org.joinmastodon.android.model.BaseModel;
|
||||||
import org.joinmastodon.android.model.Token;
|
import org.joinmastodon.android.model.Token;
|
||||||
|
|
||||||
@@ -20,9 +21,11 @@ import java.util.HashMap;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import me.grishka.appkit.api.APIRequest;
|
import me.grishka.appkit.api.APIRequest;
|
||||||
import me.grishka.appkit.api.Callback;
|
import me.grishka.appkit.api.Callback;
|
||||||
@@ -44,10 +47,11 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
|
|||||||
TypeToken<T> respTypeToken;
|
TypeToken<T> respTypeToken;
|
||||||
Call okhttpCall;
|
Call okhttpCall;
|
||||||
Token token;
|
Token token;
|
||||||
boolean canceled;
|
boolean canceled, isRemote;
|
||||||
Map<String, String> headers;
|
Map<String, String> headers;
|
||||||
private ProgressDialog progressDialog;
|
private ProgressDialog progressDialog;
|
||||||
protected boolean removeUnsupportedItems;
|
protected boolean removeUnsupportedItems;
|
||||||
|
@Nullable Context context;
|
||||||
|
|
||||||
public MastodonAPIRequest(HttpMethod method, String path, Class<T> respClass){
|
public MastodonAPIRequest(HttpMethod method, String path, Class<T> respClass){
|
||||||
this.path=path;
|
this.path=path;
|
||||||
@@ -101,6 +105,21 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MastodonAPIRequest<T> execRemote(String domain) {
|
||||||
|
return execRemote(domain, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MastodonAPIRequest<T> execRemote(String domain, @Nullable AccountSession remoteSession) {
|
||||||
|
this.isRemote = true;
|
||||||
|
return Optional.ofNullable(remoteSession)
|
||||||
|
.or(() -> AccountSessionManager.getInstance().getLoggedInAccounts().stream()
|
||||||
|
.filter(acc -> acc.domain.equals(domain))
|
||||||
|
.findAny())
|
||||||
|
.map(AccountSession::getID)
|
||||||
|
.map(this::exec)
|
||||||
|
.orElse(this.execNoAuth(domain));
|
||||||
|
}
|
||||||
|
|
||||||
public MastodonAPIRequest<T> wrapProgress(Activity activity, @StringRes int message, boolean cancelable){
|
public MastodonAPIRequest<T> wrapProgress(Activity activity, @StringRes int message, boolean cancelable){
|
||||||
return wrapProgress(activity, message, cancelable, null);
|
return wrapProgress(activity, message, cancelable, null);
|
||||||
}
|
}
|
||||||
@@ -164,9 +183,20 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MastodonAPIRequest<T> setContext(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
public void validateAndPostprocessResponse(T respObj, Response httpResponse) throws IOException{
|
public void validateAndPostprocessResponse(T respObj, Response httpResponse) throws IOException{
|
||||||
if(respObj instanceof BaseModel){
|
if(respObj instanceof BaseModel){
|
||||||
|
((BaseModel) respObj).isRemote = isRemote;
|
||||||
((BaseModel) respObj).postprocess();
|
((BaseModel) respObj).postprocess();
|
||||||
}else if(respObj instanceof List){
|
}else if(respObj instanceof List){
|
||||||
if(removeUnsupportedItems){
|
if(removeUnsupportedItems){
|
||||||
@@ -175,6 +205,7 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
|
|||||||
Object item=itr.next();
|
Object item=itr.next();
|
||||||
if(item instanceof BaseModel){
|
if(item instanceof BaseModel){
|
||||||
try{
|
try{
|
||||||
|
((BaseModel) item).isRemote = isRemote;
|
||||||
((BaseModel) item).postprocess();
|
((BaseModel) item).postprocess();
|
||||||
}catch(ObjectValidationException x){
|
}catch(ObjectValidationException x){
|
||||||
Log.w(TAG, "Removing invalid object from list", x);
|
Log.w(TAG, "Removing invalid object from list", x);
|
||||||
@@ -182,15 +213,20 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// no idea why we're post-processing twice, but well, as long
|
||||||
|
// as upstream does it like this, i don't wanna break anything
|
||||||
for(Object item:((List<?>) respObj)){
|
for(Object item:((List<?>) respObj)){
|
||||||
if(item instanceof BaseModel){
|
if(item instanceof BaseModel){
|
||||||
|
((BaseModel) item).isRemote = isRemote;
|
||||||
((BaseModel) item).postprocess();
|
((BaseModel) item).postprocess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
for(Object item:((List<?>) respObj)){
|
for(Object item:((List<?>) respObj)){
|
||||||
if(item instanceof BaseModel)
|
if(item instanceof BaseModel) {
|
||||||
|
((BaseModel) item).isRemote = isRemote;
|
||||||
((BaseModel) item).postprocess();
|
((BaseModel) item).postprocess();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ import android.util.Log;
|
|||||||
|
|
||||||
import org.joinmastodon.android.BuildConfig;
|
import org.joinmastodon.android.BuildConfig;
|
||||||
import org.joinmastodon.android.MastodonApp;
|
import org.joinmastodon.android.MastodonApp;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.notifications.RegisterForPushNotifications;
|
import org.joinmastodon.android.api.requests.notifications.RegisterForPushNotifications;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.notifications.UpdatePushSettings;
|
import org.joinmastodon.android.api.requests.notifications.UpdatePushSettings;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSession;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.model.PushNotification;
|
import org.joinmastodon.android.model.PushNotification;
|
||||||
import org.joinmastodon.android.model.PushSubscription;
|
import org.joinmastodon.android.model.PushSubscription;
|
||||||
|
|
||||||
@@ -45,6 +45,7 @@ import javax.crypto.IllegalBlockSizeException;
|
|||||||
import javax.crypto.KeyAgreement;
|
import javax.crypto.KeyAgreement;
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.NoSuchPaddingException;
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
import javax.crypto.spec.GCMParameterSpec;
|
import javax.crypto.spec.GCMParameterSpec;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import android.os.Looper;
|
|||||||
|
|
||||||
import org.joinmastodon.android.E;
|
import org.joinmastodon.android.E;
|
||||||
import org.joinmastodon.android.MastodonApp;
|
import org.joinmastodon.android.MastodonApp;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.statuses.SetStatusBookmarked;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusBookmarked;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.statuses.SetStatusFavorited;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusFavorited;
|
||||||
import org.joinmastodon.android.api.mastodon.requests.statuses.SetStatusReblogged;
|
import org.joinmastodon.android.api.requests.statuses.SetStatusReblogged;
|
||||||
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.model.StatusPrivacy;
|
import org.joinmastodon.android.model.StatusPrivacy;
|
||||||
@@ -46,7 +46,7 @@ public class StatusInteractionController{
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(Status result){
|
public void onSuccess(Status result){
|
||||||
runningFavoriteRequests.remove(status.id);
|
runningFavoriteRequests.remove(status.id);
|
||||||
result.favouritesCount = Math.max(0, status.favouritesCount) + (favorited ? 1 : -1);
|
result.favouritesCount = Math.max(0, status.favouritesCount + (favorited ? 1 : -1));
|
||||||
cb.accept(result);
|
cb.accept(result);
|
||||||
if (updateCounters) E.post(new StatusCountersUpdatedEvent(result));
|
if (updateCounters) E.post(new StatusCountersUpdatedEvent(result));
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ public class StatusInteractionController{
|
|||||||
public void onSuccess(Status reblog){
|
public void onSuccess(Status reblog){
|
||||||
Status result = reblog.getContentStatus();
|
Status result = reblog.getContentStatus();
|
||||||
runningReblogRequests.remove(status.id);
|
runningReblogRequests.remove(status.id);
|
||||||
result.reblogsCount = Math.max(0, status.reblogsCount) + (reblogged ? 1 : -1);
|
result.reblogsCount = Math.max(0, status.reblogsCount + (reblogged ? 1 : -1));
|
||||||
cb.accept(result);
|
cb.accept(result);
|
||||||
if (updateCounters) E.post(new StatusCountersUpdatedEvent(result));
|
if (updateCounters) E.post(new StatusCountersUpdatedEvent(result));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package org.joinmastodon.android.api.adapter;
|
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.statuses.GetStatusByID;
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.timelines.GetHomeTimeline;
|
|
||||||
import org.joinmastodon.android.model.Status;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ApiAdapter {
|
|
||||||
public final ServerType serverType;
|
|
||||||
|
|
||||||
public ApiAdapter(ServerType serverType){
|
|
||||||
this.serverType = serverType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MastodonAPIRequest<?> getPostById(String id){
|
|
||||||
switch (serverType){
|
|
||||||
case MASTODON -> {
|
|
||||||
return new GetStatusByID(id);
|
|
||||||
}
|
|
||||||
case MISSKEY -> {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MastodonAPIRequest<List<Status>> getHomeTimeline(String maxID, String minID, int limit, String sinceID){
|
|
||||||
switch (serverType){
|
|
||||||
case MASTODON -> {
|
|
||||||
return new GetHomeTimeline(maxID, minID, limit, sinceID);
|
|
||||||
}
|
|
||||||
case MISSKEY -> {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public enum ServerType {
|
|
||||||
MASTODON,
|
|
||||||
MISSKEY,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.timelines;
|
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
|
|
||||||
import org.joinmastodon.android.GlobalUserPreferences;
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
|
||||||
import org.joinmastodon.android.model.Status;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class GetHomeTimeline extends MastodonAPIRequest<List<Status>>{
|
|
||||||
public GetHomeTimeline(String maxID, String minID, int limit, String sinceID){
|
|
||||||
super(HttpMethod.GET, "/timelines/home", new TypeToken<>(){});
|
|
||||||
if(maxID!=null)
|
|
||||||
addQueryParameter("max_id", maxID);
|
|
||||||
if(minID!=null)
|
|
||||||
addQueryParameter("min_id", minID);
|
|
||||||
if(sinceID!=null)
|
|
||||||
addQueryParameter("since_id", sinceID);
|
|
||||||
if(limit>0)
|
|
||||||
addQueryParameter("limit", ""+limit);
|
|
||||||
if(GlobalUserPreferences.replyVisibility != null)
|
|
||||||
addQueryParameter("reply_visibility", GlobalUserPreferences.replyVisibility);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests;
|
package org.joinmastodon.android.api.requests;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
|
||||||
public class GetAccountByHandle extends MastodonAPIRequest<Account>{
|
public class GetAccountByHandle extends MastodonAPIRequest<Account>{
|
||||||
|
/**
|
||||||
|
* note that this method usually only returns a result if the instance already knows about an
|
||||||
|
* account - so it makes sense for looking up local users, search might be preferred otherwise
|
||||||
|
*/
|
||||||
public GetAccountByHandle(String acct){
|
public GetAccountByHandle(String acct){
|
||||||
super(HttpMethod.GET, "/accounts/lookup", Account.class);
|
super(HttpMethod.GET, "/accounts/lookup", Account.class);
|
||||||
addQueryParameter("acct", acct);
|
addQueryParameter("acct", acct);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.HeaderPaginationRequest;
|
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
|
||||||
public class GetAccountFollowers extends HeaderPaginationRequest<Account>{
|
public class GetAccountFollowers extends HeaderPaginationRequest<Account>{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.HeaderPaginationRequest;
|
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
|
||||||
public class GetAccountFollowing extends HeaderPaginationRequest<Account>{
|
public class GetAccountFollowing extends HeaderPaginationRequest<Account>{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.HeaderPaginationRequest;
|
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
|
||||||
public class GetFollowRequests extends HeaderPaginationRequest<Account>{
|
public class GetFollowRequests extends HeaderPaginationRequest<Account>{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Preferences;
|
import org.joinmastodon.android.model.Preferences;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Token;
|
import org.joinmastodon.android.model.Token;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.accounts;
|
package org.joinmastodon.android.api.requests.accounts;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.announcements;
|
package org.joinmastodon.android.api.requests.announcements;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.announcements;
|
package org.joinmastodon.android.api.requests.announcements;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.catalog;
|
package org.joinmastodon.android.api.requests.catalog;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.catalog;
|
package org.joinmastodon.android.api.requests.catalog;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.instance;
|
package org.joinmastodon.android.api.requests.instance;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.joinmastodon.android.api.requests.instance;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.model.DomainBlock;
|
||||||
|
import org.joinmastodon.android.model.ExtendedDescription;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GetDomainBlocks extends MastodonAPIRequest<List<DomainBlock>>{
|
||||||
|
public GetDomainBlocks(){
|
||||||
|
super(HttpMethod.GET, "/instance/domain_blocks", new TypeToken<>(){});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.joinmastodon.android.api.requests.instance;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.model.ExtendedDescription;
|
||||||
|
import org.joinmastodon.android.model.Instance;
|
||||||
|
|
||||||
|
public class GetExtendedDescription extends MastodonAPIRequest<ExtendedDescription>{
|
||||||
|
public GetExtendedDescription(){
|
||||||
|
super(HttpMethod.GET, "/instance/extended_description", ExtendedDescription.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.instance;
|
package org.joinmastodon.android.api.requests.instance;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Instance;
|
import org.joinmastodon.android.model.Instance;
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.joinmastodon.android.api.requests.instance;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.model.WeeklyActivity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GetWeeklyActivity extends MastodonAPIRequest<List<WeeklyActivity>>{
|
||||||
|
public GetWeeklyActivity(){
|
||||||
|
super(HttpMethod.GET, "/instance/activity", new TypeToken<>(){});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.ListTimeline;
|
import org.joinmastodon.android.model.ListTimeline;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.ListTimeline;
|
import org.joinmastodon.android.model.ListTimeline;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.ListTimeline;
|
import org.joinmastodon.android.model.ListTimeline;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.lists;
|
package org.joinmastodon.android.api.requests.lists;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.ListTimeline;
|
import org.joinmastodon.android.model.ListTimeline;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.markers;
|
package org.joinmastodon.android.api.requests.markers;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.ApiUtils;
|
import org.joinmastodon.android.api.ApiUtils;
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.markers;
|
package org.joinmastodon.android.api.requests.markers;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.api.gson.JsonObjectBuilder;
|
import org.joinmastodon.android.api.gson.JsonObjectBuilder;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.notifications;
|
package org.joinmastodon.android.api.requests.notifications;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.notifications;
|
package org.joinmastodon.android.api.requests.notifications;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Notification;
|
import org.joinmastodon.android.model.Notification;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.notifications;
|
package org.joinmastodon.android.api.requests.notifications;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.joinmastodon.android.api.requests.notifications;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.model.Notification;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
|
||||||
|
public class PleromaMarkNotificationsRead extends MastodonAPIRequest<List<Notification>> {
|
||||||
|
private String maxID;
|
||||||
|
public PleromaMarkNotificationsRead(String maxID) {
|
||||||
|
super(HttpMethod.POST, "/pleroma/notifications/read", new TypeToken<>(){});
|
||||||
|
this.maxID = maxID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequestBody getRequestBody() {
|
||||||
|
MultipartBody.Builder builder=new MultipartBody.Builder()
|
||||||
|
.setType(MultipartBody.FORM);
|
||||||
|
if(!TextUtils.isEmpty(maxID))
|
||||||
|
builder.addFormDataPart("max_id", maxID);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.notifications;
|
package org.joinmastodon.android.api.requests.notifications;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.PushSubscription;
|
import org.joinmastodon.android.model.PushSubscription;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.notifications;
|
package org.joinmastodon.android.api.requests.notifications;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.PushSubscription;
|
import org.joinmastodon.android.model.PushSubscription;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.oauth;
|
package org.joinmastodon.android.api.requests.oauth;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.model.Application;
|
import org.joinmastodon.android.model.Application;
|
||||||
|
|
||||||
public class CreateOAuthApp extends MastodonAPIRequest<Application>{
|
public class CreateOAuthApp extends MastodonAPIRequest<Application>{
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.oauth;
|
package org.joinmastodon.android.api.requests.oauth;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.api.mastodon.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.model.Token;
|
import org.joinmastodon.android.model.Token;
|
||||||
|
|
||||||
public class GetOauthToken extends MastodonAPIRequest<Token>{
|
public class GetOauthToken extends MastodonAPIRequest<Token>{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.oauth;
|
package org.joinmastodon.android.api.requests.oauth;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.polls;
|
package org.joinmastodon.android.api.requests.polls;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Poll;
|
import org.joinmastodon.android.model.Poll;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.reports;
|
package org.joinmastodon.android.api.requests.reports;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.ReportReason;
|
import org.joinmastodon.android.model.ReportReason;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.search;
|
package org.joinmastodon.android.api.requests.search;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.SearchResults;
|
import org.joinmastodon.android.model.SearchResults;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.model.ContentType;
|
||||||
import org.joinmastodon.android.model.ScheduledStatus;
|
import org.joinmastodon.android.model.ScheduledStatus;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.model.StatusPrivacy;
|
import org.joinmastodon.android.model.StatusPrivacy;
|
||||||
@@ -46,6 +47,7 @@ public class CreateStatus extends MastodonAPIRequest<Status>{
|
|||||||
public String language;
|
public String language;
|
||||||
|
|
||||||
public String quoteId;
|
public String quoteId;
|
||||||
|
public ContentType contentType;
|
||||||
|
|
||||||
public static class Poll{
|
public static class Poll{
|
||||||
public ArrayList<String> options=new ArrayList<>();
|
public ArrayList<String> options=new ArrayList<>();
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Attachment;
|
import org.joinmastodon.android.model.Attachment;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.HeaderPaginationRequest;
|
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
|
||||||
public class GetBookmarkedStatuses extends HeaderPaginationRequest<Status>{
|
public class GetBookmarkedStatuses extends HeaderPaginationRequest<Status>{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.HeaderPaginationRequest;
|
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
|
||||||
public class GetFavoritedStatuses extends HeaderPaginationRequest<Status>{
|
public class GetFavoritedStatuses extends HeaderPaginationRequest<Status>{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.HeaderPaginationRequest;
|
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||||
import org.joinmastodon.android.model.ScheduledStatus;
|
import org.joinmastodon.android.model.ScheduledStatus;
|
||||||
|
|
||||||
public class GetScheduledStatuses extends HeaderPaginationRequest<ScheduledStatus>{
|
public class GetScheduledStatuses extends HeaderPaginationRequest<ScheduledStatus>{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.StatusContext;
|
import org.joinmastodon.android.model.StatusContext;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.HeaderPaginationRequest;
|
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
|
||||||
public class GetStatusFavorites extends HeaderPaginationRequest<Account>{
|
public class GetStatusFavorites extends HeaderPaginationRequest<Account>{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.mastodon.requests.HeaderPaginationRequest;
|
import org.joinmastodon.android.api.requests.HeaderPaginationRequest;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
|
||||||
public class GetStatusReblogs extends HeaderPaginationRequest<Account>{
|
public class GetStatusReblogs extends HeaderPaginationRequest<Account>{
|
||||||
@@ -1,18 +1,23 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.api.RequiredField;
|
||||||
import org.joinmastodon.android.model.BaseModel;
|
import org.joinmastodon.android.model.BaseModel;
|
||||||
|
import org.joinmastodon.android.model.ContentType;
|
||||||
|
|
||||||
public class GetStatusSourceText extends MastodonAPIRequest<GetStatusSourceText.Response>{
|
public class GetStatusSourceText extends MastodonAPIRequest<GetStatusSourceText.Response>{
|
||||||
public GetStatusSourceText(String id){
|
public GetStatusSourceText(String id){
|
||||||
super(HttpMethod.GET, "/statuses/"+id+"/source", Response.class);
|
super(HttpMethod.GET, "/statuses/"+id+"/source", Response.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AllFieldsAreRequired
|
|
||||||
public static class Response extends BaseModel{
|
public static class Response extends BaseModel{
|
||||||
|
@RequiredField
|
||||||
public String id;
|
public String id;
|
||||||
|
@RequiredField
|
||||||
public String text;
|
public String text;
|
||||||
|
@RequiredField
|
||||||
public String spoilerText;
|
public String spoilerText;
|
||||||
|
public ContentType contentType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.joinmastodon.android.api.mastodon.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user