diff --git a/app/build.gradle b/app/build.gradle
index f539362a..f30ea1d6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,9 +9,8 @@ android {
defaultConfig {
minSdk 21
targetSdk 31
- versionCode 21
- versionName "beta-21"
-
+ versionCode 385
+ versionName "3.0.0-beta-22"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
flavorDimensions "default"
@@ -27,13 +26,13 @@ android {
}
productFlavors {
fdroid {
- applicationId "fr.gouv.etalab.mastodon.test"
+ applicationId "fr.gouv.etalab.mastodon"
buildConfigField "boolean", "DONATIONS", "true"
buildConfigField "boolean", "push", "false"
flavor = "fdroid"
}
playstore {
- applicationId "app.fedilab.android.test"
+ applicationId "app.fedilab.android"
buildConfigField "boolean", "DONATIONS", "false"
buildConfigField "boolean", "push", "true"
flavor = "playstore"
@@ -98,8 +97,8 @@ dependencies {
implementation project(path: ':cropper')
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.github.penfeizhou.android.animation:apng:2.22.0'
+ implementation 'com.github.penfeizhou.android.animation:gif:2.22.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'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 40873aea..4f6b36d7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -108,6 +108,12 @@
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/action_about"
android:theme="@style/AppThemeBar" />
+
+
Helper.openBrowser(AboutActivity.this, "https://www.paypal.me/Mastalab"));
-
+ binding.accountFollow.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(AboutActivity.this));
if (BuildConfig.DONATIONS) {
binding.aboutSupportPaypal.setVisibility(View.VISIBLE);
} else {
binding.aboutSupportPaypal.setVisibility(View.GONE);
}
+ binding.accountFollow.setImageResource(R.drawable.ic_baseline_person_add_24);
binding.aboutWebsite.setOnClickListener(v -> Helper.openBrowser(AboutActivity.this, "https://fedilab.app"));
CrossActionHelper.fetchRemoteAccount(AboutActivity.this, "@apps@toot.fedilab.app", new CrossActionHelper.Callback() {
@Override
diff --git a/app/src/main/java/app/fedilab/android/activities/PartnerShipActivity.java b/app/src/main/java/app/fedilab/android/activities/PartnerShipActivity.java
new file mode 100644
index 00000000..3e17e678
--- /dev/null
+++ b/app/src/main/java/app/fedilab/android/activities/PartnerShipActivity.java
@@ -0,0 +1,139 @@
+package app.fedilab.android.activities;
+/* 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 . */
+
+
+import android.content.Intent;
+import android.graphics.drawable.ColorDrawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.method.LinkMovementMethod;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.core.app.ActivityOptionsCompat;
+import androidx.core.content.ContextCompat;
+import androidx.lifecycle.ViewModelProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import app.fedilab.android.R;
+import app.fedilab.android.client.entities.api.Account;
+import app.fedilab.android.client.entities.api.Status;
+import app.fedilab.android.databinding.ActivityPartnershipBinding;
+import app.fedilab.android.helper.CrossActionHelper;
+import app.fedilab.android.helper.Helper;
+import app.fedilab.android.helper.MastodonHelper;
+import app.fedilab.android.helper.ThemeHelper;
+import app.fedilab.android.viewmodel.mastodon.AccountsVM;
+
+
+public class PartnerShipActivity extends BaseActivity {
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ThemeHelper.applyThemeBar(this);
+ ActivityPartnershipBinding binding = ActivityPartnershipBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
+
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary)));
+ }
+
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
+ assert inflater != null;
+ View view = inflater.inflate(R.layout.simple_bar, new LinearLayout(PartnerShipActivity.this), false);
+ view.setBackground(new ColorDrawable(ContextCompat.getColor(PartnerShipActivity.this, R.color.cyanea_primary)));
+ actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+ ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
+ TextView toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
+ toolbar_close.setOnClickListener(v -> finish());
+ toolbar_title.setText(R.string.action_partnership);
+ }
+
+ TextView about_partnership = findViewById(R.id.about_partnership);
+ about_partnership.setMovementMethod(LinkMovementMethod.getInstance());
+
+ binding.mastohostLogo.setOnClickListener(v -> {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://masto.host"));
+ startActivity(browserIntent);
+ });
+ binding.accountFollow.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(PartnerShipActivity.this));
+ setTitle(R.string.action_partnership);
+ binding.accountFollow.setImageResource(R.drawable.ic_baseline_person_add_24);
+ CrossActionHelper.fetchRemoteAccount(PartnerShipActivity.this, "@mastohost@mastodon.social", new CrossActionHelper.Callback() {
+ @Override
+ public void federatedStatus(Status status) {
+
+ }
+
+ @Override
+ public void federatedAccount(Account account) {
+ if (account != null && account.username.equalsIgnoreCase("mastohost")) {
+ binding.acccountContainer.setVisibility(View.VISIBLE);
+ MastodonHelper.loadPPMastodon(binding.accountPp, account);
+ binding.accountDn.setText(account.display_name);
+ binding.accountUn.setText(account.acct);
+ binding.accountPp.setOnClickListener(v -> {
+ Intent intent = new Intent(PartnerShipActivity.this, ProfileActivity.class);
+ Bundle b = new Bundle();
+ b.putSerializable(Helper.ARG_ACCOUNT, account);
+ intent.putExtras(b);
+ ActivityOptionsCompat options = ActivityOptionsCompat
+ .makeSceneTransitionAnimation(PartnerShipActivity.this, binding.accountPp, getString(R.string.activity_porfile_pp));
+ startActivity(intent, options.toBundle());
+ });
+ AccountsVM accountsVM = new ViewModelProvider(PartnerShipActivity.this).get(AccountsVM.class);
+ List ids = new ArrayList<>();
+ ids.add(account.id);
+ accountsVM.getRelationships(MainActivity.currentInstance, MainActivity.currentToken, ids)
+ .observe(PartnerShipActivity.this, relationShips -> {
+ if (relationShips != null && relationShips.size() > 0) {
+ if (!relationShips.get(0).following) {
+ binding.accountFollow.setVisibility(View.VISIBLE);
+ binding.accountFollow.setOnClickListener(v -> accountsVM.follow(MainActivity.currentInstance, MainActivity.currentToken, account.id, true, false)
+ .observe(PartnerShipActivity.this, relationShip -> binding.accountFollow.setVisibility(View.GONE)));
+ }
+ }
+ });
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+}
diff --git a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java
index 1a131c75..e73afa80 100644
--- a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java
+++ b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java
@@ -536,7 +536,7 @@ public class ProfileActivity extends BaseActivity {
private void updateAccount() {
//The value for account is from same server so id can be used
- if (account.id.equals(BaseMainActivity.accountWeakReference.get().user_id)) {
+ if (BaseMainActivity.accountWeakReference.get() != null && account.id.equals(BaseMainActivity.accountWeakReference.get().user_id)) {
binding.accountFollow.setVisibility(View.GONE);
binding.headerEditProfile.setVisibility(View.VISIBLE);
binding.headerEditProfile.bringToFront();
@@ -563,20 +563,7 @@ public class ProfileActivity extends BaseActivity {
});
}
}
- int[][] states = new int[][]{
- new int[]{android.R.attr.state_enabled}, // enabled
- new int[]{-android.R.attr.state_enabled}, // disabled
- new int[]{-android.R.attr.state_checked}, // unchecked
- new int[]{android.R.attr.state_pressed} // pressed
- };
-
- int[] colors = new int[]{
- ContextCompat.getColor(ProfileActivity.this, R.color.mastodonC4),
- ContextCompat.getColor(ProfileActivity.this, R.color.mastodonC4___),
- ContextCompat.getColor(ProfileActivity.this, R.color.mastodonC4),
- ContextCompat.getColor(ProfileActivity.this, R.color.mastodonC4)
- };
- binding.accountFollow.setBackgroundTintList(new ColorStateList(states, colors));
+ binding.accountFollow.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(ProfileActivity.this));
binding.accountFollow.setEnabled(true);
//Visibility depending of the relationship
if (relationship != null) {
diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java
index 04599fbb..b3ab9680 100644
--- a/app/src/main/java/app/fedilab/android/helper/Helper.java
+++ b/app/src/main/java/app/fedilab/android/helper/Helper.java
@@ -151,6 +151,7 @@ public class Helper {
public static final String INSTANCE_SOCIAL_KEY = "jGj9gW3z9ptyIpB8CMGhAlTlslcemMV6AgoiImfw3vPP98birAJTHOWiu5ZWfCkLvcaLsFZw9e3Pb7TIwkbIyrj3z6S7r2oE6uy6EFHvls3YtapP8QKNZ980p9RfzTb4";
public static final String WEBSITE_VALUE = "https://fedilab.app";
+ public static final String OLD_DB_NAME = "mastodon_etalab_db";
public static final String RECEIVE_TOAST_MESSAGE = "RECEIVE_TOAST_MESSAGE";
public static final String RECEIVE_TOAST_TYPE = "RECEIVE_TOAST_TYPE";
@@ -1572,4 +1573,28 @@ public class Helper {
}).start();
}
}
+
+
+ public static void transfertIfExist(Context context) {
+ File dbFile = context.getDatabasePath(OLD_DB_NAME);
+ if (!dbFile.exists()) {
+ return;
+ }
+ int version = -1;
+ try {
+ SQLiteDatabase sqlDb = SQLiteDatabase.openDatabase
+ (context.getDatabasePath(OLD_DB_NAME).getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);
+ version = sqlDb.getVersion();
+ } catch (Exception ignored) {
+ }
+ try {
+ if (version == -1) {
+ version = 38;
+ }
+ SQLiteDatabase oldDb = Sqlite.getInstance(context.getApplicationContext(), OLD_DB_NAME, null, version).open();
+
+ } catch (Exception ignored) {
+ }
+ context.deleteDatabase(OLD_DB_NAME);
+ }
}
diff --git a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java
index 2886b552..8b5397b8 100644
--- a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java
+++ b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java
@@ -263,10 +263,13 @@ public class PinnedTimelineHelper {
try {
//If some menu items have been hidden we should not create tab for them
bottomMenuDb = new BottomMenu(context).getAllBottomMenu(MainActivity.accountWeakReference.get());
- if (bottomMenuDb != null && bottomMenuDb.bottom_menu != null) {
- for (BottomMenu.MenuItem menuItem : bottomMenuDb.bottom_menu) {
- if (!menuItem.visible) {
- toRemove++;
+ if (bottomMenuDb != null) {
+ List menuItemList = bottomMenuDb.bottom_menu;
+ if (menuItemList != null) {
+ for (BottomMenu.MenuItem menuItem : menuItemList) {
+ if (!menuItem.visible) {
+ toRemove++;
+ }
}
}
}
diff --git a/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java b/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java
index faefd557..f5204a67 100644
--- a/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java
+++ b/app/src/main/java/app/fedilab/android/helper/SpannableHelper.java
@@ -710,8 +710,8 @@ public class SpannableHelper {
} catch (Exception ignored) {
}
} else {
- Drawable drawable = Drawable.createFromPath(file.getAbsolutePath());
try {
+ Drawable drawable = Drawable.createFromPath(file.getAbsolutePath());
drawable.setBounds(0, 0, (int) convertDpToPixel(20, context), (int) convertDpToPixel(20, context));
drawable.setVisible(true, true);
imageSpan = new ImageSpan(drawable);
diff --git a/app/src/main/java/app/fedilab/android/helper/ThemeHelper.java b/app/src/main/java/app/fedilab/android/helper/ThemeHelper.java
index 5ceefee6..cbdab195 100644
--- a/app/src/main/java/app/fedilab/android/helper/ThemeHelper.java
+++ b/app/src/main/java/app/fedilab/android/helper/ThemeHelper.java
@@ -282,6 +282,24 @@ public class ThemeHelper {
return new ColorStateList(states, colors);
}
+ public static ColorStateList getButtonActionColorStateList(Context context) {
+ int[][] states = new int[][]{
+ new int[]{android.R.attr.state_enabled}, // enabled
+ new int[]{-android.R.attr.state_enabled}, // disabled
+ new int[]{-android.R.attr.state_checked}, // unchecked
+ new int[]{android.R.attr.state_pressed} // pressed
+ };
+ int alphaColor = ColorUtils.setAlphaComponent(ContextCompat.getColor(context, R.color.cyanea_accent_dark_reference), 0x33);
+ int color = ContextCompat.getColor(context, R.color.cyanea_accent_dark_reference);
+ int[] colors = new int[]{
+ color,
+ alphaColor,
+ color,
+ color
+ };
+ return new ColorStateList(states, colors);
+ }
+
/**
* Allow to set colors for having description on media
diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java
index 6da90395..7f018916 100644
--- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java
+++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java
@@ -149,8 +149,11 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
private int getPosition(Status status) {
int position = 0;
boolean found = false;
+ if (status.id == null) {
+ return -1;
+ }
for (Status _status : statuses) {
- if (_status.id.compareTo(status.id) == 0) {
+ if (_status.id != null && _status.id.compareTo(status.id) == 0) {
found = true;
break;
}
diff --git a/app/src/main/res/drawable/ic_baseline_account_circle_24.xml b/app/src/main/res/drawable/ic_baseline_account_circle_24.xml
new file mode 100644
index 00000000..0b3fa82b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_account_circle_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/mastohost.png b/app/src/main/res/drawable/mastohost.png
new file mode 100644
index 00000000..f67e795c
Binary files /dev/null and b/app/src/main/res/drawable/mastohost.png differ
diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml
index bd9f11ac..643aa2c0 100644
--- a/app/src/main/res/layout/activity_about.xml
+++ b/app/src/main/res/layout/activity_about.xml
@@ -61,8 +61,11 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml
index cdbc7e8e..87296e93 100644
--- a/app/src/main/res/menu/activity_main_drawer.xml
+++ b/app/src/main/res/menu/activity_main_drawer.xml
@@ -50,5 +50,10 @@
android:id="@+id/nav_about"
android:icon="@drawable/ic_baseline_info_24"
android:title="@string/action_about" />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e194a070..a0106270 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -542,7 +542,7 @@
Follow instance
You already follow this instance!
The instance is followed!
- Masto.host is our Mastodon hosting partner.\n\nWith this partnership they provide me free hosting for Mastalab\'s instance and in exchange I promote them in here.\n\nTo be clear, there is no money involved or tracking of users. I needed an instance for testing, we talked and agreed on this.\n\nGo check them out if you want to run your own Mastodon instance.
+ Masto.host is our Mastodon hosting partner.\n\nWith this partnership they provide me free hosting for Fedilab\'s instance and in exchange I promote them in here.\n\nTo be clear, there is no money involved or tracking of users. I needed an instance for testing, we talked and agreed on this.\n\nGo check them out if you want to run your own Mastodon instance.
Partnerships
Information