refactor: Break navigation dependency cycles with :core:navigation (#305)
The previous code generally started an activity by having the activity provide a method in a companion object that returns the relevant intent, possibly taking additional parameters that will be included in the intent as extras. E.g., if A wants to start B, B provides the method that returns the intent that starts B. This introduces a dependency between A and B. This is worse if B also wants to start A. For example, if A is `StatusListActivity` and B is`ViewThreadActivity`. The user might click a status in `StatusListActivity` to view the thread, starting `ViewThreadActivity`. But from the thread they might click a hashtag to view the list of statuses with that hashtag. Now `StatusListActivity` and `ViewThreadActivity` have a circular dependency. Even if that doesn't happen the dependency means that any changes to B will trigger a rebuild of A, even if the changes to B are not relevant. Break this dependency by adding a `:core:navigation` module with an `app.pachli.core.navigation` package that contains `Intent` subclasses that should be used instead. The `quadrant` plugin is used to generate constants that can be used to launch activities by name instead of by class, breaking the dependency chain. The plugin uses the `Activity` names from the manifest, so when an activity is moved in the future the constant will automatically update to reflect the new package name. If the activity's intent requires specific extras those are passed via the constructor, with companion object methods to extract them from the intent. Using the intent classes from this package is enforced by a lint `IntentDetector` which will warn if any intents are created using a class literal. See #291
This commit is contained in:
parent
b14972cb73
commit
1214cf7c8a
|
@ -135,6 +135,7 @@ dependencies {
|
|||
implementation(projects.core.accounts)
|
||||
implementation(projects.core.common)
|
||||
implementation(projects.core.database)
|
||||
implementation(projects.core.navigation)
|
||||
implementation(projects.core.network)
|
||||
implementation(projects.core.preferences)
|
||||
|
||||
|
|
|
@ -872,7 +872,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/account/AccountActivity.kt"
|
||||
line="479"
|
||||
line="484"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2049,7 +2049,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/AboutActivity.kt"
|
||||
line="74"
|
||||
line="75"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2060,7 +2060,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/AboutActivity.kt"
|
||||
line="75"
|
||||
line="76"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2071,7 +2071,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/AboutActivity.kt"
|
||||
line="76"
|
||||
line="77"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2082,7 +2082,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/account/AccountActivity.kt"
|
||||
line="367"
|
||||
line="372"
|
||||
column="29"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2093,7 +2093,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/account/AccountActivity.kt"
|
||||
line="370"
|
||||
line="375"
|
||||
column="29"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2104,7 +2104,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/account/AccountActivity.kt"
|
||||
line="376"
|
||||
line="381"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2115,7 +2115,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/account/AccountActivity.kt"
|
||||
line="377"
|
||||
line="382"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2126,7 +2126,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/account/AccountActivity.kt"
|
||||
line="379"
|
||||
line="384"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2137,7 +2137,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/account/AccountActivity.kt"
|
||||
line="389"
|
||||
line="394"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2148,7 +2148,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/accountlist/AccountListFragment.kt"
|
||||
line="138"
|
||||
line="145"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2159,7 +2159,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/preference/AccountPreferencesFragment.kt"
|
||||
line="308"
|
||||
line="318"
|
||||
column="29"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2170,7 +2170,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/preference/AccountPreferencesFragment.kt"
|
||||
line="314"
|
||||
line="324"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2335,7 +2335,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/compose/ComposeActivity.kt"
|
||||
line="547"
|
||||
line="549"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2346,7 +2346,7 @@
|
|||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/compose/ComposeActivity.kt"
|
||||
line="556"
|
||||
line="558"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2357,7 +2357,7 @@
|
|||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/compose/ComposeActivity.kt"
|
||||
line="556"
|
||||
line="558"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2445,7 +2445,7 @@
|
|||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/filters/EditFilterActivity.kt"
|
||||
line="116"
|
||||
line="119"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2456,7 +2456,7 @@
|
|||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/filters/EditFilterActivity.kt"
|
||||
line="116"
|
||||
line="119"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2467,7 +2467,7 @@
|
|||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/filters/EditFilterActivity.kt"
|
||||
line="126"
|
||||
line="129"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2478,7 +2478,7 @@
|
|||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/filters/EditFilterActivity.kt"
|
||||
line="126"
|
||||
line="129"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2731,7 +2731,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/ListsActivity.kt"
|
||||
line="265"
|
||||
line="264"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2742,7 +2742,7 @@
|
|||
errorLine2=" ~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/ListsActivity.kt"
|
||||
line="267"
|
||||
line="266"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2775,7 +2775,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/login/LoginActivity.kt"
|
||||
line="156"
|
||||
line="161"
|
||||
column="22"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2786,7 +2786,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/login/LoginWebViewActivity.kt"
|
||||
line="143"
|
||||
line="144"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2797,7 +2797,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/login/LoginWebViewActivity.kt"
|
||||
line="143"
|
||||
line="144"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2808,7 +2808,7 @@
|
|||
errorLine2=" ~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/login/LoginWebViewActivity.kt"
|
||||
line="152"
|
||||
line="153"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2819,7 +2819,7 @@
|
|||
errorLine2=" ~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/login/LoginWebViewActivity.kt"
|
||||
line="152"
|
||||
line="153"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2830,7 +2830,7 @@
|
|||
errorLine2=" ~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/login/LoginWebViewActivity.kt"
|
||||
line="173"
|
||||
line="174"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2841,7 +2841,7 @@
|
|||
errorLine2=" ~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/login/LoginWebViewActivity.kt"
|
||||
line="173"
|
||||
line="174"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2852,7 +2852,7 @@
|
|||
errorLine2=" ~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/login/LoginWebViewActivity.kt"
|
||||
line="176"
|
||||
line="177"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2863,7 +2863,7 @@
|
|||
errorLine2=" ~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/login/LoginWebViewActivity.kt"
|
||||
line="176"
|
||||
line="177"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2874,7 +2874,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="245"
|
||||
line="252"
|
||||
column="37"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2885,7 +2885,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="249"
|
||||
line="256"
|
||||
column="37"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2896,7 +2896,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="353"
|
||||
line="360"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2907,7 +2907,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="354"
|
||||
line="361"
|
||||
column="29"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2918,7 +2918,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="356"
|
||||
line="363"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2929,7 +2929,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="357"
|
||||
line="364"
|
||||
column="29"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2940,7 +2940,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="639"
|
||||
line="646"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2951,7 +2951,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="642"
|
||||
line="649"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2962,7 +2962,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="647"
|
||||
line="654"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2973,7 +2973,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="651"
|
||||
line="658"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2984,7 +2984,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="656"
|
||||
line="663"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -2995,7 +2995,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="659"
|
||||
line="666"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3006,7 +3006,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="664"
|
||||
line="671"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3017,29 +3017,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="667"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="SyntheticAccessor"
|
||||
message="Access to `private` method `primaryDrawerItem` of class `MainActivityKt` requires synthetic accessor"
|
||||
errorLine1=" primaryDrawerItem {"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="672"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="SyntheticAccessor"
|
||||
message="Access to `private` method `setOnClick` of class `MainActivityKt` requires synthetic accessor"
|
||||
errorLine1=" onClick = {"
|
||||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="675"
|
||||
line="674"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3072,7 +3050,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="687"
|
||||
line="686"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3083,7 +3061,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="690"
|
||||
line="689"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3105,18 +3083,18 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="698"
|
||||
line="697"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="SyntheticAccessor"
|
||||
message="Access to `private` method `secondaryDrawerItem` of class `MainActivityKt` requires synthetic accessor"
|
||||
errorLine1=" secondaryDrawerItem {"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
message="Access to `private` method `primaryDrawerItem` of class `MainActivityKt` requires synthetic accessor"
|
||||
errorLine1=" primaryDrawerItem {"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="707"
|
||||
line="701"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3127,7 +3105,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="710"
|
||||
line="705"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3138,7 +3116,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="715"
|
||||
line="714"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3149,7 +3127,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="718"
|
||||
line="717"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3160,7 +3138,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="723"
|
||||
line="725"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3171,7 +3149,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="726"
|
||||
line="728"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3182,7 +3160,29 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="731"
|
||||
line="733"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="SyntheticAccessor"
|
||||
message="Access to `private` method `setOnClick` of class `MainActivityKt` requires synthetic accessor"
|
||||
errorLine1=" onClick = {"
|
||||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="736"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="SyntheticAccessor"
|
||||
message="Access to `private` method `secondaryDrawerItem` of class `MainActivityKt` requires synthetic accessor"
|
||||
errorLine1=" secondaryDrawerItem {"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="741"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3193,7 +3193,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="734"
|
||||
line="744"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3204,7 +3204,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="741"
|
||||
line="751"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3215,7 +3215,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="744"
|
||||
line="754"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3226,7 +3226,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="753"
|
||||
line="763"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3237,7 +3237,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="756"
|
||||
line="766"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3248,7 +3248,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="769"
|
||||
line="779"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3259,7 +3259,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="773"
|
||||
line="783"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3270,7 +3270,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="898"
|
||||
line="908"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3281,7 +3281,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="900"
|
||||
line="910"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3292,7 +3292,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/MainActivity.kt"
|
||||
line="911"
|
||||
line="921"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3534,7 +3534,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/fragment/SFragment.kt"
|
||||
line="225"
|
||||
line="224"
|
||||
column="48"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3644,7 +3644,7 @@
|
|||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/components/timeline/TimelineFragment.kt"
|
||||
line="196"
|
||||
line="195"
|
||||
column="47"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3699,7 +3699,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/ViewMediaActivity.kt"
|
||||
line="125"
|
||||
line="127"
|
||||
column="21"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3710,7 +3710,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/ViewMediaActivity.kt"
|
||||
line="125"
|
||||
line="127"
|
||||
column="45"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3721,7 +3721,7 @@
|
|||
errorLine2=" ~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/ViewMediaActivity.kt"
|
||||
line="125"
|
||||
line="127"
|
||||
column="45"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3732,7 +3732,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/ViewMediaActivity.kt"
|
||||
line="155"
|
||||
line="157"
|
||||
column="45"/>
|
||||
</issue>
|
||||
|
||||
|
@ -3743,7 +3743,7 @@
|
|||
errorLine2=" ~~~~~~~">
|
||||
<location
|
||||
file="src/main/java/app/pachli/ViewMediaActivity.kt"
|
||||
line="200"
|
||||
line="202"
|
||||
column="25"/>
|
||||
</issue>
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package app.pachli
|
|||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.SpannableString
|
||||
|
@ -16,6 +15,8 @@ import android.widget.Toast
|
|||
import androidx.annotation.StringRes
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import app.pachli.components.instanceinfo.InstanceInfoRepository
|
||||
import app.pachli.core.navigation.LicenseActivityIntent
|
||||
import app.pachli.core.navigation.PrivacyPolicyActivityIntent
|
||||
import app.pachli.databinding.ActivityAboutBinding
|
||||
import app.pachli.util.NoUnderlineURLSpan
|
||||
import app.pachli.util.hide
|
||||
|
@ -76,8 +77,7 @@ class AboutActivity : BottomSheetActivity() {
|
|||
binding.aboutBugsFeaturesInfoTextView.setClickableTextWithoutUnderlines(R.string.about_bug_feature_request_site)
|
||||
|
||||
binding.aboutPrivacyPolicyTextView.setOnClickListener {
|
||||
val intent = Intent(this, PrivacyPolicyActivity::class.java)
|
||||
startActivity(intent)
|
||||
startActivity(PrivacyPolicyActivityIntent(this))
|
||||
}
|
||||
|
||||
binding.appProfileButton.setOnClickListener {
|
||||
|
@ -85,7 +85,7 @@ class AboutActivity : BottomSheetActivity() {
|
|||
}
|
||||
|
||||
binding.aboutLicensesButton.setOnClickListener {
|
||||
startActivityWithSlideInAnimation(Intent(this, LicenseActivity::class.java))
|
||||
startActivityWithSlideInAnimation(LicenseActivityIntent(this))
|
||||
}
|
||||
|
||||
binding.copyDeviceInfo.setOnClickListener {
|
||||
|
|
|
@ -34,9 +34,9 @@ import androidx.core.app.ActivityCompat
|
|||
import androidx.core.content.ContextCompat
|
||||
import app.pachli.MainActivity.Companion.redirectIntent
|
||||
import app.pachli.adapter.AccountSelectionAdapter
|
||||
import app.pachli.components.login.LoginActivity
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.navigation.LoginActivityIntent
|
||||
import app.pachli.core.preferences.PrefKeys
|
||||
import app.pachli.core.preferences.PrefKeys.APP_THEME
|
||||
import app.pachli.core.preferences.SharedPreferencesRepository
|
||||
|
@ -182,7 +182,7 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||
private fun redirectIfNotLoggedIn() {
|
||||
val account = accountManager.activeAccount
|
||||
if (account == null) {
|
||||
val intent = Intent(this, LoginActivity::class.java)
|
||||
val intent = LoginActivityIntent(this)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
finish()
|
||||
|
|
|
@ -17,15 +17,14 @@
|
|||
package app.pachli
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import app.pachli.components.account.AccountActivity
|
||||
import app.pachli.components.viewthread.ViewThreadActivity
|
||||
import app.pachli.core.navigation.AccountActivityIntent
|
||||
import app.pachli.core.navigation.ViewThreadActivityIntent
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import app.pachli.util.looksLikeMastodonUrl
|
||||
import app.pachli.util.openLink
|
||||
|
@ -104,15 +103,13 @@ abstract class BottomSheetActivity : BaseActivity() {
|
|||
|
||||
open fun viewThread(statusId: String, url: String?) {
|
||||
if (!isSearching()) {
|
||||
val intent = Intent(this, ViewThreadActivity::class.java)
|
||||
intent.putExtra("id", statusId)
|
||||
intent.putExtra("url", url)
|
||||
val intent = ViewThreadActivityIntent(this, statusId, url)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
}
|
||||
|
||||
open fun viewAccount(id: String) {
|
||||
val intent = AccountActivity.getIntent(this, id)
|
||||
val intent = AccountActivityIntent(this, id)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
package app.pachli
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -36,6 +34,7 @@ import androidx.recyclerview.widget.DiffUtil
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.network.model.MastoList
|
||||
import app.pachli.databinding.ActivityListsBinding
|
||||
import app.pachli.databinding.DialogListBinding
|
||||
|
@ -191,7 +190,7 @@ class ListsActivity : BaseActivity() {
|
|||
|
||||
private fun onListSelected(listId: String, listTitle: String) {
|
||||
startActivityWithSlideInAnimation(
|
||||
StatusListActivity.newListIntent(this, listId, listTitle),
|
||||
StatusListActivityIntent.list(this, listId, listTitle),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -277,8 +276,4 @@ class ListsActivity : BaseActivity() {
|
|||
viewModel.updateList(listId, name, exclusive)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newIntent(context: Context) = Intent(context, ListsActivity::class.java)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ import androidx.appcompat.app.AlertDialog
|
|||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
|
@ -61,24 +60,32 @@ import app.pachli.appstore.CacheUpdater
|
|||
import app.pachli.appstore.EventHub
|
||||
import app.pachli.appstore.MainTabsChangedEvent
|
||||
import app.pachli.appstore.ProfileEditedEvent
|
||||
import app.pachli.components.account.AccountActivity
|
||||
import app.pachli.components.accountlist.AccountListActivity
|
||||
import app.pachli.components.announcements.AnnouncementsActivity
|
||||
import app.pachli.components.compose.ComposeActivity
|
||||
import app.pachli.components.compose.ComposeActivity.Companion.canHandleMimeType
|
||||
import app.pachli.components.drafts.DraftsActivity
|
||||
import app.pachli.components.login.LoginActivity
|
||||
import app.pachli.components.notifications.createNotificationChannelsForAccount
|
||||
import app.pachli.components.notifications.disableAllNotifications
|
||||
import app.pachli.components.notifications.enablePushNotificationsWithFallback
|
||||
import app.pachli.components.notifications.notificationsAreEnabled
|
||||
import app.pachli.components.notifications.showMigrationNoticeIfNecessary
|
||||
import app.pachli.components.preference.PreferencesActivity
|
||||
import app.pachli.components.scheduled.ScheduledStatusActivity
|
||||
import app.pachli.components.search.SearchActivity
|
||||
import app.pachli.components.trending.TrendingActivity
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.database.model.TabKind
|
||||
import app.pachli.core.navigation.AboutActivityIntent
|
||||
import app.pachli.core.navigation.AccountActivityIntent
|
||||
import app.pachli.core.navigation.AccountListActivityIntent
|
||||
import app.pachli.core.navigation.AnnouncementsActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.navigation.DraftsActivityIntent
|
||||
import app.pachli.core.navigation.EditProfileActivityIntent
|
||||
import app.pachli.core.navigation.ListActivityIntent
|
||||
import app.pachli.core.navigation.LoginActivityIntent
|
||||
import app.pachli.core.navigation.LoginActivityIntent.LoginMode
|
||||
import app.pachli.core.navigation.MainActivityIntent
|
||||
import app.pachli.core.navigation.PreferencesActivityIntent
|
||||
import app.pachli.core.navigation.PreferencesActivityIntent.PreferenceScreen
|
||||
import app.pachli.core.navigation.ScheduledStatusActivityIntent
|
||||
import app.pachli.core.navigation.SearchActivityIntent
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.navigation.TrendingActivityIntent
|
||||
import app.pachli.core.network.model.Account
|
||||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.preferences.PrefKeys
|
||||
|
@ -253,13 +260,13 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
)
|
||||
}
|
||||
} else if (openDrafts) {
|
||||
val intent = DraftsActivity.newIntent(this)
|
||||
val intent = DraftsActivityIntent(this)
|
||||
startActivity(intent)
|
||||
} else if (accountRequested && intent.hasExtra(NOTIFICATION_TYPE)) {
|
||||
// user clicked a notification, show follow requests for type FOLLOW_REQUEST,
|
||||
// otherwise show notification tab
|
||||
if (intent.getSerializableExtra(NOTIFICATION_TYPE) == Notification.Type.FOLLOW_REQUEST) {
|
||||
val intent = AccountListActivity.newIntent(this, AccountListActivity.Type.FOLLOW_REQUESTS)
|
||||
val intent = AccountListActivityIntent(this, AccountListActivityIntent.Kind.FOLLOW_REQUESTS)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
} else {
|
||||
showNotificationTab = true
|
||||
|
@ -272,7 +279,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
glide = Glide.with(this)
|
||||
|
||||
binding.composeButton.setOnClickListener {
|
||||
val composeIntent = Intent(applicationContext, ComposeActivity::class.java)
|
||||
val composeIntent = ComposeActivityIntent(applicationContext)
|
||||
startActivity(composeIntent)
|
||||
}
|
||||
|
||||
|
@ -393,7 +400,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_search -> {
|
||||
startActivity(SearchActivity.getIntent(this@MainActivity))
|
||||
startActivity(SearchActivityIntent(this@MainActivity))
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
|
@ -503,7 +510,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
return true
|
||||
}
|
||||
KeyEvent.KEYCODE_SEARCH -> {
|
||||
startActivityWithSlideInAnimation(SearchActivity.getIntent(this))
|
||||
startActivityWithSlideInAnimation(SearchActivityIntent(this))
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -512,7 +519,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_N -> {
|
||||
// open compose activity by pressing SHIFT + N (or CTRL + N)
|
||||
val composeIntent = Intent(applicationContext, ComposeActivity::class.java)
|
||||
val composeIntent = ComposeActivityIntent(applicationContext)
|
||||
startActivity(composeIntent)
|
||||
return true
|
||||
}
|
||||
|
@ -533,12 +540,12 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
}
|
||||
|
||||
private fun forwardToComposeActivity(intent: Intent) {
|
||||
val composeOptions = IntentCompat.getParcelableExtra(intent, COMPOSE_OPTIONS, ComposeActivity.ComposeOptions::class.java)
|
||||
val composeOptions = ComposeActivityIntent.getOptions(intent)
|
||||
|
||||
val composeIntent = if (composeOptions != null) {
|
||||
ComposeActivity.startIntent(this, composeOptions)
|
||||
ComposeActivityIntent(this, composeOptions)
|
||||
} else {
|
||||
Intent(this, ComposeActivity::class.java).apply {
|
||||
ComposeActivityIntent(this).apply {
|
||||
action = intent.action
|
||||
type = intent.type
|
||||
putExtras(intent)
|
||||
|
@ -640,7 +647,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.action_edit_profile
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_person
|
||||
onClick = {
|
||||
val intent = Intent(context, EditProfileActivity::class.java)
|
||||
val intent = EditProfileActivityIntent(context)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -649,7 +656,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
isSelectable = false
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_star
|
||||
onClick = {
|
||||
val intent = StatusListActivity.newFavouritesIntent(context)
|
||||
val intent = StatusListActivityIntent.favourites(context)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -657,7 +664,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.action_view_bookmarks
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_bookmark
|
||||
onClick = {
|
||||
val intent = StatusListActivity.newBookmarksIntent(context)
|
||||
val intent = StatusListActivityIntent.bookmarks(context)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -665,7 +672,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.action_view_follow_requests
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_person_add
|
||||
onClick = {
|
||||
val intent = AccountListActivity.newIntent(context, AccountListActivity.Type.FOLLOW_REQUESTS)
|
||||
val intent = AccountListActivityIntent(context, AccountListActivityIntent.Kind.FOLLOW_REQUESTS)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -673,14 +680,14 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.action_lists
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_list
|
||||
onClick = {
|
||||
startActivityWithSlideInAnimation(ListsActivity.newIntent(context))
|
||||
startActivityWithSlideInAnimation(ListActivityIntent(context))
|
||||
}
|
||||
},
|
||||
primaryDrawerItem {
|
||||
nameRes = R.string.action_access_drafts
|
||||
iconRes = R.drawable.ic_notebook
|
||||
onClick = {
|
||||
val intent = DraftsActivity.newIntent(context)
|
||||
val intent = DraftsActivityIntent(context)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -688,7 +695,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.action_access_scheduled_posts
|
||||
iconRes = R.drawable.ic_access_time
|
||||
onClick = {
|
||||
startActivityWithSlideInAnimation(ScheduledStatusActivity.newIntent(context))
|
||||
startActivityWithSlideInAnimation(ScheduledStatusActivityIntent(context))
|
||||
}
|
||||
},
|
||||
primaryDrawerItem {
|
||||
|
@ -696,7 +703,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.title_announcements
|
||||
iconRes = R.drawable.ic_bullhorn_24dp
|
||||
onClick = {
|
||||
startActivityWithSlideInAnimation(AnnouncementsActivity.newIntent(context))
|
||||
startActivityWithSlideInAnimation(AnnouncementsActivityIntent(context))
|
||||
}
|
||||
badgeStyle = BadgeStyle().apply {
|
||||
textColor = ColorHolder.fromColor(MaterialColors.getColor(binding.mainDrawer, com.google.android.material.R.attr.colorOnPrimary))
|
||||
|
@ -708,7 +715,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.action_view_account_preferences
|
||||
iconRes = R.drawable.ic_account_settings
|
||||
onClick = {
|
||||
val intent = PreferencesActivity.newIntent(context, PreferencesActivity.ACCOUNT_PREFERENCES)
|
||||
val intent = PreferencesActivityIntent(context, PreferenceScreen.ACCOUNT)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -716,7 +723,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.action_view_preferences
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_settings
|
||||
onClick = {
|
||||
val intent = PreferencesActivity.newIntent(context, PreferencesActivity.GENERAL_PREFERENCES)
|
||||
val intent = PreferencesActivityIntent(context, PreferenceScreen.GENERAL)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -724,7 +731,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.about_title_activity
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_info
|
||||
onClick = {
|
||||
val intent = Intent(context, AboutActivity::class.java)
|
||||
val intent = AboutActivityIntent(context)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
},
|
||||
|
@ -742,7 +749,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.action_search
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_search
|
||||
onClick = {
|
||||
startActivityWithSlideInAnimation(SearchActivity.getIntent(context))
|
||||
startActivityWithSlideInAnimation(SearchActivityIntent(context))
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -754,7 +761,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
nameRes = R.string.title_public_trending
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_trending_up
|
||||
onClick = {
|
||||
startActivityWithSlideInAnimation(TrendingActivity.getIntent(context))
|
||||
startActivityWithSlideInAnimation(TrendingActivityIntent(context))
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -941,13 +948,15 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
|
||||
// open profile when active image was clicked
|
||||
if (current && activeAccount != null) {
|
||||
val intent = AccountActivity.getIntent(this, activeAccount.accountId)
|
||||
val intent = AccountActivityIntent(this, activeAccount.accountId)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
return
|
||||
}
|
||||
// open LoginActivity to add new account
|
||||
if (profile.identifier == DRAWER_ITEM_ADD_ACCOUNT) {
|
||||
startActivityWithSlideInAnimation(LoginActivity.getIntent(this, LoginActivity.MODE_ADDITIONAL_LOGIN))
|
||||
startActivityWithSlideInAnimation(
|
||||
LoginActivityIntent(this, LoginMode.ADDITIONAL_LOGIN),
|
||||
)
|
||||
return
|
||||
}
|
||||
// change Account
|
||||
|
@ -958,7 +967,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
private fun changeAccount(newSelectedId: Long, forward: Intent?) {
|
||||
cacheUpdater.stop()
|
||||
accountManager.setActiveAccount(newSelectedId)
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
val intent = MainActivityIntent(this)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
if (forward != null) {
|
||||
intent.type = forward.type
|
||||
|
@ -988,9 +997,9 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
lifecycleScope.launch {
|
||||
val otherAccountAvailable = logoutUsecase.logout()
|
||||
val intent = if (otherAccountAvailable) {
|
||||
Intent(this@MainActivity, MainActivity::class.java)
|
||||
MainActivityIntent(this@MainActivity)
|
||||
} else {
|
||||
LoginActivity.getIntent(this@MainActivity, LoginActivity.MODE_DEFAULT)
|
||||
LoginActivityIntent(this@MainActivity, LoginMode.DEFAULT)
|
||||
}
|
||||
startActivity(intent)
|
||||
finishWithoutSlideOutAnimation()
|
||||
|
@ -1197,7 +1206,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
*/
|
||||
@JvmStatic
|
||||
fun accountSwitchIntent(context: Context, pachliAccountId: Long): Intent {
|
||||
return Intent(context, MainActivity::class.java).apply {
|
||||
return MainActivityIntent(context).apply {
|
||||
putExtra(PACHLI_ACCOUNT_ID, pachliAccountId)
|
||||
}
|
||||
}
|
||||
|
@ -1221,7 +1230,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
@JvmStatic
|
||||
fun composeIntent(
|
||||
context: Context,
|
||||
options: ComposeActivity.ComposeOptions,
|
||||
options: ComposeOptions,
|
||||
pachliAccountId: Long = -1,
|
||||
notificationTag: String? = null,
|
||||
notificationId: Int = -1,
|
||||
|
|
|
@ -18,12 +18,13 @@
|
|||
package app.pachli
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import app.pachli.components.login.LoginActivity
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.navigation.LoginActivityIntent
|
||||
import app.pachli.core.navigation.LoginActivityIntent.LoginMode
|
||||
import app.pachli.core.navigation.MainActivityIntent
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -41,9 +42,9 @@ class SplashActivity : AppCompatActivity() {
|
|||
/** Determine whether the user is currently logged in, and if so go ahead and load the
|
||||
* timeline. Otherwise, start the activity_login screen. */
|
||||
val intent = if (accountManager.activeAccount != null) {
|
||||
Intent(this, MainActivity::class.java)
|
||||
MainActivityIntent(this)
|
||||
} else {
|
||||
LoginActivity.getIntent(this, LoginActivity.MODE_DEFAULT)
|
||||
LoginActivityIntent(this, LoginMode.DEFAULT)
|
||||
}
|
||||
startActivity(intent)
|
||||
finish()
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
package app.pachli
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
|
@ -26,8 +24,10 @@ import androidx.fragment.app.commit
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import app.pachli.appstore.EventHub
|
||||
import app.pachli.appstore.FilterChangedEvent
|
||||
import app.pachli.components.compose.ComposeActivity
|
||||
import app.pachli.components.timeline.TimelineFragment
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.network.model.Filter
|
||||
import app.pachli.core.network.model.FilterV1
|
||||
import app.pachli.core.network.model.TimelineKind
|
||||
|
@ -84,7 +84,7 @@ class StatusListActivity : BottomSheetActivity(), AppBarLayoutHost, ActionButton
|
|||
|
||||
setSupportActionBar(binding.includedToolbar.toolbar)
|
||||
|
||||
timelineKind = intent.getParcelableExtra(EXTRA_KIND)!!
|
||||
timelineKind = StatusListActivityIntent.getKind(intent)
|
||||
|
||||
val title = when (timelineKind) {
|
||||
is TimelineKind.Favourites -> getString(R.string.title_favourites)
|
||||
|
@ -113,11 +113,11 @@ class StatusListActivity : BottomSheetActivity(), AppBarLayoutHost, ActionButton
|
|||
val composeIntent = when (timelineKind) {
|
||||
is TimelineKind.Tag -> {
|
||||
val tag = (timelineKind as TimelineKind.Tag).tags.first()
|
||||
ComposeActivity.startIntent(
|
||||
ComposeActivityIntent(
|
||||
this,
|
||||
ComposeActivity.ComposeOptions(
|
||||
ComposeOptions(
|
||||
content = getString(R.string.title_tag_with_initial_position).format(tag),
|
||||
initialCursorPosition = ComposeActivity.InitialCursorPosition.START,
|
||||
initialCursorPosition = ComposeOptions.InitialCursorPosition.START,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -125,10 +125,7 @@ class StatusListActivity : BottomSheetActivity(), AppBarLayoutHost, ActionButton
|
|||
is TimelineKind.Favourites,
|
||||
is TimelineKind.UserList,
|
||||
-> {
|
||||
ComposeActivity.startIntent(
|
||||
this,
|
||||
ComposeActivity.ComposeOptions(),
|
||||
)
|
||||
ComposeActivityIntent(this, ComposeOptions())
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
@ -367,29 +364,4 @@ class StatusListActivity : BottomSheetActivity(), AppBarLayoutHost, ActionButton
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_KIND = "kind"
|
||||
|
||||
fun newFavouritesIntent(context: Context) =
|
||||
Intent(context, StatusListActivity::class.java).apply {
|
||||
putExtra(EXTRA_KIND, TimelineKind.Favourites)
|
||||
}
|
||||
|
||||
fun newBookmarksIntent(context: Context) =
|
||||
Intent(context, StatusListActivity::class.java).apply {
|
||||
putExtra(EXTRA_KIND, TimelineKind.Bookmarks)
|
||||
}
|
||||
|
||||
fun newListIntent(context: Context, listId: String, listTitle: String) =
|
||||
Intent(context, StatusListActivity::class.java).apply {
|
||||
putExtra(EXTRA_KIND, TimelineKind.UserList(listId, listTitle))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newHashtagIntent(context: Context, hashtag: String) =
|
||||
Intent(context, StatusListActivity::class.java).apply {
|
||||
putExtra(EXTRA_KIND, TimelineKind.Tag(listOf(hashtag)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package app.pachli
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
|
@ -44,6 +43,7 @@ import app.pachli.appstore.EventHub
|
|||
import app.pachli.appstore.MainTabsChangedEvent
|
||||
import app.pachli.core.database.model.TabData
|
||||
import app.pachli.core.database.model.TabKind
|
||||
import app.pachli.core.navigation.ListActivityIntent
|
||||
import app.pachli.core.network.model.MastoList
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import app.pachli.databinding.ActivityTabPreferenceBinding
|
||||
|
@ -303,7 +303,7 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener {
|
|||
val dialogBuilder = AlertDialog.Builder(this)
|
||||
.setTitle(R.string.select_list_title)
|
||||
.setNeutralButton(R.string.select_list_manage) { _, _ ->
|
||||
val listIntent = Intent(applicationContext, ListsActivity::class.java)
|
||||
val listIntent = ListActivityIntent(applicationContext)
|
||||
startActivity(listIntent)
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
|
|
|
@ -24,7 +24,6 @@ import android.app.DownloadManager
|
|||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
|
@ -40,13 +39,14 @@ import android.webkit.MimeTypeMap
|
|||
import android.widget.Toast
|
||||
import androidx.core.app.ShareCompat
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import app.pachli.BuildConfig.APPLICATION_ID
|
||||
import app.pachli.components.viewthread.ViewThreadActivity
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.navigation.ViewMediaActivityIntent
|
||||
import app.pachli.core.navigation.ViewThreadActivityIntent
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.databinding.ActivityViewMediaBinding
|
||||
import app.pachli.fragment.ViewImageFragment
|
||||
|
@ -55,7 +55,6 @@ import app.pachli.pager.ImagePagerAdapter
|
|||
import app.pachli.pager.SingleImagePagerAdapter
|
||||
import app.pachli.util.getTemporaryMediaFilename
|
||||
import app.pachli.util.viewBinding
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import autodispose2.androidx.lifecycle.AndroidLifecycleScopeProvider
|
||||
import autodispose2.autoDispose
|
||||
import com.bumptech.glide.Glide
|
||||
|
@ -73,6 +72,9 @@ import java.util.Locale
|
|||
|
||||
typealias ToolbarVisibilityListener = (isVisible: Boolean) -> Unit
|
||||
|
||||
/**
|
||||
* Show one or more media items (pictures, video, audio, etc).
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener, ViewVideoFragment.VideoActionsListener {
|
||||
private val binding by viewBinding(ActivityViewMediaBinding::inflate)
|
||||
|
@ -100,8 +102,8 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
|
|||
supportPostponeEnterTransition()
|
||||
|
||||
// Gather the parameters.
|
||||
attachments = IntentCompat.getParcelableArrayListExtra(intent, EXTRA_ATTACHMENTS, AttachmentViewData::class.java)
|
||||
val initialPosition = intent.getIntExtra(EXTRA_ATTACHMENT_INDEX, 0)
|
||||
attachments = ViewMediaActivityIntent.getAttachments(intent)
|
||||
val initialPosition = ViewMediaActivityIntent.getAttachmentIndex(intent)
|
||||
|
||||
// Adapter is actually of existential type PageAdapter & SharedElementsTransitionListener
|
||||
// but it cannot be expressed and if I don't specify type explicitly compilation fails
|
||||
|
@ -111,7 +113,7 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
|
|||
// Setup the view pager.
|
||||
ImagePagerAdapter(this, realAttachs, initialPosition)
|
||||
} else {
|
||||
imageUrl = intent.getStringExtra(EXTRA_SINGLE_IMAGE_URL)
|
||||
imageUrl = ViewMediaActivityIntent.getImageUrl(intent)
|
||||
?: throw IllegalArgumentException("attachment list or image url has to be set")
|
||||
|
||||
SingleImagePagerAdapter(this, imageUrl!!)
|
||||
|
@ -241,7 +243,7 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
|
|||
|
||||
private fun onOpenStatus() {
|
||||
val attach = attachments!![binding.viewPager.currentItem]
|
||||
startActivityWithSlideInAnimation(ViewThreadActivity.startIntent(this, attach.statusId, attach.statusUrl))
|
||||
startActivityWithSlideInAnimation(ViewThreadActivityIntent(this, attach.statusId, attach.statusUrl))
|
||||
}
|
||||
|
||||
private fun copyLink() {
|
||||
|
@ -344,27 +346,6 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
|
|||
|
||||
shareFile(file, mimeType)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_ATTACHMENTS = "attachments"
|
||||
private const val EXTRA_ATTACHMENT_INDEX = "index"
|
||||
private const val EXTRA_SINGLE_IMAGE_URL = "single_image"
|
||||
|
||||
@JvmStatic
|
||||
fun newIntent(context: Context?, attachments: List<AttachmentViewData>, index: Int): Intent {
|
||||
val intent = Intent(context, ViewMediaActivity::class.java)
|
||||
intent.putParcelableArrayListExtra(EXTRA_ATTACHMENTS, ArrayList(attachments))
|
||||
intent.putExtra(EXTRA_ATTACHMENT_INDEX, index)
|
||||
return intent
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newSingleImageIntent(context: Context, url: String): Intent {
|
||||
val intent = Intent(context, ViewMediaActivity::class.java)
|
||||
intent.putExtra(EXTRA_SINGLE_IMAGE_URL, url)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ViewMediaAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
|
||||
|
|
|
@ -20,10 +20,10 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.core.text.HtmlCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import app.pachli.R
|
||||
import app.pachli.ViewMediaActivity.Companion.newSingleImageIntent
|
||||
import app.pachli.core.common.util.AbsoluteTimeFormatter
|
||||
import app.pachli.core.common.util.formatNumber
|
||||
import app.pachli.core.database.model.TranslationState
|
||||
import app.pachli.core.navigation.ViewMediaActivityIntent
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.core.network.model.Emoji
|
||||
import app.pachli.core.network.model.PreviewCardKind
|
||||
|
@ -877,7 +877,7 @@ abstract class StatusBaseViewHolder protected constructor(itemView: View) :
|
|||
cardView.bind(card, status.actionable.sensitive, statusDisplayOptions) { target ->
|
||||
if (card.kind == PreviewCardKind.PHOTO && card.embedUrl.isNotEmpty() && target == PreviewCardView.Target.IMAGE) {
|
||||
context.startActivity(
|
||||
newSingleImageIntent(context, card.embedUrl),
|
||||
ViewMediaActivityIntent(context, card.embedUrl),
|
||||
)
|
||||
} else {
|
||||
listener.onViewUrl(card.url)
|
||||
|
|
|
@ -47,15 +47,17 @@ import androidx.core.widget.doAfterTextChanged
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.viewpager2.widget.MarginPageTransformer
|
||||
import app.pachli.BottomSheetActivity
|
||||
import app.pachli.EditProfileActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.StatusListActivity
|
||||
import app.pachli.ViewMediaActivity
|
||||
import app.pachli.components.account.list.ListsForAccountFragment
|
||||
import app.pachli.components.accountlist.AccountListActivity
|
||||
import app.pachli.components.compose.ComposeActivity
|
||||
import app.pachli.components.report.ReportActivity
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.navigation.AccountActivityIntent
|
||||
import app.pachli.core.navigation.AccountListActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.navigation.EditProfileActivityIntent
|
||||
import app.pachli.core.navigation.ReportActivityIntent
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.navigation.ViewMediaActivityIntent
|
||||
import app.pachli.core.network.model.Account
|
||||
import app.pachli.core.network.model.Relationship
|
||||
import app.pachli.core.network.parseAsMastodonHtml
|
||||
|
@ -100,6 +102,9 @@ import java.util.Locale
|
|||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* Show a single account's profile details.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class AccountActivity :
|
||||
BottomSheetActivity(),
|
||||
|
@ -172,7 +177,7 @@ class AccountActivity :
|
|||
addMenuProvider(this)
|
||||
|
||||
// Obtain information to fill out the profile.
|
||||
viewModel.setAccountInfo(intent.getStringExtra(KEY_ACCOUNT_ID)!!)
|
||||
viewModel.setAccountInfo(AccountActivityIntent.getAccountId(intent))
|
||||
|
||||
animateAvatar = sharedPreferencesRepository.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false)
|
||||
animateEmojis = sharedPreferencesRepository.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
|
@ -221,12 +226,12 @@ class AccountActivity :
|
|||
binding.accountFieldList.adapter = accountFieldAdapter
|
||||
|
||||
val accountListClickListener = { v: View ->
|
||||
val type = when (v.id) {
|
||||
R.id.accountFollowers -> AccountListActivity.Type.FOLLOWERS
|
||||
R.id.accountFollowing -> AccountListActivity.Type.FOLLOWS
|
||||
val kind = when (v.id) {
|
||||
R.id.accountFollowers -> AccountListActivityIntent.Kind.FOLLOWERS
|
||||
R.id.accountFollowing -> AccountListActivityIntent.Kind.FOLLOWS
|
||||
else -> throw AssertionError()
|
||||
}
|
||||
val accountListIntent = AccountListActivity.newIntent(this, type, viewModel.accountId)
|
||||
val accountListIntent = AccountListActivityIntent(this, kind, viewModel.accountId)
|
||||
startActivityWithSlideInAnimation(accountListIntent)
|
||||
}
|
||||
binding.accountFollowers.setOnClickListener(accountListClickListener)
|
||||
|
@ -540,7 +545,7 @@ class AccountActivity :
|
|||
private fun viewImage(view: View, uri: String) {
|
||||
view.transitionName = uri
|
||||
startActivity(
|
||||
ViewMediaActivity.newSingleImageIntent(view.context, uri),
|
||||
ViewMediaActivityIntent(view.context, uri),
|
||||
ActivityOptionsCompat.makeSceneTransitionAnimation(this, view, uri).toBundle(),
|
||||
)
|
||||
}
|
||||
|
@ -606,7 +611,7 @@ class AccountActivity :
|
|||
|
||||
binding.accountFollowButton.setOnClickListener {
|
||||
if (viewModel.isSelf) {
|
||||
val intent = Intent(this@AccountActivity, EditProfileActivity::class.java)
|
||||
val intent = EditProfileActivityIntent(this@AccountActivity)
|
||||
startActivity(intent)
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
@ -879,26 +884,25 @@ class AccountActivity :
|
|||
private fun mention() {
|
||||
loadedAccount?.let {
|
||||
val options = if (viewModel.isSelf) {
|
||||
ComposeActivity.ComposeOptions(kind = ComposeActivity.ComposeKind.NEW)
|
||||
ComposeOptions(kind = ComposeOptions.ComposeKind.NEW)
|
||||
} else {
|
||||
ComposeActivity.ComposeOptions(
|
||||
ComposeOptions(
|
||||
mentionedUsernames = setOf(it.username),
|
||||
kind = ComposeActivity.ComposeKind.NEW,
|
||||
kind = ComposeOptions.ComposeKind.NEW,
|
||||
)
|
||||
}
|
||||
val intent = ComposeActivity.startIntent(this, options)
|
||||
val intent = ComposeActivityIntent(this, options)
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewTag(tag: String) {
|
||||
val intent = StatusListActivity.newHashtagIntent(this, tag)
|
||||
val intent = StatusListActivityIntent.hashtag(this, tag)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
|
||||
override fun onViewAccount(id: String) {
|
||||
val intent = Intent(this, AccountActivity::class.java)
|
||||
intent.putExtra("id", id)
|
||||
val intent = AccountActivityIntent(this, id)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
|
||||
|
@ -979,7 +983,7 @@ class AccountActivity :
|
|||
}
|
||||
R.id.action_report -> {
|
||||
loadedAccount?.let { loadedAccount ->
|
||||
startActivity(ReportActivity.getIntent(this, viewModel.accountId, loadedAccount.username))
|
||||
startActivity(ReportActivityIntent(this, viewModel.accountId, loadedAccount.username))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -999,14 +1003,6 @@ class AccountActivity :
|
|||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_ACCOUNT_ID = "id"
|
||||
private val argbEvaluator = ArgbEvaluator()
|
||||
|
||||
@JvmStatic
|
||||
fun getIntent(context: Context, accountId: String): Intent {
|
||||
val intent = Intent(context, AccountActivity::class.java)
|
||||
intent.putExtra(KEY_ACCOUNT_ID, accountId)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,9 @@ import androidx.paging.LoadState
|
|||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
||||
import app.pachli.R
|
||||
import app.pachli.ViewMediaActivity
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.navigation.ViewMediaActivityIntent
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.core.preferences.PrefKeys
|
||||
import app.pachli.core.preferences.SharedPreferencesRepository
|
||||
|
@ -43,7 +44,6 @@ import app.pachli.util.hide
|
|||
import app.pachli.util.openLink
|
||||
import app.pachli.util.show
|
||||
import app.pachli.util.viewBinding
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
|
@ -175,7 +175,7 @@ class AccountMediaFragment :
|
|||
Attachment.Type.VIDEO,
|
||||
Attachment.Type.AUDIO,
|
||||
-> {
|
||||
val intent = ViewMediaActivity.newIntent(context, attachmentsFromSameStatus, currentIndex)
|
||||
val intent = ViewMediaActivityIntent(requireContext(), attachmentsFromSameStatus, currentIndex)
|
||||
if (activity != null) {
|
||||
val url = selected.attachment.url
|
||||
ViewCompat.setTransitionName(view, url)
|
||||
|
|
|
@ -11,6 +11,7 @@ import androidx.core.view.setPadding
|
|||
import androidx.paging.PagingDataAdapter
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import app.pachli.R
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.databinding.ItemAccountMediaBinding
|
||||
import app.pachli.util.BindingHolder
|
||||
|
@ -18,7 +19,6 @@ import app.pachli.util.decodeBlurHash
|
|||
import app.pachli.util.getFormattedDescription
|
||||
import app.pachli.util.hide
|
||||
import app.pachli.util.show
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import java.util.Random
|
||||
|
|
|
@ -18,7 +18,7 @@ package app.pachli.components.account.media
|
|||
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
|
||||
class AccountMediaPagingSource(
|
||||
private val viewModel: AccountMediaViewModel,
|
||||
|
|
|
@ -22,8 +22,8 @@ import androidx.paging.PagingState
|
|||
import androidx.paging.RemoteMediator
|
||||
import app.pachli.components.timeline.util.ifExpected
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import retrofit2.HttpException
|
||||
|
||||
@OptIn(ExperimentalPagingApi::class)
|
||||
|
|
|
@ -23,8 +23,8 @@ import androidx.paging.Pager
|
|||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.cachedIn
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
|
@ -16,18 +16,27 @@
|
|||
|
||||
package app.pachli.components.accountlist
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.commit
|
||||
import app.pachli.BottomSheetActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.core.navigation.AccountListActivityIntent
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.BLOCKS
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.FAVOURITED
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.FOLLOWERS
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.FOLLOWS
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.FOLLOW_REQUESTS
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.MUTES
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.REBLOGGED
|
||||
import app.pachli.databinding.ActivityAccountListBinding
|
||||
import app.pachli.interfaces.AppBarLayoutHost
|
||||
import app.pachli.util.viewBinding
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
/**
|
||||
* Show a list of accounts of a particular kind.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class AccountListActivity : BottomSheetActivity(), AppBarLayoutHost {
|
||||
private val binding: ActivityAccountListBinding by viewBinding(ActivityAccountListBinding::inflate)
|
||||
|
@ -35,52 +44,30 @@ class AccountListActivity : BottomSheetActivity(), AppBarLayoutHost {
|
|||
override val appBarLayout: AppBarLayout
|
||||
get() = binding.includedToolbar.appbar
|
||||
|
||||
enum class Type {
|
||||
FOLLOWS,
|
||||
FOLLOWERS,
|
||||
BLOCKS,
|
||||
MUTES,
|
||||
FOLLOW_REQUESTS,
|
||||
REBLOGGED,
|
||||
FAVOURITED,
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(binding.root)
|
||||
|
||||
val type = intent.getSerializableExtra(EXTRA_TYPE) as Type
|
||||
val id: String? = intent.getStringExtra(EXTRA_ID)
|
||||
val kind = AccountListActivityIntent.getKind(intent)
|
||||
val id = AccountListActivityIntent.getId(intent)
|
||||
|
||||
setSupportActionBar(binding.includedToolbar.toolbar)
|
||||
supportActionBar?.apply {
|
||||
when (type) {
|
||||
Type.BLOCKS -> setTitle(R.string.title_blocks)
|
||||
Type.MUTES -> setTitle(R.string.title_mutes)
|
||||
Type.FOLLOW_REQUESTS -> setTitle(R.string.title_follow_requests)
|
||||
Type.FOLLOWERS -> setTitle(R.string.title_followers)
|
||||
Type.FOLLOWS -> setTitle(R.string.title_follows)
|
||||
Type.REBLOGGED -> setTitle(R.string.title_reblogged_by)
|
||||
Type.FAVOURITED -> setTitle(R.string.title_favourited_by)
|
||||
when (kind) {
|
||||
BLOCKS -> setTitle(R.string.title_blocks)
|
||||
MUTES -> setTitle(R.string.title_mutes)
|
||||
FOLLOW_REQUESTS -> setTitle(R.string.title_follow_requests)
|
||||
FOLLOWERS -> setTitle(R.string.title_followers)
|
||||
FOLLOWS -> setTitle(R.string.title_follows)
|
||||
REBLOGGED -> setTitle(R.string.title_reblogged_by)
|
||||
FAVOURITED -> setTitle(R.string.title_favourited_by)
|
||||
}
|
||||
setDisplayHomeAsUpEnabled(true)
|
||||
setDisplayShowHomeEnabled(true)
|
||||
}
|
||||
|
||||
supportFragmentManager.commit {
|
||||
replace(R.id.fragment_container, AccountListFragment.newInstance(type, id))
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_TYPE = "type"
|
||||
private const val EXTRA_ID = "id"
|
||||
|
||||
fun newIntent(context: Context, type: Type, id: String? = null): Intent {
|
||||
return Intent(context, AccountListActivity::class.java).apply {
|
||||
putExtra(EXTRA_TYPE, type)
|
||||
putExtra(EXTRA_ID, id)
|
||||
}
|
||||
replace(R.id.fragment_container, AccountListFragment.newInstance(kind, id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,6 @@ import app.pachli.BaseActivity
|
|||
import app.pachli.BottomSheetActivity
|
||||
import app.pachli.PostLookupFallbackBehavior
|
||||
import app.pachli.R
|
||||
import app.pachli.StatusListActivity
|
||||
import app.pachli.components.account.AccountActivity
|
||||
import app.pachli.components.accountlist.AccountListActivity.Type
|
||||
import app.pachli.components.accountlist.adapter.AccountAdapter
|
||||
import app.pachli.components.accountlist.adapter.BlocksAdapter
|
||||
import app.pachli.components.accountlist.adapter.FollowAdapter
|
||||
|
@ -38,6 +35,16 @@ import app.pachli.components.accountlist.adapter.FollowRequestsAdapter
|
|||
import app.pachli.components.accountlist.adapter.FollowRequestsHeaderAdapter
|
||||
import app.pachli.components.accountlist.adapter.MutesAdapter
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.navigation.AccountActivityIntent
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.BLOCKS
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.FAVOURITED
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.FOLLOWERS
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.FOLLOWS
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.FOLLOW_REQUESTS
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.MUTES
|
||||
import app.pachli.core.navigation.AccountListActivityIntent.Kind.REBLOGGED
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.network.model.HttpHeaderLink
|
||||
import app.pachli.core.network.model.Relationship
|
||||
import app.pachli.core.network.model.TimelineAccount
|
||||
|
@ -80,7 +87,7 @@ class AccountListFragment :
|
|||
|
||||
private val binding by viewBinding(FragmentAccountListBinding::bind)
|
||||
|
||||
private lateinit var type: Type
|
||||
private lateinit var kind: Kind
|
||||
private var id: String? = null
|
||||
|
||||
private lateinit var scrollListener: EndlessOnScrollListener
|
||||
|
@ -90,7 +97,7 @@ class AccountListFragment :
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
type = requireArguments().getSerializable(ARG_TYPE) as Type
|
||||
kind = requireArguments().getSerializable(ARG_KIND) as Kind
|
||||
id = requireArguments().getString(ARG_ID)
|
||||
}
|
||||
|
||||
|
@ -112,10 +119,10 @@ class AccountListFragment :
|
|||
|
||||
val activeAccount = accountManager.activeAccount!!
|
||||
|
||||
adapter = when (type) {
|
||||
Type.BLOCKS -> BlocksAdapter(this, animateAvatar, animateEmojis, showBotOverlay)
|
||||
Type.MUTES -> MutesAdapter(this, animateAvatar, animateEmojis, showBotOverlay)
|
||||
Type.FOLLOW_REQUESTS -> {
|
||||
adapter = when (kind) {
|
||||
BLOCKS -> BlocksAdapter(this, animateAvatar, animateEmojis, showBotOverlay)
|
||||
MUTES -> MutesAdapter(this, animateAvatar, animateEmojis, showBotOverlay)
|
||||
FOLLOW_REQUESTS -> {
|
||||
val headerAdapter = FollowRequestsHeaderAdapter(
|
||||
instanceName = activeAccount.domain,
|
||||
accountLocked = activeAccount.locked,
|
||||
|
@ -151,12 +158,12 @@ class AccountListFragment :
|
|||
|
||||
override fun onViewTag(tag: String) {
|
||||
(activity as BaseActivity?)
|
||||
?.startActivityWithSlideInAnimation(StatusListActivity.newHashtagIntent(requireContext(), tag))
|
||||
?.startActivityWithSlideInAnimation(StatusListActivityIntent.hashtag(requireContext(), tag))
|
||||
}
|
||||
|
||||
override fun onViewAccount(id: String) {
|
||||
(activity as BaseActivity?)?.let {
|
||||
val intent = AccountActivity.getIntent(it, id)
|
||||
val intent = AccountActivityIntent(it, id)
|
||||
it.startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
}
|
||||
|
@ -283,31 +290,31 @@ class AccountListFragment :
|
|||
}
|
||||
|
||||
private suspend fun getFetchCallByListType(fromId: String?): Response<List<TimelineAccount>> {
|
||||
return when (type) {
|
||||
Type.FOLLOWS -> {
|
||||
val accountId = requireId(type, id)
|
||||
return when (kind) {
|
||||
FOLLOWS -> {
|
||||
val accountId = requireId(kind, id)
|
||||
api.accountFollowing(accountId, fromId)
|
||||
}
|
||||
Type.FOLLOWERS -> {
|
||||
val accountId = requireId(type, id)
|
||||
FOLLOWERS -> {
|
||||
val accountId = requireId(kind, id)
|
||||
api.accountFollowers(accountId, fromId)
|
||||
}
|
||||
Type.BLOCKS -> api.blocks(fromId)
|
||||
Type.MUTES -> api.mutes(fromId)
|
||||
Type.FOLLOW_REQUESTS -> api.followRequests(fromId)
|
||||
Type.REBLOGGED -> {
|
||||
val statusId = requireId(type, id)
|
||||
BLOCKS -> api.blocks(fromId)
|
||||
MUTES -> api.mutes(fromId)
|
||||
FOLLOW_REQUESTS -> api.followRequests(fromId)
|
||||
REBLOGGED -> {
|
||||
val statusId = requireId(kind, id)
|
||||
api.statusRebloggedBy(statusId, fromId)
|
||||
}
|
||||
Type.FAVOURITED -> {
|
||||
val statusId = requireId(type, id)
|
||||
FAVOURITED -> {
|
||||
val statusId = requireId(kind, id)
|
||||
api.statusFavouritedBy(statusId, fromId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun requireId(type: Type, id: String?): String {
|
||||
return requireNotNull(id) { "id must not be null for type " + type.name }
|
||||
private fun requireId(kind: Kind, id: String?): String {
|
||||
return requireNotNull(id) { "id must not be null for kind " + kind.name }
|
||||
}
|
||||
|
||||
private fun fetchAccounts(fromId: String? = null) {
|
||||
|
@ -410,13 +417,13 @@ class AccountListFragment :
|
|||
}
|
||||
|
||||
companion object {
|
||||
private const val ARG_TYPE = "type"
|
||||
private const val ARG_KIND = "kind"
|
||||
private const val ARG_ID = "id"
|
||||
|
||||
fun newInstance(type: Type, id: String? = null): AccountListFragment {
|
||||
fun newInstance(kind: Kind, id: String? = null): AccountListFragment {
|
||||
return AccountListFragment().apply {
|
||||
arguments = Bundle(3).apply {
|
||||
putSerializable(ARG_TYPE, type)
|
||||
putSerializable(ARG_KIND, kind)
|
||||
putString(ARG_ID, id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package app.pachli.components.announcements
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
|
@ -29,9 +27,9 @@ import androidx.core.view.MenuProvider
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import app.pachli.BottomSheetActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.StatusListActivity
|
||||
import app.pachli.adapter.EmojiAdapter
|
||||
import app.pachli.adapter.OnEmojiSelectedListener
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.preferences.PrefKeys
|
||||
import app.pachli.databinding.ActivityAnnouncementsBinding
|
||||
import app.pachli.util.Error
|
||||
|
@ -185,7 +183,7 @@ class AnnouncementsActivity :
|
|||
}
|
||||
|
||||
override fun onViewTag(tag: String) {
|
||||
val intent = StatusListActivity.newHashtagIntent(this, tag)
|
||||
val intent = StatusListActivityIntent.hashtag(this, tag)
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
|
||||
|
@ -196,8 +194,4 @@ class AnnouncementsActivity :
|
|||
override fun onViewUrl(url: String) {
|
||||
viewUrl(url)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newIntent(context: Context) = Intent(context, AnnouncementsActivity::class.java)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ package app.pachli.components.compose
|
|||
import android.Manifest
|
||||
import android.app.ProgressDialog
|
||||
import android.content.ClipData
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
|
@ -28,7 +27,6 @@ import android.graphics.PorterDuffColorFilter
|
|||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.provider.MediaStore
|
||||
import android.text.Spanned
|
||||
import android.text.style.URLSpan
|
||||
|
@ -77,10 +75,11 @@ import app.pachli.components.compose.view.ComposeOptionsListener
|
|||
import app.pachli.components.compose.view.ComposeScheduleView
|
||||
import app.pachli.components.instanceinfo.InstanceInfoRepository
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.database.model.DraftAttachment
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions.InitialCursorPosition
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.core.network.model.Emoji
|
||||
import app.pachli.core.network.model.NewPoll
|
||||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.preferences.PrefKeys
|
||||
import app.pachli.core.preferences.PrefKeys.APP_THEME
|
||||
|
@ -116,7 +115,6 @@ import kotlinx.coroutines.flow.collect
|
|||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
@ -125,6 +123,10 @@ import java.util.Locale
|
|||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* Compose a status, either by creating one from scratch, or by editing an existing
|
||||
* status, draft, or scheduled status.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class ComposeActivity :
|
||||
BaseActivity(),
|
||||
|
@ -233,7 +235,7 @@ class ComposeActivity :
|
|||
|
||||
/* If the composer is started up as a reply to another post, override the "starting" state
|
||||
* based on what the intent from the reply request passes. */
|
||||
val composeOptions: ComposeOptions? = IntentCompat.getParcelableExtra(intent, COMPOSE_OPTIONS_EXTRA, ComposeOptions::class.java)
|
||||
val composeOptions: ComposeOptions? = ComposeActivityIntent.getOptions(intent)
|
||||
viewModel.setup(composeOptions)
|
||||
|
||||
setupButtons()
|
||||
|
@ -1297,60 +1299,6 @@ class ComposeActivity :
|
|||
viewModel.updateDescription(localId, description)
|
||||
}
|
||||
|
||||
/**
|
||||
* Status' kind. This particularly affects how the status is handled if the user
|
||||
* backs out of the edit.
|
||||
*/
|
||||
enum class ComposeKind {
|
||||
/** Status is new */
|
||||
NEW,
|
||||
|
||||
/** Editing a posted status */
|
||||
EDIT_POSTED,
|
||||
|
||||
/** Editing a status started as an existing draft */
|
||||
EDIT_DRAFT,
|
||||
|
||||
/** Editing an an existing scheduled status */
|
||||
EDIT_SCHEDULED,
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial position of the cursor in EditText when the compose button is clicked
|
||||
* in a hashtag timeline
|
||||
*/
|
||||
enum class InitialCursorPosition {
|
||||
START,
|
||||
END,
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class ComposeOptions(
|
||||
// Let's keep fields var until all consumers are Kotlin
|
||||
var scheduledTootId: String? = null,
|
||||
var draftId: Int? = null,
|
||||
var content: String? = null,
|
||||
var mediaUrls: List<String>? = null,
|
||||
var mediaDescriptions: List<String>? = null,
|
||||
var mentionedUsernames: Set<String>? = null,
|
||||
var inReplyToId: String? = null,
|
||||
var replyVisibility: Status.Visibility? = null,
|
||||
var visibility: Status.Visibility? = null,
|
||||
var contentWarning: String? = null,
|
||||
var replyingStatusAuthor: String? = null,
|
||||
var replyingStatusContent: String? = null,
|
||||
var mediaAttachments: List<Attachment>? = null,
|
||||
var draftAttachments: List<DraftAttachment>? = null,
|
||||
var scheduledAt: String? = null,
|
||||
var sensitive: Boolean? = null,
|
||||
var poll: NewPoll? = null,
|
||||
var modifiedInitialState: Boolean? = null,
|
||||
var language: String? = null,
|
||||
var statusId: String? = null,
|
||||
var kind: ComposeKind? = null,
|
||||
var initialCursorPosition: InitialCursorPosition = InitialCursorPosition.END,
|
||||
) : Parcelable
|
||||
|
||||
companion object {
|
||||
private const val PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1
|
||||
|
||||
|
@ -1360,20 +1308,6 @@ class ComposeActivity :
|
|||
private const val SCHEDULED_TIME_KEY = "SCHEDULE"
|
||||
private const val CONTENT_WARNING_VISIBLE_KEY = "CONTENT_WARNING_VISIBLE"
|
||||
|
||||
/**
|
||||
* @param options ComposeOptions to configure the ComposeActivity
|
||||
* @return an Intent to start the ComposeActivity
|
||||
*/
|
||||
@JvmStatic
|
||||
fun startIntent(
|
||||
context: Context,
|
||||
options: ComposeOptions,
|
||||
): Intent {
|
||||
return Intent(context, ComposeActivity::class.java).apply {
|
||||
putExtra(COMPOSE_OPTIONS_EXTRA, options)
|
||||
}
|
||||
}
|
||||
|
||||
fun canHandleMimeType(mimeType: String?): Boolean {
|
||||
return mimeType != null && (mimeType.startsWith("image/") || mimeType.startsWith("video/") || mimeType.startsWith("audio/") || mimeType == "text/plain")
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import android.net.Uri
|
|||
import androidx.core.net.toUri
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.pachli.components.compose.ComposeActivity.ComposeKind
|
||||
import app.pachli.components.compose.ComposeActivity.QueuedMedia
|
||||
import app.pachli.components.compose.ComposeAutoCompleteAdapter.AutocompleteResult
|
||||
import app.pachli.components.drafts.DraftHelper
|
||||
|
@ -29,6 +28,8 @@ import app.pachli.components.instanceinfo.InstanceInfoRepository
|
|||
import app.pachli.components.search.SearchType
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.common.string.randomAlphanumericString
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions.ComposeKind
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.core.network.model.Emoji
|
||||
import app.pachli.core.network.model.NewPoll
|
||||
|
@ -412,7 +413,7 @@ class ComposeViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun setup(composeOptions: ComposeActivity.ComposeOptions?) {
|
||||
fun setup(composeOptions: ComposeOptions?) {
|
||||
if (setupComplete) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -36,10 +36,11 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
||||
import app.pachli.R
|
||||
import app.pachli.StatusListActivity
|
||||
import app.pachli.adapter.StatusBaseViewHolder
|
||||
import app.pachli.appstore.EventHub
|
||||
import app.pachli.components.account.AccountActivity
|
||||
import app.pachli.core.navigation.AccountActivityIntent
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.preferences.PrefKeys
|
||||
import app.pachli.core.preferences.SharedPreferencesRepository
|
||||
import app.pachli.databinding.FragmentTimelineBinding
|
||||
|
@ -52,7 +53,6 @@ import app.pachli.util.hide
|
|||
import app.pachli.util.show
|
||||
import app.pachli.util.viewBinding
|
||||
import app.pachli.util.visible
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import at.connyduck.sparkbutton.helpers.Utils
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
|
@ -327,12 +327,12 @@ class ConversationsFragment :
|
|||
}
|
||||
|
||||
override fun onViewAccount(id: String) {
|
||||
val intent = AccountActivity.getIntent(requireContext(), id)
|
||||
val intent = AccountActivityIntent(requireContext(), id)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
override fun onViewTag(tag: String) {
|
||||
val intent = StatusListActivity.newHashtagIntent(requireContext(), tag)
|
||||
val intent = StatusListActivityIntent.hashtag(requireContext(), tag)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package app.pachli.components.drafts
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Toast
|
||||
|
@ -26,8 +25,9 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import app.pachli.BaseActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.components.compose.ComposeActivity
|
||||
import app.pachli.core.database.model.DraftEntity
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.network.parseAsMastodonHtml
|
||||
import app.pachli.databinding.ActivityDraftsBinding
|
||||
import app.pachli.db.DraftsAlert
|
||||
|
@ -106,7 +106,7 @@ class DraftsActivity : BaseActivity(), DraftActionListener {
|
|||
viewModel.getStatus(draft.inReplyToId!!)
|
||||
.fold(
|
||||
{ status ->
|
||||
val composeOptions = ComposeActivity.ComposeOptions(
|
||||
val composeOptions = ComposeOptions(
|
||||
draftId = draft.id,
|
||||
content = draft.content,
|
||||
contentWarning = draft.contentWarning,
|
||||
|
@ -120,12 +120,12 @@ class DraftsActivity : BaseActivity(), DraftActionListener {
|
|||
scheduledAt = draft.scheduledAt,
|
||||
language = draft.language,
|
||||
statusId = draft.statusId,
|
||||
kind = ComposeActivity.ComposeKind.EDIT_DRAFT,
|
||||
kind = ComposeOptions.ComposeKind.EDIT_DRAFT,
|
||||
)
|
||||
|
||||
bottomSheet.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
|
||||
startActivity(ComposeActivity.startIntent(context, composeOptions))
|
||||
startActivity(ComposeActivityIntent(context, composeOptions))
|
||||
},
|
||||
{ throwable ->
|
||||
bottomSheet.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
|
@ -147,7 +147,7 @@ class DraftsActivity : BaseActivity(), DraftActionListener {
|
|||
}
|
||||
|
||||
private fun openDraftWithoutReply(draft: DraftEntity) {
|
||||
val composeOptions = ComposeActivity.ComposeOptions(
|
||||
val composeOptions = ComposeOptions(
|
||||
draftId = draft.id,
|
||||
content = draft.content,
|
||||
contentWarning = draft.contentWarning,
|
||||
|
@ -158,10 +158,10 @@ class DraftsActivity : BaseActivity(), DraftActionListener {
|
|||
scheduledAt = draft.scheduledAt,
|
||||
language = draft.language,
|
||||
statusId = draft.statusId,
|
||||
kind = ComposeActivity.ComposeKind.EDIT_DRAFT,
|
||||
kind = ComposeOptions.ComposeKind.EDIT_DRAFT,
|
||||
)
|
||||
|
||||
startActivity(ComposeActivity.startIntent(this, composeOptions))
|
||||
startActivity(ComposeActivityIntent(this, composeOptions))
|
||||
}
|
||||
|
||||
override fun onDeleteDraft(draft: DraftEntity) {
|
||||
|
@ -172,8 +172,4 @@ class DraftsActivity : BaseActivity(), DraftActionListener {
|
|||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newIntent(context: Context) = Intent(context, DraftsActivity::class.java)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,13 @@ import android.widget.AdapterView
|
|||
import android.widget.ArrayAdapter
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.core.view.size
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import app.pachli.BaseActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.appstore.EventHub
|
||||
import app.pachli.core.navigation.EditFilterActivityIntent
|
||||
import app.pachli.core.network.model.Filter
|
||||
import app.pachli.core.network.model.FilterKeyword
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
|
@ -32,6 +32,9 @@ import retrofit2.HttpException
|
|||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Edit a single server-side filter.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class EditFilterActivity : BaseActivity() {
|
||||
@Inject
|
||||
|
@ -50,7 +53,7 @@ class EditFilterActivity : BaseActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
originalFilter = IntentCompat.getParcelableExtra(intent, FILTER_TO_EDIT, Filter::class.java)
|
||||
originalFilter = EditFilterActivityIntent.getFilter(intent)
|
||||
filter = originalFilter ?: Filter("", "", listOf(), null, Filter.Action.WARN.action, listOf())
|
||||
binding.apply {
|
||||
contextSwitches = mapOf(
|
||||
|
@ -295,8 +298,6 @@ class EditFilterActivity : BaseActivity() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
const val FILTER_TO_EDIT = "FilterToEdit"
|
||||
|
||||
// Mastodon *stores* the absolute date in the filter,
|
||||
// but create/edit take a number of seconds (relative to the time the operation is posted)
|
||||
fun getSecondsForDurationIndex(index: Int, context: Context?, default: Date? = null): Int? {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package app.pachli.components.filters
|
||||
|
||||
import android.content.DialogInterface.BUTTON_POSITIVE
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import app.pachli.BaseActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.core.navigation.EditFilterActivityIntent
|
||||
import app.pachli.core.network.model.Filter
|
||||
import app.pachli.databinding.ActivityFiltersBinding
|
||||
import app.pachli.util.hide
|
||||
|
@ -95,11 +95,7 @@ class FiltersActivity : BaseActivity(), FiltersListener {
|
|||
}
|
||||
|
||||
private fun launchEditFilterActivity(filter: Filter? = null) {
|
||||
val intent = Intent(this, EditFilterActivity::class.java).apply {
|
||||
if (filter != null) {
|
||||
putExtra(EditFilterActivity.FILTER_TO_EDIT, filter)
|
||||
}
|
||||
}
|
||||
val intent = EditFilterActivityIntent(this, filter)
|
||||
startActivity(intent)
|
||||
overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
|
|
|
@ -30,8 +30,9 @@ import androidx.core.net.toUri
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import app.pachli.BaseActivity
|
||||
import app.pachli.BuildConfig
|
||||
import app.pachli.MainActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.core.navigation.LoginActivityIntent
|
||||
import app.pachli.core.navigation.MainActivityIntent
|
||||
import app.pachli.core.network.model.AccessToken
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import app.pachli.core.preferences.getNonNullString
|
||||
|
@ -48,7 +49,11 @@ import okhttp3.HttpUrl
|
|||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Main login page, the first thing that users see. Has prompt for instance and login button. */
|
||||
/**
|
||||
* Main login page, the first thing that users see.
|
||||
*
|
||||
* Has prompt for instance and login button.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class LoginActivity : BaseActivity() {
|
||||
|
||||
|
@ -318,7 +323,7 @@ class LoginActivity : BaseActivity() {
|
|||
newAccount = newAccount,
|
||||
)
|
||||
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
val intent = MainActivityIntent(this)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
startActivity(intent)
|
||||
finish()
|
||||
|
@ -343,33 +348,19 @@ class LoginActivity : BaseActivity() {
|
|||
}
|
||||
|
||||
private fun isAdditionalLogin(): Boolean {
|
||||
return intent.getIntExtra(LOGIN_MODE, MODE_DEFAULT) == MODE_ADDITIONAL_LOGIN
|
||||
return LoginActivityIntent.getLoginMode(intent) == LoginActivityIntent.LoginMode.ADDITIONAL_LOGIN
|
||||
}
|
||||
|
||||
private fun isAccountMigration(): Boolean {
|
||||
return intent.getIntExtra(LOGIN_MODE, MODE_DEFAULT) == MODE_MIGRATION
|
||||
return LoginActivityIntent.getLoginMode(intent) == LoginActivityIntent.LoginMode.MIGRATION
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val OAUTH_SCOPES = "read write follow push"
|
||||
private const val LOGIN_MODE = "LOGIN_MODE"
|
||||
private const val DOMAIN = "domain"
|
||||
private const val CLIENT_ID = "clientId"
|
||||
private const val CLIENT_SECRET = "clientSecret"
|
||||
|
||||
const val MODE_DEFAULT = 0
|
||||
const val MODE_ADDITIONAL_LOGIN = 1
|
||||
|
||||
// "Migration" is used to update the OAuth scope granted to the client
|
||||
const val MODE_MIGRATION = 2
|
||||
|
||||
@JvmStatic
|
||||
fun getIntent(context: Context, mode: Int): Intent {
|
||||
val loginIntent = Intent(context, LoginActivity::class.java)
|
||||
loginIntent.putExtra(LOGIN_MODE, mode)
|
||||
return loginIntent
|
||||
}
|
||||
|
||||
/** Make sure the user-entered text is just a fully-qualified domain name. */
|
||||
private fun canonicalizeDomain(domain: String): String {
|
||||
// Strip any schemes out.
|
||||
|
|
|
@ -39,6 +39,7 @@ import androidx.lifecycle.lifecycleScope
|
|||
import app.pachli.BaseActivity
|
||||
import app.pachli.BuildConfig
|
||||
import app.pachli.R
|
||||
import app.pachli.core.navigation.LoginWebViewActivityIntent
|
||||
import app.pachli.databinding.ActivityLoginWebviewBinding
|
||||
import app.pachli.util.hide
|
||||
import app.pachli.util.viewBinding
|
||||
|
@ -51,7 +52,7 @@ import timber.log.Timber
|
|||
/** Contract for starting [LoginWebViewActivity]. */
|
||||
class OauthLogin : ActivityResultContract<LoginData, LoginResult>() {
|
||||
override fun createIntent(context: Context, input: LoginData): Intent {
|
||||
val intent = Intent(context, LoginWebViewActivity::class.java)
|
||||
val intent = LoginWebViewActivityIntent(context)
|
||||
intent.putExtra(DATA_EXTRA, input)
|
||||
return intent
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package app.pachli.components.notifications
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationChannelGroup
|
||||
import android.app.NotificationManager
|
||||
|
@ -44,10 +45,10 @@ import app.pachli.MainActivity
|
|||
import app.pachli.MainActivity.Companion.composeIntent
|
||||
import app.pachli.MainActivity.Companion.openNotificationIntent
|
||||
import app.pachli.R
|
||||
import app.pachli.components.compose.ComposeActivity
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.common.string.unicodeWrap
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.parseAsMastodonHtml
|
||||
import app.pachli.receiver.SendStatusBroadcastReceiver
|
||||
|
@ -382,6 +383,9 @@ private fun getStatusReplyIntent(
|
|||
}
|
||||
mentionedUsernames.removeAll(setOf(account.username))
|
||||
mentionedUsernames = ArrayList(LinkedHashSet(mentionedUsernames))
|
||||
|
||||
// TODO: Revisit suppressing this when this file is moved
|
||||
@SuppressLint("IntentDetector")
|
||||
val replyIntent = Intent(context, SendStatusBroadcastReceiver::class.java)
|
||||
.setAction(REPLY_ACTION)
|
||||
.putExtra(KEY_SENDER_ACCOUNT_ID, account.id)
|
||||
|
@ -417,16 +421,17 @@ private fun getStatusComposeIntent(
|
|||
mentionedUsernames.add(mentionedUsername)
|
||||
}
|
||||
}
|
||||
val composeOptions = ComposeActivity.ComposeOptions()
|
||||
composeOptions.inReplyToId = inReplyToId
|
||||
composeOptions.replyVisibility = replyVisibility
|
||||
composeOptions.contentWarning = contentWarning
|
||||
composeOptions.replyingStatusAuthor = citedLocalAuthor
|
||||
composeOptions.replyingStatusContent = citedText
|
||||
composeOptions.mentionedUsernames = mentionedUsernames
|
||||
composeOptions.modifiedInitialState = true
|
||||
composeOptions.language = language
|
||||
composeOptions.kind = ComposeActivity.ComposeKind.NEW
|
||||
val composeOptions = ComposeOptions(
|
||||
inReplyToId = inReplyToId,
|
||||
replyVisibility = replyVisibility,
|
||||
contentWarning = contentWarning,
|
||||
replyingStatusAuthor = citedLocalAuthor,
|
||||
replyingStatusContent = citedText,
|
||||
mentionedUsernames = mentionedUsernames,
|
||||
modifiedInitialState = true,
|
||||
language = language,
|
||||
kind = ComposeOptions.ComposeKind.NEW,
|
||||
)
|
||||
val composeIntent =
|
||||
composeIntent(context, composeOptions, account.id, body.id, account.id.toInt())
|
||||
composeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
|
|
|
@ -46,6 +46,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
|||
import app.pachli.R
|
||||
import app.pachli.adapter.StatusBaseViewHolder
|
||||
import app.pachli.components.timeline.TimelineLoadStateAdapter
|
||||
import app.pachli.core.navigation.AttachmentViewData.Companion.list
|
||||
import app.pachli.core.network.model.Filter
|
||||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.model.Status
|
||||
|
@ -63,7 +64,6 @@ import app.pachli.util.openLink
|
|||
import app.pachli.util.show
|
||||
import app.pachli.util.viewBinding
|
||||
import app.pachli.util.visible
|
||||
import app.pachli.viewdata.AttachmentViewData.Companion.list
|
||||
import app.pachli.viewdata.NotificationViewData
|
||||
import at.connyduck.sparkbutton.helpers.Utils
|
||||
import com.google.android.material.color.MaterialColors
|
||||
|
|
|
@ -22,9 +22,10 @@ import android.os.Build
|
|||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import app.pachli.R
|
||||
import app.pachli.components.login.LoginActivity
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.navigation.LoginActivityIntent
|
||||
import app.pachli.core.navigation.LoginActivityIntent.LoginMode
|
||||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import app.pachli.core.preferences.SharedPreferencesRepository
|
||||
|
@ -78,7 +79,12 @@ private fun showMigrationExplanationDialog(
|
|||
if (currentAccountNeedsMigration(accountManager)) {
|
||||
setMessage(R.string.dialog_push_notification_migration)
|
||||
setPositiveButton(R.string.title_migration_relogin) { _, _ ->
|
||||
context.startActivity(LoginActivity.getIntent(context, LoginActivity.MODE_MIGRATION))
|
||||
context.startActivity(
|
||||
LoginActivityIntent(
|
||||
context,
|
||||
LoginMode.MIGRATION,
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
setMessage(R.string.dialog_push_notification_migration_other_accounts)
|
||||
|
|
|
@ -24,15 +24,18 @@ import androidx.preference.PreferenceFragmentCompat
|
|||
import app.pachli.BaseActivity
|
||||
import app.pachli.BuildConfig
|
||||
import app.pachli.R
|
||||
import app.pachli.TabPreferenceActivity
|
||||
import app.pachli.appstore.EventHub
|
||||
import app.pachli.components.accountlist.AccountListActivity
|
||||
import app.pachli.components.filters.FiltersActivity
|
||||
import app.pachli.components.followedtags.FollowedTagsActivity
|
||||
import app.pachli.components.instancemute.InstanceListActivity
|
||||
import app.pachli.components.login.LoginActivity
|
||||
import app.pachli.components.notifications.currentAccountNeedsMigration
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.navigation.AccountListActivityIntent
|
||||
import app.pachli.core.navigation.FiltersActivityIntent
|
||||
import app.pachli.core.navigation.FollowedTagsActivityIntent
|
||||
import app.pachli.core.navigation.InstanceListActivityIntent
|
||||
import app.pachli.core.navigation.LoginActivityIntent
|
||||
import app.pachli.core.navigation.LoginActivityIntent.LoginMode
|
||||
import app.pachli.core.navigation.PreferencesActivityIntent
|
||||
import app.pachli.core.navigation.PreferencesActivityIntent.PreferenceScreen
|
||||
import app.pachli.core.navigation.TabPreferenceActivityIntent
|
||||
import app.pachli.core.network.model.Account
|
||||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
|
@ -90,7 +93,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat() {
|
|||
setTitle(R.string.title_tab_preferences)
|
||||
setIcon(R.drawable.ic_tabs)
|
||||
setOnPreferenceClickListener {
|
||||
val intent = Intent(context, TabPreferenceActivity::class.java)
|
||||
val intent = TabPreferenceActivityIntent(context)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(
|
||||
R.anim.slide_from_right,
|
||||
|
@ -104,7 +107,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat() {
|
|||
setTitle(R.string.title_followed_hashtags)
|
||||
setIcon(R.drawable.ic_hashtag)
|
||||
setOnPreferenceClickListener {
|
||||
val intent = Intent(context, FollowedTagsActivity::class.java)
|
||||
val intent = FollowedTagsActivityIntent(context)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(
|
||||
R.anim.slide_from_right,
|
||||
|
@ -118,8 +121,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat() {
|
|||
setTitle(R.string.action_view_mutes)
|
||||
setIcon(R.drawable.ic_mute_24dp)
|
||||
setOnPreferenceClickListener {
|
||||
val intent = Intent(context, AccountListActivity::class.java)
|
||||
intent.putExtra("type", AccountListActivity.Type.MUTES)
|
||||
val intent = AccountListActivityIntent(context, AccountListActivityIntent.Kind.MUTES)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(
|
||||
R.anim.slide_from_right,
|
||||
|
@ -133,8 +135,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat() {
|
|||
setTitle(R.string.action_view_blocks)
|
||||
icon = makeIcon(GoogleMaterial.Icon.gmd_block)
|
||||
setOnPreferenceClickListener {
|
||||
val intent = Intent(context, AccountListActivity::class.java)
|
||||
intent.putExtra("type", AccountListActivity.Type.BLOCKS)
|
||||
val intent = AccountListActivityIntent(context, AccountListActivityIntent.Kind.BLOCKS)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(
|
||||
R.anim.slide_from_right,
|
||||
|
@ -148,7 +149,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat() {
|
|||
setTitle(R.string.title_domain_mutes)
|
||||
setIcon(R.drawable.ic_mute_24dp)
|
||||
setOnPreferenceClickListener {
|
||||
val intent = Intent(context, InstanceListActivity::class.java)
|
||||
val intent = InstanceListActivityIntent(context)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(
|
||||
R.anim.slide_from_right,
|
||||
|
@ -163,7 +164,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat() {
|
|||
setTitle(R.string.title_migration_relogin)
|
||||
setIcon(R.drawable.ic_logout)
|
||||
setOnPreferenceClickListener {
|
||||
val intent = LoginActivity.getIntent(context, LoginActivity.MODE_MIGRATION)
|
||||
val intent = LoginActivityIntent(context, LoginMode.MIGRATION)
|
||||
(activity as BaseActivity).startActivityWithSlideInAnimation(intent)
|
||||
true
|
||||
}
|
||||
|
@ -280,7 +281,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat() {
|
|||
} else {
|
||||
activity?.let {
|
||||
val intent =
|
||||
PreferencesActivity.newIntent(it, PreferencesActivity.NOTIFICATION_PREFERENCES)
|
||||
PreferencesActivityIntent(it, PreferenceScreen.NOTIFICATION)
|
||||
it.startActivity(intent)
|
||||
it.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
|
@ -346,7 +347,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
|
||||
private fun launchFilterActivity() {
|
||||
val intent = Intent(context, FiltersActivity::class.java)
|
||||
val intent = FiltersActivityIntent(requireContext())
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package app.pachli.components.preference
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
|
@ -26,9 +25,11 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import app.pachli.BaseActivity
|
||||
import app.pachli.MainActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.appstore.EventHub
|
||||
import app.pachli.core.navigation.MainActivityIntent
|
||||
import app.pachli.core.navigation.PreferencesActivityIntent
|
||||
import app.pachli.core.navigation.PreferencesActivityIntent.PreferenceScreen
|
||||
import app.pachli.core.preferences.PrefKeys
|
||||
import app.pachli.core.preferences.PrefKeys.APP_THEME
|
||||
import app.pachli.core.preferences.getNonNullString
|
||||
|
@ -41,6 +42,9 @@ import kotlinx.coroutines.launch
|
|||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Show specific preferences.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class PreferencesActivity :
|
||||
BaseActivity(),
|
||||
|
@ -55,7 +59,7 @@ class PreferencesActivity :
|
|||
* Either the back stack activities need to all be recreated, or do the easier thing, which
|
||||
* is hijack the back button press and use it to launch a new MainActivity and clear the
|
||||
* back stack. */
|
||||
val intent = Intent(this@PreferencesActivity, MainActivity::class.java)
|
||||
val intent = MainActivityIntent(this@PreferencesActivity)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
|
@ -73,15 +77,15 @@ class PreferencesActivity :
|
|||
setDisplayShowHomeEnabled(true)
|
||||
}
|
||||
|
||||
val preferenceType = intent.getIntExtra(EXTRA_PREFERENCE_TYPE, 0)
|
||||
val preferenceType = PreferencesActivityIntent.getPreferenceType(intent)
|
||||
|
||||
val fragmentTag = "preference_fragment_$preferenceType"
|
||||
|
||||
val fragment: Fragment = supportFragmentManager.findFragmentByTag(fragmentTag)
|
||||
?: when (preferenceType) {
|
||||
GENERAL_PREFERENCES -> PreferencesFragment.newInstance()
|
||||
ACCOUNT_PREFERENCES -> AccountPreferencesFragment.newInstance()
|
||||
NOTIFICATION_PREFERENCES -> NotificationPreferencesFragment.newInstance()
|
||||
PreferenceScreen.GENERAL -> PreferencesFragment.newInstance()
|
||||
PreferenceScreen.ACCOUNT -> AccountPreferencesFragment.newInstance()
|
||||
PreferenceScreen.NOTIFICATION -> NotificationPreferencesFragment.newInstance()
|
||||
else -> throw IllegalArgumentException("preferenceType not known")
|
||||
}
|
||||
|
||||
|
@ -164,17 +168,6 @@ class PreferencesActivity :
|
|||
}
|
||||
|
||||
companion object {
|
||||
const val GENERAL_PREFERENCES = 0
|
||||
const val ACCOUNT_PREFERENCES = 1
|
||||
const val NOTIFICATION_PREFERENCES = 2
|
||||
private const val EXTRA_PREFERENCE_TYPE = "EXTRA_PREFERENCE_TYPE"
|
||||
private const val EXTRA_RESTART_ON_BACK = "restart"
|
||||
|
||||
@JvmStatic
|
||||
fun newIntent(context: Context, preferenceType: Int): Intent {
|
||||
val intent = Intent(context, PreferencesActivity::class.java)
|
||||
intent.putExtra(EXTRA_PREFERENCE_TYPE, preferenceType)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,17 +16,19 @@
|
|||
|
||||
package app.pachli.components.report
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import app.pachli.BottomSheetActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.components.report.adapter.ReportPagerAdapter
|
||||
import app.pachli.core.navigation.ReportActivityIntent
|
||||
import app.pachli.databinding.ActivityReportBinding
|
||||
import app.pachli.util.viewBinding
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
/**
|
||||
* Report a status or user.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class ReportActivity : BottomSheetActivity() {
|
||||
private val viewModel: ReportViewModel by viewModels()
|
||||
|
@ -35,13 +37,13 @@ class ReportActivity : BottomSheetActivity() {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val accountId = intent?.getStringExtra(ACCOUNT_ID)
|
||||
val accountUserName = intent?.getStringExtra(ACCOUNT_USERNAME)
|
||||
if (accountId.isNullOrBlank() || accountUserName.isNullOrBlank()) {
|
||||
throw IllegalStateException("accountId ($accountId) or accountUserName ($accountUserName) is null")
|
||||
val accountId = ReportActivityIntent.getAccountId(intent)
|
||||
val accountUserName = ReportActivityIntent.getAccountUserName(intent)
|
||||
if (accountId.isBlank() || accountUserName.isBlank()) {
|
||||
throw IllegalStateException("accountId ($accountId) or accountUserName ($accountUserName) is blank")
|
||||
}
|
||||
|
||||
viewModel.init(accountId, accountUserName, intent?.getStringExtra(STATUS_ID))
|
||||
viewModel.init(accountId, accountUserName, ReportActivityIntent.getStatusId(intent))
|
||||
|
||||
setContentView(binding.root)
|
||||
|
||||
|
@ -115,19 +117,4 @@ class ReportActivity : BottomSheetActivity() {
|
|||
private fun showStatusesPage() {
|
||||
binding.wizard.currentItem = 0
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ACCOUNT_ID = "account_id"
|
||||
private const val ACCOUNT_USERNAME = "account_username"
|
||||
private const val STATUS_ID = "status_id"
|
||||
|
||||
@JvmStatic
|
||||
fun getIntent(context: Context, accountId: String, userName: String, statusId: String? = null) =
|
||||
Intent(context, ReportActivity::class.java)
|
||||
.apply {
|
||||
putExtra(ACCOUNT_ID, accountId)
|
||||
putExtra(ACCOUNT_USERNAME, userName)
|
||||
putExtra(STATUS_ID, statusId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,20 +33,20 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
||||
import app.pachli.R
|
||||
import app.pachli.StatusListActivity
|
||||
import app.pachli.ViewMediaActivity
|
||||
import app.pachli.components.account.AccountActivity
|
||||
import app.pachli.components.report.ReportViewModel
|
||||
import app.pachli.components.report.Screen
|
||||
import app.pachli.components.report.adapter.AdapterHandler
|
||||
import app.pachli.components.report.adapter.StatusesAdapter
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.navigation.AccountActivityIntent
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.navigation.ViewMediaActivityIntent
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.databinding.FragmentReportStatusesBinding
|
||||
import app.pachli.util.viewBinding
|
||||
import app.pachli.util.visible
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
@ -82,7 +82,7 @@ class ReportStatusesFragment :
|
|||
when (actionable.attachments[idx].type) {
|
||||
Attachment.Type.GIFV, Attachment.Type.VIDEO, Attachment.Type.IMAGE, Attachment.Type.AUDIO -> {
|
||||
val attachments = AttachmentViewData.list(actionable)
|
||||
val intent = ViewMediaActivity.newIntent(context, attachments, idx)
|
||||
val intent = ViewMediaActivityIntent(requireContext(), attachments, idx)
|
||||
if (v != null) {
|
||||
val url = actionable.attachments[idx].url
|
||||
ViewCompat.setTransitionName(v, url)
|
||||
|
@ -209,9 +209,9 @@ class ReportStatusesFragment :
|
|||
return viewModel.isStatusChecked(id)
|
||||
}
|
||||
|
||||
override fun onViewAccount(id: String) = startActivity(AccountActivity.getIntent(requireContext(), id))
|
||||
override fun onViewAccount(id: String) = startActivity(AccountActivityIntent(requireContext(), id))
|
||||
|
||||
override fun onViewTag(tag: String) = startActivity(StatusListActivity.newHashtagIntent(requireContext(), tag))
|
||||
override fun onViewTag(tag: String) = startActivity(StatusListActivityIntent.hashtag(requireContext(), tag))
|
||||
|
||||
override fun onViewUrl(url: String) = viewModel.checkClickedUrl(url)
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package app.pachli.components.scheduled
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
|
@ -32,7 +30,8 @@ import app.pachli.BaseActivity
|
|||
import app.pachli.R
|
||||
import app.pachli.appstore.EventHub
|
||||
import app.pachli.appstore.StatusScheduledEvent
|
||||
import app.pachli.components.compose.ComposeActivity
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.network.model.ScheduledStatus
|
||||
import app.pachli.databinding.ActivityScheduledStatusBinding
|
||||
import app.pachli.util.hide
|
||||
|
@ -151,9 +150,9 @@ class ScheduledStatusActivity :
|
|||
}
|
||||
|
||||
override fun edit(item: ScheduledStatus) {
|
||||
val intent = ComposeActivity.startIntent(
|
||||
val intent = ComposeActivityIntent(
|
||||
this,
|
||||
ComposeActivity.ComposeOptions(
|
||||
ComposeOptions(
|
||||
scheduledTootId = item.id,
|
||||
content = item.params.text,
|
||||
contentWarning = item.params.spoilerText,
|
||||
|
@ -162,7 +161,7 @@ class ScheduledStatusActivity :
|
|||
visibility = item.params.visibility,
|
||||
scheduledAt = item.scheduledAt,
|
||||
sensitive = item.params.sensitive,
|
||||
kind = ComposeActivity.ComposeKind.EDIT_SCHEDULED,
|
||||
kind = ComposeOptions.ComposeKind.EDIT_SCHEDULED,
|
||||
),
|
||||
)
|
||||
startActivity(intent)
|
||||
|
@ -177,8 +176,4 @@ class ScheduledStatusActivity :
|
|||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newIntent(context: Context) = Intent(context, ScheduledStatusActivity::class.java)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,8 +153,4 @@ class SearchActivity : BottomSheetActivity(), MenuProvider, SearchView.OnQueryTe
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context) = Intent(context, SearchActivity::class.java)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ import androidx.recyclerview.widget.SimpleItemAnimator
|
|||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import app.pachli.BottomSheetActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.StatusListActivity
|
||||
import app.pachli.components.account.AccountActivity
|
||||
import app.pachli.components.search.SearchViewModel
|
||||
import app.pachli.core.navigation.AccountActivityIntent
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.network.retrofit.MastodonApi
|
||||
import app.pachli.databinding.FragmentSearchBinding
|
||||
import app.pachli.interfaces.LinkListener
|
||||
|
@ -141,11 +141,11 @@ abstract class SearchFragment<T : Any> :
|
|||
}
|
||||
|
||||
override fun onViewAccount(id: String) {
|
||||
bottomSheetActivity?.startActivityWithSlideInAnimation(AccountActivity.getIntent(requireContext(), id))
|
||||
bottomSheetActivity?.startActivityWithSlideInAnimation(AccountActivityIntent(requireContext(), id))
|
||||
}
|
||||
|
||||
override fun onViewTag(tag: String) {
|
||||
bottomSheetActivity?.startActivityWithSlideInAnimation(StatusListActivity.newHashtagIntent(requireContext(), tag))
|
||||
bottomSheetActivity?.startActivityWithSlideInAnimation(StatusListActivityIntent.hashtag(requireContext(), tag))
|
||||
}
|
||||
|
||||
override fun onViewUrl(url: String) {
|
||||
|
|
|
@ -38,12 +38,13 @@ import androidx.paging.PagingDataAdapter
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import app.pachli.BaseActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.ViewMediaActivity
|
||||
import app.pachli.components.compose.ComposeActivity
|
||||
import app.pachli.components.compose.ComposeActivity.ComposeOptions
|
||||
import app.pachli.components.report.ReportActivity
|
||||
import app.pachli.components.search.adapter.SearchStatusesAdapter
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.navigation.ReportActivityIntent
|
||||
import app.pachli.core.navigation.ViewMediaActivityIntent
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.network.model.Status.Mention
|
||||
|
@ -52,7 +53,6 @@ import app.pachli.interfaces.StatusActionListener
|
|||
import app.pachli.util.StatusDisplayOptionsRepository
|
||||
import app.pachli.util.openLink
|
||||
import app.pachli.view.showMuteAccountDialog
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import app.pachli.viewdata.StatusViewData
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
|
@ -119,8 +119,8 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
|||
when (actionable.attachments[attachmentIndex].type) {
|
||||
Attachment.Type.GIFV, Attachment.Type.VIDEO, Attachment.Type.IMAGE, Attachment.Type.AUDIO -> {
|
||||
val attachments = AttachmentViewData.list(actionable)
|
||||
val intent = ViewMediaActivity.newIntent(
|
||||
context,
|
||||
val intent = ViewMediaActivityIntent(
|
||||
requireContext(),
|
||||
attachments,
|
||||
attachmentIndex,
|
||||
)
|
||||
|
@ -202,7 +202,7 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
|||
remove(viewModel.activeAccount?.username)
|
||||
}
|
||||
|
||||
val intent = ComposeActivity.startIntent(
|
||||
val intent = ComposeActivityIntent(
|
||||
requireContext(),
|
||||
ComposeOptions(
|
||||
inReplyToId = status.actionableId,
|
||||
|
@ -212,7 +212,7 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
|||
replyingStatusAuthor = actionableStatus.account.localUsername,
|
||||
replyingStatusContent = status.content.toString(),
|
||||
language = actionableStatus.language,
|
||||
kind = ComposeActivity.ComposeKind.NEW,
|
||||
kind = ComposeOptions.ComposeKind.NEW,
|
||||
),
|
||||
)
|
||||
bottomSheetActivity?.startActivityWithSlideInAnimation(intent)
|
||||
|
@ -423,7 +423,7 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
|||
}
|
||||
|
||||
private fun openReportPage(accountId: String, accountUsername: String, statusId: String) {
|
||||
startActivity(ReportActivity.getIntent(requireContext(), accountId, accountUsername, statusId))
|
||||
startActivity(ReportActivityIntent(requireContext(), accountId, accountUsername, statusId))
|
||||
}
|
||||
|
||||
private fun showConfirmDeleteDialog(id: String, position: Int) {
|
||||
|
@ -455,7 +455,7 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
|||
deletedStatus
|
||||
}
|
||||
|
||||
val intent = ComposeActivity.startIntent(
|
||||
val intent = ComposeActivityIntent(
|
||||
requireContext(),
|
||||
ComposeOptions(
|
||||
content = redraftStatus.text.orEmpty(),
|
||||
|
@ -466,7 +466,7 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
|||
sensitive = redraftStatus.sensitive,
|
||||
poll = redraftStatus.poll?.toNewPoll(status.createdAt),
|
||||
language = redraftStatus.language,
|
||||
kind = ComposeActivity.ComposeKind.NEW,
|
||||
kind = ComposeOptions.ComposeKind.NEW,
|
||||
),
|
||||
)
|
||||
startActivity(intent)
|
||||
|
@ -497,9 +497,9 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
|||
language = status.language,
|
||||
statusId = source.id,
|
||||
poll = status.poll?.toNewPoll(status.createdAt),
|
||||
kind = ComposeActivity.ComposeKind.EDIT_POSTED,
|
||||
kind = ComposeOptions.ComposeKind.EDIT_POSTED,
|
||||
)
|
||||
startActivity(ComposeActivity.startIntent(requireContext(), composeOptions))
|
||||
startActivity(ComposeActivityIntent(requireContext(), composeOptions))
|
||||
},
|
||||
{
|
||||
Snackbar.make(
|
||||
|
|
|
@ -42,8 +42,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
|||
import app.pachli.BaseActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.adapter.StatusBaseViewHolder
|
||||
import app.pachli.components.accountlist.AccountListActivity
|
||||
import app.pachli.components.accountlist.AccountListActivity.Companion.newIntent
|
||||
import app.pachli.components.timeline.viewmodel.CachedTimelineViewModel
|
||||
import app.pachli.components.timeline.viewmodel.InfallibleUiAction
|
||||
import app.pachli.components.timeline.viewmodel.NetworkTimelineViewModel
|
||||
|
@ -52,6 +50,8 @@ import app.pachli.components.timeline.viewmodel.StatusActionSuccess
|
|||
import app.pachli.components.timeline.viewmodel.TimelineViewModel
|
||||
import app.pachli.components.timeline.viewmodel.UiSuccess
|
||||
import app.pachli.core.database.model.TranslationState
|
||||
import app.pachli.core.navigation.AccountListActivityIntent
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.network.model.TimelineKind
|
||||
import app.pachli.databinding.FragmentTimelineBinding
|
||||
|
@ -72,7 +72,6 @@ import app.pachli.util.show
|
|||
import app.pachli.util.viewBinding
|
||||
import app.pachli.util.visible
|
||||
import app.pachli.util.withPresentationState
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import app.pachli.viewdata.StatusViewData
|
||||
import at.connyduck.sparkbutton.helpers.Utils
|
||||
import com.google.android.material.color.MaterialColors
|
||||
|
@ -635,13 +634,13 @@ class TimelineFragment :
|
|||
|
||||
override fun onShowReblogs(position: Int) {
|
||||
val statusId = adapter.peek(position)?.id ?: return
|
||||
val intent = newIntent(requireContext(), AccountListActivity.Type.REBLOGGED, statusId)
|
||||
val intent = AccountListActivityIntent(requireContext(), AccountListActivityIntent.Kind.REBLOGGED, statusId)
|
||||
(activity as BaseActivity).startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
|
||||
override fun onShowFavs(position: Int) {
|
||||
val statusId = adapter.peek(position)?.id ?: return
|
||||
val intent = newIntent(requireContext(), AccountListActivity.Type.FAVOURITED, statusId)
|
||||
val intent = AccountListActivityIntent(requireContext(), AccountListActivityIntent.Kind.FAVOURITED, statusId)
|
||||
(activity as BaseActivity).startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
package app.pachli.components.trending
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
|
@ -86,10 +84,6 @@ class TrendingActivity : BottomSheetActivity(), AppBarLayoutHost, MenuProvider {
|
|||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
return super.onOptionsItemSelected(menuItem)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context) = Intent(context, TrendingActivity::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
class TrendingFragmentAdapter(val activity: FragmentActivity) : FragmentStateAdapter(activity) {
|
||||
|
|
|
@ -38,8 +38,8 @@ import androidx.recyclerview.widget.SimpleItemAnimator
|
|||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
||||
import app.pachli.BaseActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.StatusListActivity
|
||||
import app.pachli.components.trending.viewmodel.TrendingTagsViewModel
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.databinding.FragmentTrendingTagsBinding
|
||||
import app.pachli.interfaces.ActionButtonActivity
|
||||
import app.pachli.interfaces.AppBarLayoutHost
|
||||
|
@ -173,7 +173,7 @@ class TrendingTagsFragment :
|
|||
|
||||
fun onViewTag(tag: String) {
|
||||
(requireActivity() as BaseActivity).startActivityWithSlideInAnimation(
|
||||
StatusListActivity.newHashtagIntent(
|
||||
StatusListActivityIntent.hashtag(
|
||||
requireContext(),
|
||||
tag,
|
||||
),
|
||||
|
|
|
@ -16,16 +16,18 @@
|
|||
|
||||
package app.pachli.components.viewthread
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.commit
|
||||
import app.pachli.BottomSheetActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.core.navigation.ViewThreadActivityIntent
|
||||
import app.pachli.databinding.ActivityViewThreadBinding
|
||||
import app.pachli.util.viewBinding
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
/**
|
||||
* View the statuses in a single thread.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class ViewThreadActivity : BottomSheetActivity() {
|
||||
private val binding by viewBinding(ActivityViewThreadBinding::inflate)
|
||||
|
@ -39,8 +41,8 @@ class ViewThreadActivity : BottomSheetActivity() {
|
|||
setDisplayShowHomeEnabled(true)
|
||||
setDisplayShowTitleEnabled(true)
|
||||
}
|
||||
val id = intent.getStringExtra(ID_EXTRA)!!
|
||||
val url = intent.getStringExtra(URL_EXTRA)!!
|
||||
val id = ViewThreadActivityIntent.getStatusId(intent)
|
||||
val url = ViewThreadActivityIntent.getUrl(intent)
|
||||
val fragment =
|
||||
supportFragmentManager.findFragmentByTag(FRAGMENT_TAG + id) as ViewThreadFragment?
|
||||
?: ViewThreadFragment.newInstance(id, url)
|
||||
|
@ -51,15 +53,6 @@ class ViewThreadActivity : BottomSheetActivity() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
fun startIntent(context: Context, id: String, url: String): Intent {
|
||||
val intent = Intent(context, ViewThreadActivity::class.java)
|
||||
intent.putExtra(ID_EXTRA, id)
|
||||
intent.putExtra(URL_EXTRA, url)
|
||||
return intent
|
||||
}
|
||||
|
||||
private const val ID_EXTRA = "id"
|
||||
private const val URL_EXTRA = "url"
|
||||
private const val FRAGMENT_TAG = "ViewThreadFragment_"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ import androidx.recyclerview.widget.SimpleItemAnimator
|
|||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
||||
import app.pachli.BaseActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.components.accountlist.AccountListActivity
|
||||
import app.pachli.components.accountlist.AccountListActivity.Companion.newIntent
|
||||
import app.pachli.components.viewthread.edits.ViewEditsFragment
|
||||
import app.pachli.core.navigation.AccountListActivityIntent
|
||||
import app.pachli.core.navigation.AttachmentViewData.Companion.list
|
||||
import app.pachli.databinding.FragmentViewThreadBinding
|
||||
import app.pachli.fragment.SFragment
|
||||
import app.pachli.interfaces.StatusActionListener
|
||||
|
@ -45,7 +45,6 @@ import app.pachli.util.hide
|
|||
import app.pachli.util.openLink
|
||||
import app.pachli.util.show
|
||||
import app.pachli.util.viewBinding
|
||||
import app.pachli.viewdata.AttachmentViewData.Companion.list
|
||||
import app.pachli.viewdata.StatusViewData
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||
|
@ -366,13 +365,13 @@ class ViewThreadFragment :
|
|||
|
||||
override fun onShowReblogs(position: Int) {
|
||||
val statusId = adapter.currentList[position].id
|
||||
val intent = newIntent(requireContext(), AccountListActivity.Type.REBLOGGED, statusId)
|
||||
val intent = AccountListActivityIntent(requireContext(), AccountListActivityIntent.Kind.REBLOGGED, statusId)
|
||||
(requireActivity() as BaseActivity).startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
|
||||
override fun onShowFavs(position: Int) {
|
||||
val statusId = adapter.currentList[position].id
|
||||
val intent = newIntent(requireContext(), AccountListActivity.Type.FAVOURITED, statusId)
|
||||
val intent = AccountListActivityIntent(requireContext(), AccountListActivityIntent.Kind.FAVOURITED, statusId)
|
||||
(requireActivity() as BaseActivity).startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
|
||||
|
@ -423,7 +422,7 @@ class ViewThreadFragment :
|
|||
private const val ID_EXTRA = "id"
|
||||
private const val URL_EXTRA = "url"
|
||||
|
||||
fun newInstance(id: String, url: String): ViewThreadFragment {
|
||||
fun newInstance(id: String, url: String?): ViewThreadFragment {
|
||||
val arguments = Bundle(2)
|
||||
val fragment = ViewThreadFragment()
|
||||
arguments.putString(ID_EXTRA, id)
|
||||
|
|
|
@ -31,9 +31,9 @@ import androidx.recyclerview.widget.SimpleItemAnimator
|
|||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
||||
import app.pachli.BottomSheetActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.StatusListActivity
|
||||
import app.pachli.components.account.AccountActivity
|
||||
import app.pachli.core.common.string.unicodeWrap
|
||||
import app.pachli.core.navigation.AccountActivityIntent
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.preferences.PrefKeys
|
||||
import app.pachli.core.preferences.SharedPreferencesRepository
|
||||
import app.pachli.databinding.FragmentViewEditsBinding
|
||||
|
@ -184,11 +184,11 @@ class ViewEditsFragment :
|
|||
}
|
||||
|
||||
override fun onViewAccount(id: String) {
|
||||
bottomSheetActivity?.startActivityWithSlideInAnimation(AccountActivity.getIntent(requireContext(), id))
|
||||
bottomSheetActivity?.startActivityWithSlideInAnimation(AccountActivityIntent(requireContext(), id))
|
||||
}
|
||||
|
||||
override fun onViewTag(tag: String) {
|
||||
bottomSheetActivity?.startActivityWithSlideInAnimation(StatusListActivity.newHashtagIntent(requireContext(), tag))
|
||||
bottomSheetActivity?.startActivityWithSlideInAnimation(StatusListActivityIntent.hashtag(requireContext(), tag))
|
||||
}
|
||||
|
||||
override fun onViewUrl(url: String) {
|
||||
|
|
|
@ -23,9 +23,9 @@ import androidx.lifecycle.LifecycleCoroutineScope
|
|||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import app.pachli.R
|
||||
import app.pachli.components.drafts.DraftsActivity
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.database.dao.DraftDao
|
||||
import app.pachli.core.navigation.DraftsActivityIntent
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
@ -66,7 +66,7 @@ class DraftsAlert @Inject constructor(private val draftDao: DraftDao) {
|
|||
.setPositiveButton(R.string.action_post_failed_show_drafts) { _: DialogInterface?, _: Int ->
|
||||
clearDraftsAlert(coroutineScope, activeAccountId) // User looked at drafts
|
||||
|
||||
val intent = DraftsActivity.newIntent(context)
|
||||
val intent = DraftsActivityIntent(context)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
.setNegativeButton(R.string.action_post_failed_do_nothing) { _: DialogInterface?, _: Int ->
|
||||
|
|
|
@ -42,15 +42,15 @@ import app.pachli.BaseActivity
|
|||
import app.pachli.BottomSheetActivity
|
||||
import app.pachli.PostLookupFallbackBehavior
|
||||
import app.pachli.R
|
||||
import app.pachli.StatusListActivity.Companion.newHashtagIntent
|
||||
import app.pachli.ViewMediaActivity.Companion.newIntent
|
||||
import app.pachli.components.compose.ComposeActivity
|
||||
import app.pachli.components.compose.ComposeActivity.Companion.startIntent
|
||||
import app.pachli.components.compose.ComposeActivity.ComposeOptions
|
||||
import app.pachli.components.report.ReportActivity.Companion.getIntent
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.database.model.TranslationState
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.navigation.ReportActivityIntent
|
||||
import app.pachli.core.navigation.StatusListActivityIntent
|
||||
import app.pachli.core.navigation.ViewMediaActivityIntent
|
||||
import app.pachli.core.network.ServerOperation
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.core.network.model.Status
|
||||
|
@ -61,7 +61,6 @@ import app.pachli.network.ServerCapabilitiesRepository
|
|||
import app.pachli.usecase.TimelineCases
|
||||
import app.pachli.util.openLink
|
||||
import app.pachli.view.showMuteAccountDialog
|
||||
import app.pachli.viewdata.AttachmentViewData
|
||||
import app.pachli.viewdata.StatusViewData
|
||||
import at.connyduck.calladapter.networkresult.fold
|
||||
import at.connyduck.calladapter.networkresult.onFailure
|
||||
|
@ -163,10 +162,10 @@ abstract class SFragment : Fragment() {
|
|||
replyingStatusAuthor = account.localUsername,
|
||||
replyingStatusContent = actionableStatus.content.parseAsMastodonHtml().toString(),
|
||||
language = actionableStatus.language,
|
||||
kind = ComposeActivity.ComposeKind.NEW,
|
||||
kind = ComposeOptions.ComposeKind.NEW,
|
||||
)
|
||||
|
||||
val intent = startIntent(requireContext(), composeOptions)
|
||||
val intent = ComposeActivityIntent(requireContext(), composeOptions)
|
||||
requireActivity().startActivity(intent)
|
||||
}
|
||||
|
||||
|
@ -379,7 +378,7 @@ abstract class SFragment : Fragment() {
|
|||
val (attachment) = attachments[urlIndex]
|
||||
when (attachment.type) {
|
||||
Attachment.Type.GIFV, Attachment.Type.VIDEO, Attachment.Type.IMAGE, Attachment.Type.AUDIO -> {
|
||||
val intent = newIntent(context, attachments, urlIndex)
|
||||
val intent = ViewMediaActivityIntent(requireContext(), attachments, urlIndex)
|
||||
if (view != null) {
|
||||
val url = attachment.url
|
||||
view.transitionName = url
|
||||
|
@ -400,11 +399,11 @@ abstract class SFragment : Fragment() {
|
|||
}
|
||||
|
||||
protected fun viewTag(tag: String) {
|
||||
startActivity(newHashtagIntent(requireContext(), tag))
|
||||
startActivity(StatusListActivityIntent.hashtag(requireContext(), tag))
|
||||
}
|
||||
|
||||
private fun openReportPage(accountId: String, accountUsername: String, statusId: String) {
|
||||
startActivity(getIntent(requireContext(), accountId, accountUsername, statusId))
|
||||
startActivity(ReportActivityIntent(requireContext(), accountId, accountUsername, statusId))
|
||||
}
|
||||
|
||||
private fun showConfirmDeleteDialog(id: String, position: Int) {
|
||||
|
@ -455,9 +454,9 @@ abstract class SFragment : Fragment() {
|
|||
modifiedInitialState = true,
|
||||
language = sourceStatus.language,
|
||||
poll = sourceStatus.poll?.toNewPoll(sourceStatus.createdAt),
|
||||
kind = ComposeActivity.ComposeKind.NEW,
|
||||
kind = ComposeOptions.ComposeKind.NEW,
|
||||
)
|
||||
startActivity(startIntent(requireContext(), composeOptions))
|
||||
startActivity(ComposeActivityIntent(requireContext(), composeOptions))
|
||||
},
|
||||
{ error: Throwable? ->
|
||||
Timber.w(error, "error deleting status")
|
||||
|
@ -485,9 +484,9 @@ abstract class SFragment : Fragment() {
|
|||
language = status.language,
|
||||
statusId = source.id,
|
||||
poll = status.poll?.toNewPoll(status.createdAt),
|
||||
kind = ComposeActivity.ComposeKind.EDIT_POSTED,
|
||||
kind = ComposeOptions.ComposeKind.EDIT_POSTED,
|
||||
)
|
||||
startActivity(startIntent(requireContext(), composeOptions))
|
||||
startActivity(ComposeActivityIntent(requireContext(), composeOptions))
|
||||
},
|
||||
{
|
||||
Snackbar.make(
|
||||
|
|
|
@ -24,8 +24,8 @@ import android.content.Intent
|
|||
import android.os.Build
|
||||
import android.service.quicksettings.TileService
|
||||
import app.pachli.MainActivity
|
||||
import app.pachli.components.compose.ComposeActivity
|
||||
import app.pachli.components.notifications.pendingIntentFlags
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
|
||||
/**
|
||||
* Small Addition that adds in a QuickSettings tile
|
||||
|
@ -35,7 +35,7 @@ import app.pachli.components.notifications.pendingIntentFlags
|
|||
class PachliTileService : TileService() {
|
||||
@SuppressLint("StartActivityAndCollapseDeprecated")
|
||||
override fun onClick() {
|
||||
val intent = MainActivity.composeIntent(this, ComposeActivity.ComposeOptions())
|
||||
val intent = MainActivity.composeIntent(this, ComposeOptions())
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
startActivityAndCollapse(getActivityPendingIntent(this, 0, intent))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package app.pachli.service
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
|
@ -373,6 +374,8 @@ class SendStatusService : Service() {
|
|||
}
|
||||
|
||||
private fun cancelSendingIntent(statusId: Int): PendingIntent {
|
||||
// TODO: Revisit suppressing this when this file is moved
|
||||
@SuppressLint("IntentDetector")
|
||||
val intent = Intent(this, SendStatusService::class.java)
|
||||
intent.putExtra(KEY_CANCEL, statusId)
|
||||
return PendingIntent.getService(
|
||||
|
@ -428,6 +431,8 @@ class SendStatusService : Service() {
|
|||
context: Context,
|
||||
statusToSend: StatusToSend,
|
||||
): Intent {
|
||||
// TODO: Revisit suppressing this when this file is moved
|
||||
@SuppressLint("IntentDetector")
|
||||
val intent = Intent(context, SendStatusService::class.java)
|
||||
intent.putExtra(KEY_STATUS, statusToSend)
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@ import androidx.core.app.Person
|
|||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import app.pachli.MainActivity
|
||||
import app.pachli.R
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.navigation.MainActivityIntent
|
||||
import com.bumptech.glide.Glide
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
|
@ -67,7 +67,7 @@ fun updateShortcut(context: Context, account: AccountEntity) {
|
|||
.build()
|
||||
|
||||
// This intent will be sent when the user clicks on one of the launcher shortcuts. Intent from share sheet will be different
|
||||
val intent = Intent(context, MainActivity::class.java).apply {
|
||||
val intent = MainActivityIntent(context).apply {
|
||||
action = Intent.ACTION_SEND
|
||||
type = "text/plain"
|
||||
putExtra(ShortcutManagerCompat.EXTRA_SHORTCUT_ID, account.id.toString())
|
||||
|
|
|
@ -33,6 +33,7 @@ import app.pachli.core.accounts.AccountManager
|
|||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.database.model.TabKind
|
||||
import app.pachli.core.database.model.defaultTabs
|
||||
import app.pachli.core.navigation.AccountListActivityIntent
|
||||
import app.pachli.core.network.model.Account
|
||||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.model.TimelineAccount
|
||||
|
@ -176,7 +177,7 @@ class MainActivityTest {
|
|||
nextActivity.component,
|
||||
)
|
||||
assertEquals(
|
||||
AccountListActivity.Type.FOLLOW_REQUESTS,
|
||||
AccountListActivityIntent.Kind.FOLLOW_REQUESTS,
|
||||
nextActivity.getSerializableExtra("type"),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import app.pachli.PachliApplication
|
|||
import app.pachli.R
|
||||
import app.pachli.components.instanceinfo.InstanceInfoRepository
|
||||
import app.pachli.core.accounts.AccountManager
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.network.model.Account
|
||||
import app.pachli.core.network.model.InstanceConfiguration
|
||||
import app.pachli.core.network.model.InstanceV1
|
||||
|
@ -138,7 +140,7 @@ class ComposeActivityTest {
|
|||
|
||||
@Test
|
||||
fun whenModifiedInitialState_andCloseButtonPressed_notFinish() {
|
||||
rule.launch(intent(ComposeActivity.ComposeOptions(modifiedInitialState = true)))
|
||||
rule.launch(intent(ComposeOptions(modifiedInitialState = true)))
|
||||
rule.getScenario().onActivity {
|
||||
clickUp(it)
|
||||
assertFalse(it.isFinishing)
|
||||
|
@ -167,7 +169,7 @@ class ComposeActivityTest {
|
|||
|
||||
@Test
|
||||
fun whenModifiedInitialState_andBackButtonPressed_notFinish() {
|
||||
rule.launch(intent(ComposeActivity.ComposeOptions(modifiedInitialState = true)))
|
||||
rule.launch(intent(ComposeOptions(modifiedInitialState = true)))
|
||||
rule.getScenario().onActivity {
|
||||
clickBack(it)
|
||||
assertFalse(it.isFinishing)
|
||||
|
@ -512,7 +514,7 @@ class ComposeActivityTest {
|
|||
|
||||
@Test
|
||||
fun languageGivenInComposeOptionsIsRespected() {
|
||||
rule.launch(intent(ComposeActivity.ComposeOptions(language = "no")))
|
||||
rule.launch(intent(ComposeOptions(language = "no")))
|
||||
rule.getScenario().onActivity {
|
||||
assertEquals("no", it.selectedLanguage)
|
||||
}
|
||||
|
@ -522,7 +524,7 @@ class ComposeActivityTest {
|
|||
fun modernLanguageCodeIsUsed() {
|
||||
// https://github.com/tuskyapp/Tusky/issues/2903
|
||||
// "ji" was deprecated in favor of "yi"
|
||||
rule.launch(intent(ComposeActivity.ComposeOptions(language = "ji")))
|
||||
rule.launch(intent(ComposeOptions(language = "ji")))
|
||||
rule.getScenario().onActivity {
|
||||
assertEquals("yi", it.selectedLanguage)
|
||||
}
|
||||
|
@ -530,14 +532,14 @@ class ComposeActivityTest {
|
|||
|
||||
@Test
|
||||
fun unknownLanguageGivenInComposeOptionsIsRespected() {
|
||||
rule.launch(intent(ComposeActivity.ComposeOptions(language = "zzz")))
|
||||
rule.launch(intent(ComposeOptions(language = "zzz")))
|
||||
rule.getScenario().onActivity {
|
||||
assertEquals("zzz", it.selectedLanguage)
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns an intent to launch [ComposeActivity] with the given options */
|
||||
private fun intent(composeOptions: ComposeActivity.ComposeOptions) = ComposeActivity.startIntent(
|
||||
private fun intent(composeOptions: ComposeOptions) = ComposeActivityIntent(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
composeOptions,
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ plugins {
|
|||
alias(libs.plugins.ktlint) apply false
|
||||
alias(libs.plugins.aboutlibraries) apply false
|
||||
alias(libs.plugins.hilt) apply false
|
||||
alias(libs.plugins.quadrant) apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright 2023 Pachli Association
|
||||
*
|
||||
* This file is a part of Pachli.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||
* see <http://www.gnu.org/licenses>.
|
||||
*/
|
||||
|
||||
package app.pachli.lint.checks
|
||||
|
||||
import com.android.SdkConstants.CLASS_INTENT
|
||||
import com.android.tools.lint.client.api.UElementHandler
|
||||
import com.android.tools.lint.detector.api.Category
|
||||
import com.android.tools.lint.detector.api.Detector
|
||||
import com.android.tools.lint.detector.api.Implementation
|
||||
import com.android.tools.lint.detector.api.Issue
|
||||
import com.android.tools.lint.detector.api.JavaContext
|
||||
import com.android.tools.lint.detector.api.Scope
|
||||
import com.android.tools.lint.detector.api.Severity
|
||||
import org.jetbrains.uast.UCallExpression
|
||||
import org.jetbrains.uast.getQualifiedName
|
||||
import org.jetbrains.uast.util.isConstructorCall
|
||||
|
||||
class IntentDetector : Detector(), Detector.UastScanner {
|
||||
override fun getApplicableUastTypes() = listOf(UCallExpression::class.java)
|
||||
|
||||
override fun createUastHandler(context: JavaContext) = object : UElementHandler() {
|
||||
override fun visitCallExpression(node: UCallExpression) {
|
||||
// Ignore anything that is not constructing an Intent
|
||||
if (!node.isConstructorCall()) return
|
||||
val classRef = node.classReference ?: return
|
||||
val className = classRef.getQualifiedName()
|
||||
if (className != CLASS_INTENT) return
|
||||
|
||||
// Ignore calls that don't have 2 or 4 parameters
|
||||
val constructor = node.resolve() ?: return
|
||||
val parameters = constructor.parameterList.parameters
|
||||
if (parameters.size != 2 && parameters.size != 4) return
|
||||
|
||||
// Ignore calls where the last parameter is not a class literal
|
||||
val lastParam = parameters.last()
|
||||
if (lastParam.type.canonicalText != "java.lang.Class<?>") return
|
||||
|
||||
context.report(
|
||||
issue = ISSUE,
|
||||
scope = node,
|
||||
location = context.getCallLocation(node, true, true),
|
||||
message = "Use functions from `core.navigation`",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ISSUE = Issue.create(
|
||||
id = "IntentDetector",
|
||||
briefDescription = "Don't use `Intent(...)`, use functions from core.navigation",
|
||||
explanation = """
|
||||
Creating an `Intent` with a class from another module can create unnecessary or circular
|
||||
dependencies. Use the `...Intent` classes in `core.navigation` to create an intent for
|
||||
the appropriate `Activity`.
|
||||
""".trimIndent(),
|
||||
category = Category.CORRECTNESS,
|
||||
priority = 6,
|
||||
severity = Severity.WARNING,
|
||||
implementation = Implementation(
|
||||
IntentDetector::class.java,
|
||||
Scope.JAVA_FILE_SCOPE,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -7,7 +7,10 @@ import com.android.tools.lint.detector.api.Issue
|
|||
@Suppress("UnstableApiUsage")
|
||||
class LintRegistry : IssueRegistry() {
|
||||
override val issues: List<Issue>
|
||||
get() = listOf(AndroidxToolbarDetector.ISSUE)
|
||||
get() = listOf(
|
||||
AndroidxToolbarDetector.ISSUE,
|
||||
IntentDetector.ISSUE,
|
||||
)
|
||||
|
||||
override val api: Int
|
||||
get() = CURRENT_API
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright 2023 Pachli Association
|
||||
*
|
||||
* This file is a part of Pachli.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||
* see <http://www.gnu.org/licenses>.
|
||||
*/
|
||||
|
||||
package app.pachli.lint.checks
|
||||
|
||||
import com.android.tools.lint.checks.infrastructure.LintDetectorTest
|
||||
import com.android.tools.lint.detector.api.Detector
|
||||
import com.android.tools.lint.detector.api.Issue
|
||||
|
||||
class IntentDetectorTest : LintDetectorTest() {
|
||||
override fun getDetector(): Detector = IntentDetector()
|
||||
|
||||
override fun getIssues(): List<Issue> = listOf(IntentDetector.ISSUE)
|
||||
|
||||
fun `test Intent component constructor emits warning`() {
|
||||
lint().files(
|
||||
Context,
|
||||
Intent,
|
||||
kotlin(
|
||||
"""
|
||||
package test.pkg
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
|
||||
fun makeIntent(context: Context) = Intent(context, String::class.java)
|
||||
""",
|
||||
|
||||
).indented(),
|
||||
).allowMissingSdk().run().expect(
|
||||
"""src/test/pkg/test.kt:6: Warning: Use functions from core.navigation [IntentDetector]
|
||||
fun makeIntent(context: Context) = Intent(context, String::class.java)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
0 errors, 1 warnings""",
|
||||
)
|
||||
}
|
||||
|
||||
fun `test Intent action and data component constructor emits warning`() {
|
||||
lint().files(
|
||||
Context,
|
||||
Intent,
|
||||
kotlin(
|
||||
"""
|
||||
package test.pkg
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
|
||||
fun makeIntent(context: Context) = Intent(
|
||||
"someAction",
|
||||
Uri.parse("https://example.com"),
|
||||
context,
|
||||
String::class.java,
|
||||
)
|
||||
""",
|
||||
).indented(),
|
||||
).allowMissingSdk().run().expect(
|
||||
"""src/test/pkg/test.kt:6: Warning: Use functions from core.navigation [IntentDetector]
|
||||
fun makeIntent(context: Context) = Intent(
|
||||
^
|
||||
0 errors, 1 warnings""",
|
||||
)
|
||||
}
|
||||
|
||||
fun `test empty constructor does not warn`() {
|
||||
lint().files(
|
||||
Context,
|
||||
Intent,
|
||||
kotlin(
|
||||
"""
|
||||
package test.pkg
|
||||
|
||||
import android.content.Intent
|
||||
|
||||
fun makeIntent() = Intent()
|
||||
""",
|
||||
).indented(),
|
||||
).allowMissingSdk().run().expectClean()
|
||||
}
|
||||
|
||||
fun `test copy constructor does not warn`() {
|
||||
lint().files(
|
||||
Context,
|
||||
Intent,
|
||||
kotlin(
|
||||
"""
|
||||
package test.pkg
|
||||
|
||||
import android.content.Intent
|
||||
|
||||
fun makeIntent(intent: Intent) = Intent(intent, 0)
|
||||
""",
|
||||
).indented(),
|
||||
).allowMissingSdk().run().expectClean()
|
||||
}
|
||||
|
||||
fun `test action constructor does not warn`() {
|
||||
lint().files(
|
||||
Context,
|
||||
Intent,
|
||||
kotlin(
|
||||
"""
|
||||
package test.pkg
|
||||
|
||||
import android.content.Intent
|
||||
|
||||
fun makeIntent() = Intent("some action")
|
||||
""",
|
||||
).indented(),
|
||||
).allowMissingSdk().run().expectClean()
|
||||
}
|
||||
|
||||
fun `test action and uri constructor does not warn`() {
|
||||
lint().files(
|
||||
Context,
|
||||
Intent,
|
||||
kotlin(
|
||||
"""
|
||||
package test.pkg
|
||||
|
||||
import android.content.Intent
|
||||
|
||||
fun makeIntent() = Intent("some action", Uri.parse("http://example.com"))
|
||||
""",
|
||||
).indented(),
|
||||
).allowMissingSdk().run().expectClean()
|
||||
}
|
||||
|
||||
companion object Stubs {
|
||||
/** Stub for `android.content.Context` */
|
||||
private val Context = java(
|
||||
"""
|
||||
package android.content;
|
||||
|
||||
public class Context {}
|
||||
""",
|
||||
).indented()
|
||||
|
||||
/** Stub for `android.content.Intent` */
|
||||
private val Intent = java(
|
||||
"""
|
||||
package android.content;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class Intent {
|
||||
public Intent() { return null; }
|
||||
public Intent(Intent o, int copyMode) { return null; }
|
||||
public Intent(String action) { return null; }
|
||||
public Intent(String action, Uri uri) { return null; }
|
||||
public Intent(Context packageContext, Class<?> cls) { return null; }
|
||||
public Intent(String action, Uri uri, Context packageContext, Class<?> cls) { return null; }
|
||||
}
|
||||
""",
|
||||
).indented()
|
||||
}
|
||||
}
|
|
@ -36,5 +36,5 @@ dependencies {
|
|||
implementation(projects.core.preferences)
|
||||
|
||||
// Because of the use of @SerializedName in DraftEntity
|
||||
compileOnly(libs.gson)
|
||||
implementation(libs.gson)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# :core:navigation
|
||||
|
||||
## package app.pachli.core.navigation
|
||||
|
||||
Intents for starting activities to break circular dependencies.
|
||||
|
||||
A common approach for surfacing type-safe (ish) intents to start activities is for the activity-to-be-launched to provide a method in a companion object that returns the relevant intent, possibly taking additional parameters that will be included in the intent as extras.
|
||||
|
||||
E.g., if A wants to start B, B provides the method that returns the intent.
|
||||
|
||||
This introduces a dependency between A and B.
|
||||
|
||||
This is worse if B also wants to start A.
|
||||
|
||||
For example, if A is `StatusListActivity` and B is`ViewThreadActivity`. The user might click a status in `StatusListActivity` to view the thread, starting `ViewThreadActivity`. But from the thread they might click a hashtag to view the list of statuses with that hashtag. Now `StatusListActivity` and `ViewThreadActivity` have a circular dependency.
|
||||
|
||||
Even if that doesn't happen the dependency means that any changes to B will trigger a rebuild of A, even if the changes to B are not relevant.
|
||||
|
||||
This package contains `Intent` subclasses that should be used instead. The `quadrant` plugin is used to generate constants that can be used to launch activities by name instead of by class, breaking the dependency chain.
|
||||
|
||||
If the activity's intent requires specific extras those are passed via the constructor, with companion object methods to extract them from the intent.
|
||||
|
||||
Using the intent classes from this package is enforced by a lint `IntentDetector` which will warn if any intents are created using a class literal.
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2023 Pachli Association
|
||||
*
|
||||
* This file is a part of Pachli.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||
* see <http://www.gnu.org/licenses>.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.pachli.android.library)
|
||||
alias(libs.plugins.kotlin.parcelize)
|
||||
alias(libs.plugins.quadrant)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "app.pachli.core.navigation"
|
||||
|
||||
defaultConfig {
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.core.database) // For DraftAttachment, used in ComposeOptions
|
||||
implementation(projects.core.network) // For Attachment, used in AttachmentViewData
|
||||
|
||||
implementation(libs.androidx.core.ktx) // IntentCompat
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<issues format="6" by="lint 8.2.0" type="baseline" client="gradle" dependencies="false" name="AGP (8.2.0)" variant="all" version="8.2.0">
|
||||
|
||||
</issues>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2023 Pachli Association
|
||||
~
|
||||
~ This file is a part of Pachli.
|
||||
~
|
||||
~ This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
~ GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
~ License, or (at your option) any later version.
|
||||
~
|
||||
~ Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
~ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
~ Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||
~ see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
|
||||
<manifest>
|
||||
|
||||
</manifest>
|
|
@ -1,4 +1,5 @@
|
|||
/* Copyright 2022 Tusky Contributors
|
||||
/*
|
||||
* Copyright 2022 Tusky Contributors
|
||||
*
|
||||
* This file is a part of Pachli.
|
||||
*
|
||||
|
@ -14,7 +15,7 @@
|
|||
* see <http://www.gnu.org/licenses>.
|
||||
*/
|
||||
|
||||
package app.pachli.viewdata
|
||||
package app.pachli.core.navigation
|
||||
|
||||
import android.os.Parcelable
|
||||
import app.pachli.core.network.model.Attachment
|
|
@ -0,0 +1,482 @@
|
|||
/*
|
||||
* Copyright 2023 Pachli Association
|
||||
*
|
||||
* This file is a part of Pachli.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||
* see <http://www.gnu.org/licenses>.
|
||||
*/
|
||||
|
||||
package app.pachli.core.navigation
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Parcelable
|
||||
import androidx.core.content.IntentCompat
|
||||
import app.pachli.core.database.model.DraftAttachment
|
||||
import app.pachli.core.navigation.LoginActivityIntent.LoginMode
|
||||
import app.pachli.core.navigation.StatusListActivityIntent.Companion.bookmarks
|
||||
import app.pachli.core.navigation.StatusListActivityIntent.Companion.favourites
|
||||
import app.pachli.core.navigation.StatusListActivityIntent.Companion.hashtag
|
||||
import app.pachli.core.navigation.StatusListActivityIntent.Companion.list
|
||||
import app.pachli.core.network.model.Attachment
|
||||
import app.pachli.core.network.model.Filter
|
||||
import app.pachli.core.network.model.NewPoll
|
||||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.network.model.TimelineKind
|
||||
import com.gaelmarhic.quadrant.QuadrantConstants
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param accountId Server ID of the account to view
|
||||
* @see [app.pachli.components.account.AccountActivity]
|
||||
*/
|
||||
class AccountActivityIntent(context: Context, accountId: String) : Intent() {
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.ACCOUNT_ACTIVITY}")
|
||||
putExtra(EXTRA_KEY_ACCOUNT_ID, accountId)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_KEY_ACCOUNT_ID = "id"
|
||||
|
||||
/** @return the account ID passed in this intent */
|
||||
fun getAccountId(intent: Intent) = intent.getStringExtra(EXTRA_KEY_ACCOUNT_ID)!!
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param kind The kind of accounts to show
|
||||
* @param id Optional ID. Sometimes an account ID, sometimes a status ID, and
|
||||
* sometimes ignored. See [Kind] for details of how `id` is interpreted.
|
||||
* @see [app.pachli.components.accountlist.AccountListActivity]
|
||||
*/
|
||||
class AccountListActivityIntent(context: Context, kind: Kind, id: String? = null) : Intent() {
|
||||
enum class Kind {
|
||||
/** Show the accounts the account with `id` is following */
|
||||
FOLLOWS,
|
||||
|
||||
/** Show the accounts following the account with `id` */
|
||||
FOLLOWERS,
|
||||
|
||||
/** Show the accounts the account with `id` is blocking */
|
||||
BLOCKS,
|
||||
|
||||
/** Show the accounts the account with `id` is muting */
|
||||
MUTES,
|
||||
|
||||
/** Show the logged in account's follow requests (`id` is ignored) */
|
||||
FOLLOW_REQUESTS,
|
||||
|
||||
/** Show the accounts that reblogged the status with `id` */
|
||||
REBLOGGED,
|
||||
|
||||
/** Show the accounts that favourited the status with `id` */
|
||||
FAVOURITED,
|
||||
}
|
||||
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.ACCOUNT_LIST_ACTIVITY}")
|
||||
putExtra(EXTRA_KIND, kind)
|
||||
putExtra(EXTRA_ID, id)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_KIND = "kind"
|
||||
private const val EXTRA_ID = "id"
|
||||
|
||||
/** @return The [Kind] passed in this intent */
|
||||
fun getKind(intent: Intent) = intent.getSerializableExtra(EXTRA_KIND) as Kind
|
||||
|
||||
/** @return The ID passed in this intent, or null */
|
||||
fun getId(intent: Intent) = intent.getStringExtra(EXTRA_ID)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @see [app.pachli.components.compose.ComposeActivity]
|
||||
*/
|
||||
class ComposeActivityIntent(context: Context) : Intent() {
|
||||
@Parcelize
|
||||
data class ComposeOptions(
|
||||
val scheduledTootId: String? = null,
|
||||
val draftId: Int? = null,
|
||||
val content: String? = null,
|
||||
val mediaUrls: List<String>? = null,
|
||||
val mediaDescriptions: List<String>? = null,
|
||||
val mentionedUsernames: Set<String>? = null,
|
||||
val inReplyToId: String? = null,
|
||||
val replyVisibility: Status.Visibility? = null,
|
||||
val visibility: Status.Visibility? = null,
|
||||
val contentWarning: String? = null,
|
||||
val replyingStatusAuthor: String? = null,
|
||||
val replyingStatusContent: String? = null,
|
||||
val mediaAttachments: List<Attachment>? = null,
|
||||
val draftAttachments: List<DraftAttachment>? = null,
|
||||
val scheduledAt: String? = null,
|
||||
val sensitive: Boolean? = null,
|
||||
val poll: NewPoll? = null,
|
||||
val modifiedInitialState: Boolean? = null,
|
||||
val language: String? = null,
|
||||
val statusId: String? = null,
|
||||
val kind: ComposeKind? = null,
|
||||
val initialCursorPosition: InitialCursorPosition = InitialCursorPosition.END,
|
||||
) : Parcelable {
|
||||
/**
|
||||
* Status' kind. This particularly affects how the status is handled if the user
|
||||
* backs out of the edit.
|
||||
*/
|
||||
enum class ComposeKind {
|
||||
/** Status is new */
|
||||
NEW,
|
||||
|
||||
/** Editing a posted status */
|
||||
EDIT_POSTED,
|
||||
|
||||
/** Editing a status started as an existing draft */
|
||||
EDIT_DRAFT,
|
||||
|
||||
/** Editing an an existing scheduled status */
|
||||
EDIT_SCHEDULED,
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial position of the cursor in EditText when the compose button is clicked
|
||||
* in a hashtag timeline
|
||||
*/
|
||||
enum class InitialCursorPosition {
|
||||
/** Position the cursor at the start of the line */
|
||||
START,
|
||||
|
||||
/** Position the cursor at the end of the line */
|
||||
END,
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.COMPOSE_ACTIVITY}")
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param options Configure the initial state of the activity
|
||||
* @see [app.pachli.components.compose.ComposeActivity]
|
||||
*/
|
||||
constructor(context: Context, options: ComposeOptions) : this(context) {
|
||||
putExtra(EXTRA_COMPOSE_OPTIONS, options)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_COMPOSE_OPTIONS = "composeOptions"
|
||||
|
||||
/** @return the [ComposeOptions] passed in this intent, or null */
|
||||
fun getOptions(intent: Intent) = IntentCompat.getParcelableExtra(intent, EXTRA_COMPOSE_OPTIONS, ComposeOptions::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param filter Optional filter to edit. If null an empty filter is created.
|
||||
* @see [app.pachli.components.filters.EditFilterActivity]
|
||||
*/
|
||||
class EditFilterActivityIntent(context: Context, filter: Filter? = null) : Intent() {
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.EDIT_FILTER_ACTIVITY}")
|
||||
filter?.let {
|
||||
putExtra(EXTRA_FILTER_TO_EDIT, it)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXTRA_FILTER_TO_EDIT = "filterToEdit"
|
||||
|
||||
/** @return the [Filter] passed in this intent, or null */
|
||||
fun getFilter(intent: Intent) = IntentCompat.getParcelableExtra(intent, EXTRA_FILTER_TO_EDIT, Filter::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param loginMode See [LoginMode]
|
||||
* @see [app.pachli.components.login.LoginActivity]
|
||||
*/
|
||||
class LoginActivityIntent(context: Context, loginMode: LoginMode = LoginMode.DEFAULT) : Intent() {
|
||||
/** How to log in */
|
||||
enum class LoginMode {
|
||||
DEFAULT,
|
||||
|
||||
/** Already logged in, log in with an additional account */
|
||||
ADDITIONAL_LOGIN,
|
||||
|
||||
/** Update the OAuth scope granted to the client */
|
||||
MIGRATION,
|
||||
}
|
||||
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.LOGIN_ACTIVITY}")
|
||||
putExtra(EXTRA_LOGIN_MODE, loginMode)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_LOGIN_MODE = "loginMode"
|
||||
|
||||
/** @return the `loginMode` passed to this intent */
|
||||
fun getLoginMode(intent: Intent) = intent.getSerializableExtra(EXTRA_LOGIN_MODE)!! as LoginMode
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param screen The preference screen to show
|
||||
* @see [app.pachli.components.preference.PreferencesActivity]
|
||||
*/
|
||||
class PreferencesActivityIntent(context: Context, screen: PreferenceScreen) : Intent() {
|
||||
/** A specific preference screen */
|
||||
enum class PreferenceScreen {
|
||||
/** General preferences */
|
||||
GENERAL,
|
||||
|
||||
/** Account-specific preferences */
|
||||
ACCOUNT,
|
||||
|
||||
/** Notification preferences */
|
||||
NOTIFICATION,
|
||||
}
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.PREFERENCES_ACTIVITY}")
|
||||
putExtra(EXTRA_PREFERENCE_SCREEN, screen)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_PREFERENCE_SCREEN = "preferenceScreen"
|
||||
|
||||
/** @return the `screen` passed to this intent */
|
||||
fun getPreferenceType(intent: Intent) = intent.getSerializableExtra(EXTRA_PREFERENCE_SCREEN)!! as PreferenceScreen
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param accountId The ID of the account to report
|
||||
* @param userName The username of the account to report
|
||||
* @param statusId Optional ID of a status to include in the report
|
||||
* @see [app.pachli.components.report.ReportActivity]
|
||||
*/
|
||||
class ReportActivityIntent(context: Context, accountId: String, userName: String, statusId: String? = null) : Intent() {
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.REPORT_ACTIVITY}")
|
||||
putExtra(EXTRA_ACCOUNT_ID, accountId)
|
||||
putExtra(EXTRA_ACCOUNT_USERNAME, userName)
|
||||
putExtra(EXTRA_STATUS_ID, statusId)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_ACCOUNT_ID = "accountId"
|
||||
private const val EXTRA_ACCOUNT_USERNAME = "accountUsername"
|
||||
private const val EXTRA_STATUS_ID = "statusId"
|
||||
|
||||
/** @return the `accountId` passed to this intent */
|
||||
fun getAccountId(intent: Intent) = intent.getStringExtra(EXTRA_ACCOUNT_ID)!!
|
||||
/** @return the `userName` passed to this intent */
|
||||
fun getAccountUserName(intent: Intent) = intent.getStringExtra(EXTRA_ACCOUNT_USERNAME)!!
|
||||
/** @return the `statusId` passed to this intent, or null */
|
||||
fun getStatusId(intent: Intent) = intent.getStringExtra(EXTRA_STATUS_ID)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use one of [bookmarks], [favourites], [hashtag], or [list] to construct.
|
||||
*/
|
||||
class StatusListActivityIntent private constructor (context: Context) : Intent() {
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.STATUS_LIST_ACTIVITY}")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_KIND = "kind"
|
||||
|
||||
/**
|
||||
* Show the user's bookmarks.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
fun bookmarks(context: Context) = StatusListActivityIntent(context).apply {
|
||||
putExtra(EXTRA_KIND, TimelineKind.Bookmarks)
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the user's favourites.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
fun favourites(context: Context) = StatusListActivityIntent(context).apply {
|
||||
putExtra(EXTRA_KIND, TimelineKind.Favourites)
|
||||
}
|
||||
|
||||
/**
|
||||
* Show statuses containing [hashtag].
|
||||
*
|
||||
* @param context
|
||||
* @param hashtag The hashtag to show, without the leading "`#`"
|
||||
*/
|
||||
fun hashtag(context: Context, hashtag: String) = StatusListActivityIntent(context).apply {
|
||||
putExtra(EXTRA_KIND, TimelineKind.Tag(listOf(hashtag)))
|
||||
}
|
||||
|
||||
/**
|
||||
* Show statuses from a list.
|
||||
*
|
||||
* @param context
|
||||
* @param listId ID of the list to show
|
||||
* @param title The title to display
|
||||
*/
|
||||
fun list(context: Context, listId: String, title: String) = StatusListActivityIntent(context).apply {
|
||||
putExtra(EXTRA_KIND, TimelineKind.UserList(listId, title))
|
||||
}
|
||||
|
||||
/** @return The [TimelineKind] to show */
|
||||
fun getKind(intent: Intent) = IntentCompat.getParcelableExtra(intent, EXTRA_KIND, TimelineKind::class.java)!!
|
||||
}
|
||||
}
|
||||
|
||||
class ViewMediaActivityIntent private constructor(context: Context) : Intent() {
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.VIEW_MEDIA_ACTIVITY}")
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a collection of media attachments.
|
||||
*
|
||||
* @param context
|
||||
* @param attachments The attachments to show
|
||||
* @param index The index of the attachment in [attachments] to focus on
|
||||
*/
|
||||
constructor(context: Context, attachments: List<AttachmentViewData>, index: Int) : this(context) {
|
||||
putParcelableArrayListExtra(EXTRA_ATTACHMENTS, ArrayList(attachments))
|
||||
putExtra(EXTRA_ATTACHMENT_INDEX, index)
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a single image identified by a URL
|
||||
*
|
||||
* @param context
|
||||
* @param url The URL of the image
|
||||
*/
|
||||
constructor(context: Context, url: String) : this(context) {
|
||||
putExtra(EXTRA_SINGLE_IMAGE_URL, url)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_ATTACHMENTS = "attachments"
|
||||
private const val EXTRA_ATTACHMENT_INDEX = "index"
|
||||
private const val EXTRA_SINGLE_IMAGE_URL = "singleImage"
|
||||
|
||||
/** @return the list of [AttachmentViewData] passed in this intent, or null */
|
||||
fun getAttachments(intent: Intent): ArrayList<AttachmentViewData>? = IntentCompat.getParcelableArrayListExtra(intent, EXTRA_ATTACHMENTS, AttachmentViewData::class.java)
|
||||
|
||||
/** @return the index of the attachment to show, or 0 */
|
||||
fun getAttachmentIndex(intent: Intent) = intent.getIntExtra(EXTRA_ATTACHMENT_INDEX, 0)
|
||||
|
||||
/** @return the URL of the single image to show, null if no URL was included */
|
||||
fun getImageUrl(intent: Intent) = intent.getStringExtra(EXTRA_SINGLE_IMAGE_URL)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param statusId ID of the status to start from (may be in the middle of the thread)
|
||||
* @param statusUrl Optional URL of the status in `statusId`
|
||||
* @see [app.pachli.components.viewthread.ViewThreadActivity]
|
||||
*/
|
||||
class ViewThreadActivityIntent(context: Context, statusId: String, statusUrl: String? = null) : Intent() {
|
||||
init {
|
||||
setClassName(context, "app.pachli${QuadrantConstants.VIEW_THREAD_ACTIVITY}")
|
||||
putExtra(EXTRA_STATUS_ID, statusId)
|
||||
putExtra(EXTRA_STATUS_URL, statusUrl)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_STATUS_ID = "id"
|
||||
private const val EXTRA_STATUS_URL = "url"
|
||||
|
||||
/** @return the `statusId` passed to this intent */
|
||||
fun getStatusId(intent: Intent) = intent.getStringExtra(EXTRA_STATUS_ID)!!
|
||||
/** @return the `statusUrl` passed to this intent, or null */
|
||||
fun getUrl(intent: Intent) = intent.getStringExtra(EXTRA_STATUS_URL)
|
||||
}
|
||||
}
|
||||
|
||||
class AboutActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.ABOUT_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class AnnouncementsActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.ANNOUNCEMENTS_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class DraftsActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.DRAFTS_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class EditProfileActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.EDIT_PROFILE_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class FiltersActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.FILTERS_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class FollowedTagsActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.FOLLOWED_TAGS_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class InstanceListActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.INSTANCE_LIST_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class LicenseActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.LICENSE_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class ListActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.LISTS_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class LoginWebViewActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.LOGIN_WEB_VIEW_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class MainActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.MAIN_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class PrivacyPolicyActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.PRIVACY_POLICY_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class ScheduledStatusActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.SCHEDULED_STATUS_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class SearchActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.SEARCH_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class TabPreferenceActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.TAB_PREFERENCE_ACTIVITY}") }
|
||||
}
|
||||
|
||||
class TrendingActivityIntent(context: Context) : Intent() {
|
||||
init { setClassName(context, "app.pachli${QuadrantConstants.TRENDING_ACTIVITY}") }
|
||||
}
|
|
@ -50,6 +50,7 @@ mockito-inline = "5.2.0"
|
|||
mockito-kotlin = "5.2.1"
|
||||
networkresult-calladapter = "1.0.0"
|
||||
okhttp = "4.12.0"
|
||||
quadrant = "1.7"
|
||||
retrofit = "2.9.0"
|
||||
robolectric = "4.11.1"
|
||||
rxandroid3 = "3.0.2"
|
||||
|
@ -76,6 +77,7 @@ kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
|||
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
|
||||
ktlint = "org.jlleitschuh.gradle.ktlint:11.6.1"
|
||||
room = { id = "androidx.room", version.ref = "androidx-room" }
|
||||
quadrant = { id = "com.gaelmarhic.quadrant", version.ref = "quadrant" }
|
||||
|
||||
# Plugins defined by this project
|
||||
pachli-android-application = { id = "pachli.android.application", version = "unspecified" }
|
||||
|
|
|
@ -27,6 +27,7 @@ include(":core:accounts")
|
|||
include(":core:common")
|
||||
include(":core:database")
|
||||
include(":core:preferences")
|
||||
include(":core:navigation")
|
||||
include(":core:network")
|
||||
include(":core:testing")
|
||||
include(":tools:mklanguages")
|
||||
|
|
Loading…
Reference in New Issue