first commit
This commit is contained in:
commit
0f855c5ac2
|
@ -0,0 +1,10 @@
|
|||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/*
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
|
@ -0,0 +1 @@
|
|||
/build
|
|
@ -0,0 +1,122 @@
|
|||
plugins {
|
||||
id 'com.android.application'
|
||||
}
|
||||
def flavor
|
||||
android {
|
||||
compileSdk 31
|
||||
|
||||
defaultConfig {
|
||||
minSdk 21
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
flavorDimensions "default"
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
productFlavors {
|
||||
fdroid {
|
||||
applicationId "fr.gouv.etalab.mastodon"
|
||||
buildConfigField "boolean", "DONATIONS", "true"
|
||||
buildConfigField "boolean", "push", "false"
|
||||
flavor = "fdroid"
|
||||
}
|
||||
playstore {
|
||||
applicationId "app.fedilab.android"
|
||||
buildConfigField "boolean", "DONATIONS", "false"
|
||||
buildConfigField "boolean", "push", "true"
|
||||
flavor = "playstore"
|
||||
}
|
||||
}
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
sourceSets {
|
||||
playstore {
|
||||
manifest.srcFile "src/playstore/AndroidManifest.xml"
|
||||
java.srcDirs = ['src/main/java', 'src/playstore/java']
|
||||
res.srcDirs = ['src/main/res', 'src/playstore/res']
|
||||
}
|
||||
fdroid {
|
||||
java.srcDirs = ['src/main/java', 'src/fdroid/java']
|
||||
res.srcDirs = ['src/main/res', 'src/fdroid/res']
|
||||
}
|
||||
}
|
||||
configurations {
|
||||
all {
|
||||
exclude group: 'androidx.lifecycle', module: 'lifecycle-viewmodel-ktx'
|
||||
}
|
||||
}
|
||||
}
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
implementation project(':autoimageslider')
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.5.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
implementation "com.google.code.gson:gson:2.8.6"
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
implementation 'androidx.preference:preference:1.2.0'
|
||||
implementation 'com.github.evozi:Cyanea:1.0.7'
|
||||
implementation 'com.vanniktech:emoji-one:0.6.0'
|
||||
implementation 'com.github.GrenderG:Toasty:1.5.2'
|
||||
implementation 'org.framagit.tom79:SparkButton:1.0.13'
|
||||
implementation "com.github.bumptech.glide:glide:4.12.0"
|
||||
implementation 'com.github.mergehez:ArgPlayer:v3.1'
|
||||
implementation ("com.github.bumptech.glide:recyclerview-integration:4.12.0") {
|
||||
// Excludes the support library because it's already included by Glide.
|
||||
transitive = false
|
||||
}
|
||||
implementation project(path: ':mytransl')
|
||||
implementation project(path: ':ratethisapp')
|
||||
annotationProcessor "com.github.bumptech.glide:compiler:4.12.0"
|
||||
implementation 'jp.wasabeef:glide-transformations:4.3.0'
|
||||
implementation 'com.github.penfeizhou.android.animation:apng:2.17.0'
|
||||
implementation 'com.github.penfeizhou.android.animation:gif:2.17.0'
|
||||
implementation 'com.google.android.exoplayer:exoplayer:2.16.1'
|
||||
implementation 'com.github.piasy:rxandroidaudio:1.7.0'
|
||||
implementation 'com.github.piasy:AudioProcessor:1.7.0'
|
||||
implementation "androidx.work:work-runtime:2.7.1"
|
||||
implementation 'app.futured.hauler:hauler:5.0.0'
|
||||
implementation "com.github.chrisbanes:PhotoView:2.3.0"
|
||||
implementation "ch.acra:acra-mail:5.5.0"
|
||||
implementation "ch.acra:acra-limiter:5.5.0"
|
||||
implementation "ch.acra:acra-notification:5.5.0"
|
||||
|
||||
implementation "com.madgag.spongycastle:bctls-jdk15on:1.58.0.0"
|
||||
implementation 'com.github.UnifiedPush:android-connector:2.0.0'
|
||||
// implementation 'com.github.UnifiedPush:android-foss_embedded_fcm_distributor:1.0.0-beta1'
|
||||
playstoreImplementation 'com.github.UnifiedPush:android-embedded_fcm_distributor:1.1.0'
|
||||
implementation 'com.burhanrashid52:photoeditor:1.5.1'
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata:2.4.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.4.1'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.4.1'
|
||||
implementation 'androidx.navigation:navigation-ui:2.4.1'
|
||||
testImplementation 'junit:junit:'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
|
@ -0,0 +1,26 @@
|
|||
package app.fedilab.android;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("app.fedilab.android", appContext.getPackageName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Fedilab 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 Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package app.fedilab.android.activities;
|
||||
|
||||
import app.fedilab.android.BaseMainActivity;
|
||||
|
||||
public class MainActivity extends BaseMainActivity {
|
||||
|
||||
|
||||
@Override
|
||||
protected void rateThisApp() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<external-path
|
||||
name="my_images"
|
||||
path="Android/data/fr.gouv.etalab.mastodon/files/Pictures" />
|
||||
|
||||
<cache-path
|
||||
name="*"
|
||||
path="." />
|
||||
|
||||
</paths>
|
|
@ -0,0 +1,187 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="app.fedilab.android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
tools:ignore="ScopedStorage" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
tools:replace="android:allowBackup"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme"
|
||||
>
|
||||
<activity
|
||||
android:name=".activities.MainActivity"
|
||||
android:exported="true"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".activities.LoginActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:windowSoftInputMode="stateAlwaysHidden">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="backtofedilab"
|
||||
android:scheme="fedilab" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activities.WebviewConnectActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||
<activity
|
||||
android:name=".activities.ContextActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||
<activity
|
||||
android:name=".activities.DraftActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||
<activity
|
||||
android:name=".activities.ComposeActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:windowSoftInputMode="stateVisible"
|
||||
android:label="@string/compose" />
|
||||
<activity
|
||||
android:name=".activities.StatusInfoActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||
<activity
|
||||
android:name=".activities.WebviewActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||
<activity
|
||||
android:name=".activities.ProfileActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/account" />
|
||||
<activity
|
||||
android:name=".activities.ScheduledActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/scheduled" />
|
||||
|
||||
<service
|
||||
android:name=".services.PostMessageService"
|
||||
android:label="@string/post_message" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.SearchResultTabActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:theme="@style/AppThemeBar"
|
||||
android:label="@string/search" />
|
||||
<activity
|
||||
android:name=".activities.ReorderTimelinesActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/reorder_timelines"
|
||||
android:theme="@style/AppThemeBar" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.ActionActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/interactions"
|
||||
android:theme="@style/AppThemeBar" />
|
||||
<activity
|
||||
android:name=".activities.MastodonListActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/action_lists"
|
||||
android:theme="@style/AppThemeBar" />
|
||||
<activity
|
||||
android:name=".activities.SettingsActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/settings"
|
||||
android:theme="@style/AppThemeBar" />
|
||||
<activity
|
||||
android:name=".activities.InstanceActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/action_about_instance"
|
||||
android:theme="@style/DialogDark" />
|
||||
<activity
|
||||
android:name=".activities.InstanceProfileActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/DialogDark" />
|
||||
<activity
|
||||
android:name=".activities.ProxyActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/DialogDark" />
|
||||
<activity
|
||||
android:name=".activities.HashTagActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||
<activity
|
||||
android:name=".activities.MediaActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:theme="@style/TransparentDark" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.InstanceHealthActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/DialogDark" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.ReportActivity"
|
||||
android:theme="@style/AppThemeBarDark"
|
||||
android:windowSoftInputMode="stateVisible" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.CustomSharingActivity"
|
||||
android:label="@string/settings_title_custom_sharing"
|
||||
android:windowSoftInputMode="stateVisible"
|
||||
android:theme="@style/AppThemeBarDark" />
|
||||
<activity
|
||||
android:name=".activities.FilterActivity"
|
||||
android:label="@string/filters"
|
||||
android:theme="@style/AppThemeBarDark"
|
||||
android:windowSoftInputMode="stateVisible" />
|
||||
<activity
|
||||
android:name=".activities.EditProfileActivity"
|
||||
android:label="@string/edit_profile"
|
||||
android:theme="@style/AppThemeBarDark"
|
||||
android:windowSoftInputMode="stateVisible" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileProvider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<receiver
|
||||
android:name=".broadcastreceiver.ToastMessage"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="RECEIVE_TOAST_MESSAGE" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name=".services.CustomReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="org.unifiedpush.android.connector.MESSAGE" />
|
||||
<action android:name="org.unifiedpush.android.connector.UNREGISTERED" />
|
||||
<action android:name="org.unifiedpush.android.connector.NEW_ENDPOINT" />
|
||||
<action android:name="org.unifiedpush.android.connector.REGISTRATION_FAILED" />
|
||||
<action android:name="org.unifiedpush.android.connector.REGISTRATION_REFUSED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
</manifest>
|
|
@ -0,0 +1,13 @@
|
|||
base_theme,2
|
||||
author,Fedilab
|
||||
name,Breeze Dark - Yellow
|
||||
theme_boost_header_color,-14012878
|
||||
theme_statuses_color,-14473687
|
||||
theme_link_color,-12734743
|
||||
theme_icons_color,-4340793
|
||||
pref_color_background,-15658735
|
||||
pref_color_navigation_bar,true
|
||||
pref_color_status_bar,true
|
||||
theme_accent,-148405
|
||||
theme_text_color,-1052431
|
||||
theme_primary,-13552069
|
|
|
@ -0,0 +1,15 @@
|
|||
base_theme,2
|
||||
author,Roboron
|
||||
name,Cyberpunk Neon
|
||||
theme_boost_header_color,-16776697,
|
||||
theme_text_header_1_line,-1441575,
|
||||
theme_text_header_2_line,-5242717,
|
||||
theme_statuses_color,-16181197,
|
||||
theme_link_color,-1441575,
|
||||
theme_icons_color,-16138810,
|
||||
pref_color_background,-16774370,
|
||||
pref_color_navigation_bar,true,
|
||||
pref_color_status_bar,true,
|
||||
theme_accent,-1441575,
|
||||
theme_text_color,-16138810,
|
||||
theme_primary,-16774370,
|
|
|
@ -0,0 +1,15 @@
|
|||
base_theme,2
|
||||
author,Jøta Seth
|
||||
name,Grey Orange
|
||||
theme_boost_header_color,-14869219
|
||||
theme_text_header_1_line,-1
|
||||
theme_text_header_2_line,-1
|
||||
theme_statuses_color,-14145496
|
||||
theme_link_color,-26624
|
||||
theme_icons_color,-26624
|
||||
pref_color_background,-13092808
|
||||
pref_color_navigation_bar,true
|
||||
pref_color_status_bar,true
|
||||
theme_accent,-26624
|
||||
theme_text_color,-1
|
||||
theme_primary,-14408668
|
|
|
@ -0,0 +1,15 @@
|
|||
base_theme,2
|
||||
author,@AntoineD@h.kher.nl
|
||||
name,Gruvbox OLED
|
||||
theme_boost_header_color,-16777216
|
||||
theme_text_header_1_line,-265785
|
||||
theme_text_header_2_line,-6777062
|
||||
theme_statuses_color,-16777216
|
||||
theme_link_color,-2647775
|
||||
theme_icons_color,-7175308
|
||||
pref_color_background,-16777216
|
||||
pref_color_navigation_bar,true
|
||||
pref_color_status_bar,true
|
||||
theme_accent,-9921174
|
||||
theme_text_color,-265785
|
||||
theme_primary,-16777216
|
|
|
@ -0,0 +1,15 @@
|
|||
base_theme,2
|
||||
author,AngryTux
|
||||
name,Less Angry Orange
|
||||
theme_boost_header_color,-15855063
|
||||
theme_text_header_1_line,-2128640
|
||||
theme_text_header_2_line,-5329234
|
||||
theme_statuses_color,-1
|
||||
theme_link_color,-12146699
|
||||
theme_icons_color,-2128640
|
||||
pref_color_background,-15987700
|
||||
pref_color_navigation_bar,true
|
||||
pref_color_status_bar,true
|
||||
theme_accent,-3968000
|
||||
theme_text_color,-197380
|
||||
theme_primary,-14408668
|
|
|
@ -0,0 +1,15 @@
|
|||
base_theme,2
|
||||
author,Mondstern
|
||||
name,Mondstern Fedilab
|
||||
theme_boost_header_color,-1,
|
||||
theme_text_header_1_line,-13855804,
|
||||
theme_text_header_2_line,-16227945,
|
||||
theme_statuses_color,-14935012,
|
||||
theme_link_color,-15542685,
|
||||
theme_icons_color,-10723999,
|
||||
pref_color_background,-15921907,
|
||||
pref_color_navigation_bar,false,
|
||||
pref_color_status_bar,false,
|
||||
theme_accent,-15542685,
|
||||
theme_text_color,-1,
|
||||
theme_primary,-14474461,
|
|
|
@ -0,0 +1,13 @@
|
|||
base_theme,2
|
||||
author,Fedilab
|
||||
name,Nocturnal
|
||||
theme_boost_header_color,-12895429
|
||||
theme_statuses_color,-13553359
|
||||
theme_link_color,-16747570
|
||||
theme_icons_color,-10158118
|
||||
pref_color_background,-14606047
|
||||
pref_color_navigation_bar,true
|
||||
pref_color_status_bar,true
|
||||
theme_accent,-13136013
|
||||
theme_text_color,-2236963
|
||||
theme_primary,-14013910
|
|
|
@ -0,0 +1,15 @@
|
|||
base_theme,2
|
||||
author,Jøta Seth
|
||||
name,Photon Dark
|
||||
theme_boost_header_color,-14145496
|
||||
theme_text_header_1_line,-1
|
||||
theme_text_header_2_line,-1
|
||||
theme_statuses_color,-14935012
|
||||
theme_link_color,-14059009
|
||||
theme_icons_color,-9474193
|
||||
pref_color_background,-15921907
|
||||
pref_color_navigation_bar,true
|
||||
pref_color_status_bar,true
|
||||
theme_accent,-14059009
|
||||
theme_text_color,-1
|
||||
theme_primary,-14474461
|
|
|
@ -0,0 +1,15 @@
|
|||
base_theme,2
|
||||
author,Fedilab
|
||||
name,Solarized Dark - Purple
|
||||
theme_boost_header_color,-16506327
|
||||
theme_text_header_1_line,-1120043
|
||||
theme_text_header_2_line,-1120043
|
||||
theme_statuses_color,-16304574
|
||||
theme_link_color,-14251054
|
||||
theme_icons_color,-7102047
|
||||
pref_color_background,-16766154
|
||||
pref_color_navigation_bar,true
|
||||
pref_color_status_bar,true
|
||||
theme_accent,-9670204
|
||||
theme_text_color,-133405
|
||||
theme_primary,-16304574
|
|
|
@ -0,0 +1,47 @@
|
|||
[
|
||||
{
|
||||
"theme_name": "Dark",
|
||||
"base_theme": "DARK",
|
||||
"primary": "#FF272727",
|
||||
"primary_dark": "#FF272727",
|
||||
"primary_light": "#FFd9e1e8",
|
||||
"accent": "#FF2b90d9",
|
||||
"accent_dark": "#FF1b80c9",
|
||||
"accent_light": "#FF772b90d9",
|
||||
"background": "#FF121212",
|
||||
"background_dark": "#FF282c37",
|
||||
"background_light": "#FF282c37",
|
||||
"should_tint_statusbar": true,
|
||||
"should_tint_navbar": true
|
||||
},
|
||||
{
|
||||
"theme_name": "Light",
|
||||
"base_theme": "LIGHT",
|
||||
"primary": "#FFFFFF",
|
||||
"primary_dark": "#FFFFFFFF",
|
||||
"primary_light": "#FFd9e1e8",
|
||||
"accent": "#FF2b90d9",
|
||||
"accent_dark": "#FF1b80c9",
|
||||
"accent_light": "#FF772b90d9",
|
||||
"background": "#FFFFFFFF",
|
||||
"background_dark": "#FFFFFFFF",
|
||||
"background_light": "#FFFFFFFF",
|
||||
"should_tint_statusbar": true,
|
||||
"should_tint_navbar": true
|
||||
},
|
||||
{
|
||||
"theme_name": "Black",
|
||||
"base_theme": "DARK",
|
||||
"primary": "#FF000000",
|
||||
"primary_dark": "#FF000000",
|
||||
"primary_light": "#FF000000",
|
||||
"accent": "#FF606984",
|
||||
"accent_dark": "#FF606984",
|
||||
"accent_light": "#FF606984",
|
||||
"background": "#FF000000",
|
||||
"background_dark": "#FF000000",
|
||||
"background_light": "#FF000000",
|
||||
"should_tint_statusbar": true,
|
||||
"should_tint_navbar": true
|
||||
}
|
||||
]
|
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
|
@ -0,0 +1,677 @@
|
|||
package app.fedilab.android;
|
||||
/* Copyright 2021 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Fedilab 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 Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import static app.fedilab.android.BaseMainActivity.status.DISCONNECTED;
|
||||
import static app.fedilab.android.BaseMainActivity.status.UNKNOWN;
|
||||
import static app.fedilab.android.helper.Helper.PREF_USER_TOKEN;
|
||||
import static app.fedilab.android.helper.Helper.deleteDir;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
import androidx.core.view.GravityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.navigation.NavController;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.ui.AppBarConfiguration;
|
||||
import androidx.navigation.ui.NavigationUI;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.gif.GifDrawable;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.jaredrummler.cyanea.Cyanea;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.android.activities.ActionActivity;
|
||||
import app.fedilab.android.activities.BaseActivity;
|
||||
import app.fedilab.android.activities.ComposeActivity;
|
||||
import app.fedilab.android.activities.DraftActivity;
|
||||
import app.fedilab.android.activities.FilterActivity;
|
||||
import app.fedilab.android.activities.InstanceActivity;
|
||||
import app.fedilab.android.activities.InstanceHealthActivity;
|
||||
import app.fedilab.android.activities.LoginActivity;
|
||||
import app.fedilab.android.activities.MainActivity;
|
||||
import app.fedilab.android.activities.MastodonListActivity;
|
||||
import app.fedilab.android.activities.ProfileActivity;
|
||||
import app.fedilab.android.activities.ProxyActivity;
|
||||
import app.fedilab.android.activities.ReorderTimelinesActivity;
|
||||
import app.fedilab.android.activities.ScheduledActivity;
|
||||
import app.fedilab.android.activities.SearchResultTabActivity;
|
||||
import app.fedilab.android.activities.SettingsActivity;
|
||||
import app.fedilab.android.broadcastreceiver.NetworkStateReceiver;
|
||||
import app.fedilab.android.client.entities.Account;
|
||||
import app.fedilab.android.client.entities.Pinned;
|
||||
import app.fedilab.android.client.entities.app.PinnedTimeline;
|
||||
import app.fedilab.android.client.mastodon.entities.Filter;
|
||||
import app.fedilab.android.client.mastodon.entities.Instance;
|
||||
import app.fedilab.android.client.mastodon.entities.MastodonList;
|
||||
import app.fedilab.android.databinding.ActivityMainBinding;
|
||||
import app.fedilab.android.databinding.NavHeaderMainBinding;
|
||||
import app.fedilab.android.exception.DBException;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.helper.PinnedTimelineHelper;
|
||||
import app.fedilab.android.helper.PushHelper;
|
||||
import app.fedilab.android.helper.ThemeHelper;
|
||||
import app.fedilab.android.ui.fragment.timeline.FragmentMastodonTimeline;
|
||||
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
||||
import app.fedilab.android.viewmodel.mastodon.InstancesVM;
|
||||
import app.fedilab.android.viewmodel.mastodon.TimelinesVM;
|
||||
import app.fedilab.android.viewmodel.mastodon.TopBarVM;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
public abstract class BaseMainActivity extends BaseActivity implements NetworkStateReceiver.NetworkStateReceiverListener {
|
||||
|
||||
public static String currentInstance, currentToken, currentUserID, client_id, client_secret, software;
|
||||
public static Account.API api;
|
||||
public static boolean admin;
|
||||
public static WeakReference<Account> accountWeakReference;
|
||||
public static HashMap<Integer, Fragment> mPageReferenceMap;
|
||||
public static status networkAvailable = UNKNOWN;
|
||||
public static Instance instanceInfo;
|
||||
public static List<Filter> mainFilters;
|
||||
public static boolean filterFetched;
|
||||
Fragment currentFragment;
|
||||
private Account account;
|
||||
private AppBarConfiguration mAppBarConfiguration;
|
||||
private ActivityMainBinding binding;
|
||||
private Pinned pinned;
|
||||
|
||||
private final BroadcastReceiver broadcast_data = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle b = intent.getExtras();
|
||||
if (b != null) {
|
||||
if (b.getBoolean(Helper.RECEIVE_REDRAW_TOPBAR, false)) {
|
||||
List<MastodonList> mastodonLists = (List<MastodonList>) b.getSerializable(Helper.RECEIVE_MASTODON_LIST);
|
||||
redrawPinned(mastodonLists);
|
||||
} else if (b.getBoolean(Helper.RECEIVE_RECREATE_ACTIVITY, false)) {
|
||||
Cyanea.getInstance().edit().apply().recreate(BaseMainActivity.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
private NetworkStateReceiver networkStateReceiver;
|
||||
private boolean headerMenuOpen;
|
||||
|
||||
protected abstract void rateThisApp();
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
mamageNewIntent(intent);
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
private void mamageNewIntent(Intent intent) {
|
||||
if (intent == null)
|
||||
return;
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
Bundle extras = intent.getExtras();
|
||||
String userIdIntent, instanceIntent;
|
||||
if (extras != null && extras.containsKey(Helper.INTENT_ACTION)) {
|
||||
userIdIntent = extras.getString(Helper.PREF_KEY_ID); //Id of the account in the intent
|
||||
instanceIntent = extras.getString(Helper.PREF_INSTANCE);
|
||||
if (extras.getInt(Helper.INTENT_ACTION) == Helper.NOTIFICATION_INTENT) {
|
||||
try {
|
||||
Account account = new Account(BaseMainActivity.this).getUniqAccount(userIdIntent, instanceIntent);
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(BaseMainActivity.this);
|
||||
headerMenuOpen = false;
|
||||
Toasty.info(BaseMainActivity.this, getString(R.string.toast_account_changed, "@" + account.mastodon_account.acct + "@" + account.instance), Toasty.LENGTH_LONG).show();
|
||||
BaseMainActivity.currentToken = account.token;
|
||||
BaseMainActivity.currentUserID = account.user_id;
|
||||
api = account.api;
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(PREF_USER_TOKEN, account.token);
|
||||
editor.commit();
|
||||
Intent mainActivity = new Intent(this, MainActivity.class);
|
||||
startActivity(mainActivity);
|
||||
intent.removeExtra(Helper.INTENT_ACTION);
|
||||
finish();
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(BaseMainActivity.this);
|
||||
ThemeHelper.applyTheme(this);
|
||||
if (!Helper.isLoggedIn(BaseMainActivity.this)) {
|
||||
//It is not, the user is redirected to the login page
|
||||
Intent myIntent = new Intent(BaseMainActivity.this, LoginActivity.class);
|
||||
startActivity(myIntent);
|
||||
finish();
|
||||
return;
|
||||
} else {
|
||||
BaseMainActivity.currentToken = sharedpreferences.getString(Helper.PREF_USER_TOKEN, null);
|
||||
}
|
||||
mamageNewIntent(getIntent());
|
||||
ThemeHelper.initiliazeColors(BaseMainActivity.this);
|
||||
filterFetched = false;
|
||||
networkStateReceiver = new NetworkStateReceiver();
|
||||
networkStateReceiver.addListener(this);
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
//Remove title
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayShowTitleEnabled(false);
|
||||
}
|
||||
rateThisApp();
|
||||
SharedPreferences cyneaPref = getSharedPreferences("com.jaredrummler.cyanea", Context.MODE_PRIVATE);
|
||||
binding.tabLayout.setTabTextColors(ThemeHelper.getAttColor(BaseMainActivity.this, R.attr.mTextColor), cyneaPref.getInt("theme_accent", -1));
|
||||
binding.tabLayout.setTabIconTint(ThemeHelper.getColorStateList(BaseMainActivity.this));
|
||||
binding.compose.setOnClickListener(v -> startActivity(new Intent(this, ComposeActivity.class)));
|
||||
headerMenuOpen = false;
|
||||
binding.bottomNavView.inflateMenu(R.menu.bottom_nav_menu);
|
||||
binding.bottomNavView.setOnItemSelectedListener(item -> {
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.nav_home) {
|
||||
binding.viewPager.setCurrentItem(0);
|
||||
} else if (itemId == R.id.nav_local) {
|
||||
binding.viewPager.setCurrentItem(1);
|
||||
} else if (itemId == R.id.nav_public) {
|
||||
binding.viewPager.setCurrentItem(2);
|
||||
} else if (itemId == R.id.nav_notifications) {
|
||||
binding.viewPager.setCurrentItem(3);
|
||||
} else if (itemId == R.id.nav_privates) {
|
||||
binding.viewPager.setCurrentItem(4);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
// Passing each menu ID as a set of Ids because each
|
||||
// menu should be considered as top level destinations.
|
||||
mAppBarConfiguration = new AppBarConfiguration.Builder()
|
||||
.setOpenableLayout(binding.drawerLayout)
|
||||
.build();
|
||||
|
||||
NavHeaderMainBinding headerMainBinding = NavHeaderMainBinding.inflate(getLayoutInflater());
|
||||
binding.navView.addHeaderView(headerMainBinding.getRoot());
|
||||
binding.navView.setNavigationItemSelectedListener(menuItem -> {
|
||||
int id = menuItem.getItemId();
|
||||
if (id == R.id.nav_drafts) {
|
||||
Intent intent = new Intent(this, DraftActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_reorder) {
|
||||
Intent intent = new Intent(this, ReorderTimelinesActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_interactions) {
|
||||
Intent intent = new Intent(this, ActionActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_filter) {
|
||||
Intent intent = new Intent(this, FilterActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_list) {
|
||||
Intent intent = new Intent(this, MastodonListActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_settings) {
|
||||
Intent intent = new Intent(this, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_scheduled) {
|
||||
Intent intent = new Intent(this, ScheduledActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
binding.drawerLayout.close();
|
||||
return false;
|
||||
});
|
||||
headerMainBinding.instanceInfoContainer.setOnClickListener(v -> startActivity(new Intent(BaseMainActivity.this, InstanceHealthActivity.class)));
|
||||
headerMainBinding.accountProfilePicture.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(BaseMainActivity.this, ProfileActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putSerializable(Helper.ARG_ACCOUNT, account.mastodon_account);
|
||||
intent.putExtras(b);
|
||||
ActivityOptionsCompat options = ActivityOptionsCompat
|
||||
.makeSceneTransitionAnimation(BaseMainActivity.this, headerMainBinding.instanceInfoContainer, getString(R.string.activity_porfile_pp));
|
||||
startActivity(intent, options.toBundle());
|
||||
});
|
||||
headerMainBinding.changeAccount.setOnClickListener(v -> {
|
||||
headerMenuOpen = !headerMenuOpen;
|
||||
if (headerMenuOpen) {
|
||||
headerMainBinding.ownerAccounts.setImageResource(R.drawable.ic_baseline_arrow_drop_up_24);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<Account> accounts = new Account(BaseMainActivity.this).getAll();
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
binding.navView.getMenu().clear();
|
||||
binding.navView.inflateMenu(R.menu.menu_accounts);
|
||||
headerMenuOpen = true;
|
||||
|
||||
Menu mainMenu = binding.navView.getMenu();
|
||||
SubMenu currentSubmenu = null;
|
||||
String lastInstance = "";
|
||||
if (accounts != null) {
|
||||
for (final Account account : accounts) {
|
||||
if (!currentToken.equalsIgnoreCase(account.token)) {
|
||||
if (!lastInstance.trim().equalsIgnoreCase(account.instance.trim())) {
|
||||
lastInstance = account.instance.toUpperCase();
|
||||
currentSubmenu = mainMenu.addSubMenu(account.instance.toUpperCase());
|
||||
}
|
||||
if (currentSubmenu == null) {
|
||||
continue;
|
||||
}
|
||||
final MenuItem item = currentSubmenu.add("@" + account.mastodon_account.acct);
|
||||
item.setIcon(R.drawable.ic_person);
|
||||
boolean disableGif = sharedpreferences.getBoolean(getString(R.string.SET_DISABLE_GIF), false);
|
||||
String url = !disableGif ? account.mastodon_account.avatar : account.mastodon_account.avatar_static;
|
||||
if (url.startsWith("/")) {
|
||||
url = "https://" + account.instance + account.mastodon_account.avatar;
|
||||
}
|
||||
if (!this.isDestroyed() && !this.isFinishing()) {
|
||||
if (url.contains(".gif")) {
|
||||
Glide.with(BaseMainActivity.this)
|
||||
.asGif()
|
||||
.load(url)
|
||||
.into(new CustomTarget<GifDrawable>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull GifDrawable resource, Transition<? super GifDrawable> transition) {
|
||||
item.setIcon(resource);
|
||||
item.getIcon().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(@Nullable Drawable placeholder) {
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Glide.with(BaseMainActivity.this)
|
||||
.asDrawable()
|
||||
.load(url)
|
||||
.into(new CustomTarget<Drawable>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Drawable resource, Transition<? super Drawable> transition) {
|
||||
item.setIcon(resource);
|
||||
item.getIcon().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(@Nullable Drawable placeholder) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
item.setOnMenuItemClickListener(item1 -> {
|
||||
if (!this.isFinishing()) {
|
||||
headerMenuOpen = false;
|
||||
Toasty.info(BaseMainActivity.this, getString(R.string.toast_account_changed, "@" + account.mastodon_account.acct + "@" + account.instance), Toasty.LENGTH_LONG).show();
|
||||
BaseMainActivity.currentToken = account.token;
|
||||
BaseMainActivity.currentUserID = account.user_id;
|
||||
api = account.api;
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(PREF_USER_TOKEN, account.token);
|
||||
editor.commit();
|
||||
//The user is now aut
|
||||
//The user is now authenticated, it will be redirected to MainActivity
|
||||
Intent mainActivity = new Intent(this, MainActivity.class);
|
||||
startActivity(mainActivity);
|
||||
finish();
|
||||
headerMainBinding.ownerAccounts.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
currentSubmenu = mainMenu.addSubMenu("");
|
||||
MenuItem addItem = currentSubmenu.add(R.string.add_account);
|
||||
addItem.setIcon(R.drawable.ic_baseline_person_add_24);
|
||||
addItem.setOnMenuItemClickListener(item -> {
|
||||
Intent intent = new Intent(BaseMainActivity.this, LoginActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
binding.navView.getMenu().clear();
|
||||
binding.navView.inflateMenu(R.menu.activity_main_drawer);
|
||||
headerMainBinding.ownerAccounts.setImageResource(R.drawable.ic_baseline_arrow_drop_down_24);
|
||||
headerMenuOpen = false;
|
||||
}
|
||||
});
|
||||
headerMainBinding.headerOptionInfo.setOnClickListener(v -> {
|
||||
PopupMenu popup = new PopupMenu(new ContextThemeWrapper(BaseMainActivity.this, Helper.popupStyle()), headerMainBinding.headerOptionInfo);
|
||||
popup.getMenuInflater()
|
||||
.inflate(R.menu.main, popup.getMenu());
|
||||
|
||||
popup.setOnMenuItemClickListener(item -> {
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.action_logout_account) {
|
||||
AlertDialog.Builder alt_bld = new AlertDialog.Builder(BaseMainActivity.this, Helper.dialogStyle());
|
||||
alt_bld.setTitle(R.string.action_logout);
|
||||
alt_bld.setMessage(getString(R.string.logout_account_confirmation, account.mastodon_account.username, account.instance));
|
||||
alt_bld.setPositiveButton(R.string.action_logout, (dialog, id) -> {
|
||||
dialog.dismiss();
|
||||
try {
|
||||
Helper.removeAccount(BaseMainActivity.this, null);
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
alt_bld.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
|
||||
AlertDialog alert = alt_bld.create();
|
||||
alert.show();
|
||||
return true;
|
||||
} else if (itemId == R.id.action_about_instance) {
|
||||
Intent intent = new Intent(BaseMainActivity.this, InstanceActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
} else if (itemId == R.id.action_cache) {
|
||||
new Helper.CacheTask(BaseMainActivity.this);
|
||||
return true;
|
||||
} else if (itemId == R.id.action_proxy) {
|
||||
Intent intent = new Intent(BaseMainActivity.this, ProxyActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
popup.show();
|
||||
});
|
||||
account = null;
|
||||
//Update account details
|
||||
new Thread(() -> {
|
||||
try {
|
||||
account = new Account(BaseMainActivity.this).getConnectedAccount();
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
if (account == null) {
|
||||
//It is not, the user is redirected to the login page
|
||||
Intent myIntent = new Intent(BaseMainActivity.this, LoginActivity.class);
|
||||
startActivity(myIntent);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
currentInstance = account.instance;
|
||||
currentUserID = account.user_id;
|
||||
accountWeakReference = new WeakReference<>(account);
|
||||
binding.profilePicture.setOnClickListener(v -> binding.drawerLayout.openDrawer(GravityCompat.START));
|
||||
Helper.loadPP(binding.profilePicture, account);
|
||||
headerMainBinding.accountAcc.setText(String.format("%s@%s", account.mastodon_account.username, account.instance));
|
||||
if (account.mastodon_account.display_name.isEmpty()) {
|
||||
account.mastodon_account.display_name = account.mastodon_account.acct;
|
||||
}
|
||||
headerMainBinding.accountName.setText(account.mastodon_account.display_name);
|
||||
|
||||
Helper.loadPP(headerMainBinding.accountProfilePicture, account);
|
||||
|
||||
/*
|
||||
* Some general data are loaded when the app starts such;
|
||||
* - Instance info (for limits)
|
||||
* - Emoji for picker
|
||||
* - Filters for timelines
|
||||
* - Pinned timelines (in app feature)
|
||||
*/
|
||||
|
||||
//Update emoji in db for the current instance
|
||||
new ViewModelProvider(BaseMainActivity.this).get(InstancesVM.class).getEmoji(currentInstance);
|
||||
//Retrieve instance info
|
||||
new ViewModelProvider(BaseMainActivity.this).get(InstancesVM.class).getInstance(currentInstance)
|
||||
.observe(BaseMainActivity.this, instance -> instanceInfo = instance.info);
|
||||
//Retrieve filters
|
||||
new ViewModelProvider(BaseMainActivity.this).get(AccountsVM.class).getFilters(currentInstance, currentToken)
|
||||
.observe(BaseMainActivity.this, filters -> mainFilters = filters);
|
||||
new ViewModelProvider(BaseMainActivity.this).get(AccountsVM.class).getConnectedAccount(currentInstance, currentToken)
|
||||
.observe(BaseMainActivity.this, account1 -> {
|
||||
BaseMainActivity.accountWeakReference.get().mastodon_account = account1;
|
||||
});
|
||||
//Update pinned timelines
|
||||
new ViewModelProvider(BaseMainActivity.this).get(TopBarVM.class).getDBPinned()
|
||||
.observe(this, pinned -> {
|
||||
this.pinned = pinned;
|
||||
//First it's taken from db (last stored values)
|
||||
PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, null);
|
||||
//Fetch remote lists for the authenticated account and update them
|
||||
new ViewModelProvider(BaseMainActivity.this).get(TimelinesVM.class).getLists(currentInstance, currentToken)
|
||||
.observe(this, mastodonLists -> PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, mastodonLists));
|
||||
});
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
}).start();
|
||||
//Toolbar search
|
||||
binding.toolbarSearch.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
//Hide keyboard
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(binding.toolbarSearch.getWindowToken(), 0);
|
||||
query = query.replaceAll("^#+", "");
|
||||
Intent intent;
|
||||
intent = new Intent(BaseMainActivity.this, SearchResultTabActivity.class);
|
||||
intent.putExtra(Helper.ARG_SEARCH_KEYWORD, query);
|
||||
startActivity(intent);
|
||||
binding.toolbarSearch.setQuery("", false);
|
||||
binding.toolbarSearch.setIconified(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
binding.toolbarSearch.setOnCloseListener(() -> {
|
||||
binding.tabLayout.setVisibility(View.VISIBLE);
|
||||
return false;
|
||||
});
|
||||
|
||||
PushHelper.startStreaming(BaseMainActivity.this);
|
||||
|
||||
binding.toolbarSearch.setOnSearchClickListener(v -> binding.tabLayout.setVisibility(View.VISIBLE));
|
||||
//For receiving data from other activities
|
||||
LocalBroadcastManager.getInstance(BaseMainActivity.this).registerReceiver(broadcast_data, new IntentFilter(Helper.BROADCAST_DATA));
|
||||
}
|
||||
|
||||
public void refreshFragment() {
|
||||
if (binding.viewPager.getAdapter() != null) {
|
||||
binding.viewPager.getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
LocalBroadcastManager.getInstance(BaseMainActivity.this).unregisterReceiver(broadcast_data);
|
||||
if (networkStateReceiver != null) {
|
||||
try {
|
||||
unregisterReceiver(networkStateReceiver);
|
||||
} catch (IllegalArgumentException illegalArgumentException) {
|
||||
illegalArgumentException.printStackTrace();
|
||||
}
|
||||
}
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(BaseMainActivity.this);
|
||||
boolean clearCacheExit = sharedpreferences.getBoolean(getString(R.string.SET_CLEAR_CACHE_EXIT), false);
|
||||
//Clear cache when leaving - Default = false
|
||||
if (clearCacheExit) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
if (getCacheDir().getParentFile() != null) {
|
||||
String path = getCacheDir().getParentFile().getPath();
|
||||
File dir = new File(path);
|
||||
if (dir.isDirectory()) {
|
||||
deleteDir(dir);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
public void redrawPinned(List<MastodonList> mastodonLists) {
|
||||
int currentItem = binding.viewPager.getCurrentItem();
|
||||
new ViewModelProvider(BaseMainActivity.this).get(TopBarVM.class).getDBPinned()
|
||||
.observe(this, pinned -> {
|
||||
this.pinned = pinned;
|
||||
//First it's taken from db (last stored values)
|
||||
PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, mastodonLists);
|
||||
binding.viewPager.setCurrentItem(currentItem);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
binding.drawerLayout.closeDrawer(GravityCompat.START);
|
||||
} else {
|
||||
int fragments = getSupportFragmentManager().getBackStackEntryCount();
|
||||
if (fragments == 1) {
|
||||
finish();
|
||||
} else if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
|
||||
getSupportFragmentManager().popBackStack();
|
||||
List<Fragment> fragmentList = getSupportFragmentManager().getFragments();
|
||||
for (Fragment fragment : fragmentList) {
|
||||
if (fragment != null && fragment.isVisible()) {
|
||||
|
||||
if (fragment instanceof FragmentMastodonTimeline) {
|
||||
currentFragment = fragment;
|
||||
getSupportFragmentManager().beginTransaction().show(currentFragment).commit();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getFloatingVisibility() {
|
||||
return binding.compose.getVisibility() == View.VISIBLE;
|
||||
}
|
||||
|
||||
public void manageFloatingButton(boolean display) {
|
||||
if (display) {
|
||||
binding.compose.show();
|
||||
} else {
|
||||
binding.compose.hide();
|
||||
}
|
||||
}
|
||||
|
||||
/* @Override
|
||||
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_logout) {
|
||||
AlertDialog.Builder alt_bld = new AlertDialog.Builder(BaseMainActivity.this, Helper.dialogStyle());
|
||||
alt_bld.setTitle(R.string.action_logout);
|
||||
alt_bld.setMessage(getString(R.string.logout_account_confirmation, account.mastodon_account.username, account.instance));
|
||||
alt_bld.setPositiveButton(R.string.action_logout, (dialog, id) -> {
|
||||
dialog.dismiss();
|
||||
try {
|
||||
Helper.removeAccount(BaseMainActivity.this, null);
|
||||
} catch (DBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
alt_bld.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
|
||||
AlertDialog alert = alt_bld.create();
|
||||
alert.show();
|
||||
|
||||
}
|
||||
return true;
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public boolean onSupportNavigateUp() {
|
||||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
|
||||
//unselect all tag elements
|
||||
for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) {
|
||||
pinnedTimeline.isSelected = false;
|
||||
}
|
||||
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|
||||
|| super.onSupportNavigateUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void networkAvailable() {
|
||||
networkAvailable = status.CONNECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void networkUnavailable() {
|
||||
networkAvailable = DISCONNECTED;
|
||||
}
|
||||
|
||||
|
||||
public enum status {
|
||||
UNKNOWN,
|
||||
CONNECTED,
|
||||
DISCONNECTED
|
||||
}
|
||||
}
|