Commit 34887955 authored by Thomas's avatar Thomas
Browse files

Add release notes

parent c033064d
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
[
  {
    "version": "3.0.9",
    "code": "399",
    "note": "Added:\n- Set compose language (from compose menu -> three vertical dots)\n- Add reactions support for Pleroma\n- Add privacy indicator at the top right\n\nChanged\n- Improve the scrolling behaviour\n- Scroll to top (tab reselection) will fetch new messages and then scroll to top\n\nFixed:\n- Empty tag timelines\n- Remove focus point for fit media preview\n- Fix cannot share with one account\n- Fix black theme\n- Theme cannot be selected\n- Fix some button colors"
  },
  {
    "version": "3.0.8",
    "code": "398",
    "note": "- Keep improving the scroll behaviour\n- Scroll to top (tab reselection) will fetch new messages and then scroll to top\n- Remove focus point for fit media preview\n- Fix cannot share with one account\n- Fix black theme\n- Fix some button colors"
  },
  {
    "version": "3.0.7",
    "code": "397",
    "note": "- Fix some bugs reported."
  },
  {
    "version": "3.0.6",
    "code": "396",
    "note": "Added:\n- Allow to set a focus point on previews (media editor)\n- Respect the focus point with previews\n- Pagination with the fetch more button support reading up or down\n- Add trends\n\nFixed:\n- Only last push notification is displayed (not grouped)\n- Bad behavior with the right/left scroll\n- Fix long profiles not fully displayed\n- Issues with some polls\n- Some crashes\n- Some bad behaviors"
  },
  {
    "version": "3.0.5",
    "code": "395",
    "note": "- Fix some bugs\n- Allow to share with the app"
  },
  {
    "version": "3.0.4",
    "code": "394",
    "note": "- Fix crashes for some Pleroma instances"
  },
  {
    "version": "3.0.2",
    "code": "393",
    "note": "- Some bug fixes\n- Improve pinned timelines"
  },
  {
    "version": "3.0.1",
    "code": "391",
    "note": "Some quick fixes"
  },
  {
    "version": "3.0.0",
    "code": "390",
    "note": "New version of Fedilab with new feature.\n- You can now compose threads\n- See the whole thread when replying\n- Cache support\n- New design"
  }
]
 No newline at end of file
+7 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ import static app.fedilab.android.BaseMainActivity.status.DISCONNECTED;
import static app.fedilab.android.BaseMainActivity.status.UNKNOWN;
import static app.fedilab.android.helper.CacheHelper.deleteDir;
import static app.fedilab.android.helper.Helper.PREF_USER_TOKEN;
import static app.fedilab.android.helper.Helper.displayReleaseNotesIfNeeded;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
@@ -504,6 +505,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
            } else if (id == R.id.nav_about) {
                Intent intent = new Intent(this, AboutActivity.class);
                startActivity(intent);
            } else if (id == R.id.nav_release_notes) {
                displayReleaseNotesIfNeeded(BaseMainActivity.this, true);
            } else if (id == R.id.nav_partnership) {
                Intent intent = new Intent(this, PartnerShipActivity.class);
                startActivity(intent);
@@ -523,6 +526,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
            binding.drawerLayout.close();
            return false;
        });


        headerMainBinding.instanceInfo.setOnClickListener(v -> startActivity(new Intent(BaseMainActivity.this, InstanceHealthActivity.class)));
        headerMainBinding.accountProfilePicture.setOnClickListener(v -> {
            Intent intent = new Intent(BaseMainActivity.this, ProfileActivity.class);
@@ -758,6 +763,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt

                currentInstance = currentAccount.instance;
                currentUserID = currentAccount.user_id;

                show_boosts = sharedpreferences.getBoolean(getString(R.string.SET_SHOW_BOOSTS) + currentUserID + currentInstance, true);
                show_replies = sharedpreferences.getBoolean(getString(R.string.SET_SHOW_REPLIES) + currentUserID + currentInstance, true);
                regex_home = sharedpreferences.getString(getString(R.string.SET_FILTER_REGEX_HOME) + currentUserID + currentInstance, null);
@@ -798,6 +804,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
                        .observe(BaseMainActivity.this, mastodonAccount -> {
                            //Initialize static var
                            currentAccount.mastodon_account = mastodonAccount;
                            displayReleaseNotesIfNeeded(BaseMainActivity.this, false);
                            new Thread(() -> {
                                try {
                                    //Update account in db
+39 −0
Original line number Diff line number Diff line
package app.fedilab.android.client.entities.app;
/* 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>. */

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;
import java.util.List;


public class ReleaseNote implements Serializable {

    @SerializedName("languages")
    public List<Note> ReleaseNotes;


    public static class Note implements Serializable {
        @SerializedName("code")
        public String code;
        @SerializedName("version")
        public String version;
        @SerializedName("note")
        public String note;
        @SerializedName("noteTranslated")
        public String noteTranslated;
    }
}
+120 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
@@ -81,10 +82,12 @@ import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
@@ -95,6 +98,7 @@ import com.bumptech.glide.request.RequestOptions;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
@@ -115,10 +119,12 @@ import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
@@ -133,19 +139,26 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;

import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.BuildConfig;
import app.fedilab.android.MainApplication;
import app.fedilab.android.R;
import app.fedilab.android.activities.ComposeActivity;
import app.fedilab.android.activities.LoginActivity;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.activities.ProfileActivity;
import app.fedilab.android.activities.WebviewActivity;
import app.fedilab.android.broadcastreceiver.ToastMessage;
import app.fedilab.android.client.entities.api.Attachment;
import app.fedilab.android.client.entities.api.Status;
import app.fedilab.android.client.entities.app.Account;
import app.fedilab.android.client.entities.app.BaseAccount;
import app.fedilab.android.client.entities.app.ReleaseNote;
import app.fedilab.android.databinding.PopupReleaseNotesBinding;
import app.fedilab.android.exception.DBException;
import app.fedilab.android.interfaces.OnDownloadInterface;
import app.fedilab.android.sqlite.Sqlite;
import app.fedilab.android.ui.drawer.ReleaseNoteAdapter;
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
import app.fedilab.android.viewmodel.mastodon.OauthVM;
import app.fedilab.android.watermark.androidwm.WatermarkBuilder;
import app.fedilab.android.watermark.androidwm.bean.WatermarkText;
@@ -1749,4 +1762,111 @@ public class Helper {
        return null;
    }


    public static void displayReleaseNotesIfNeeded(Activity activity, boolean forced) {
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
        int lastReleaseNoteRead = sharedpreferences.getInt(activity.getString(R.string.SET_POPUP_RELEASE_NOTES), 0);
        int versionCode = BuildConfig.VERSION_CODE;
        if (lastReleaseNoteRead != versionCode || forced) {
            try {
                InputStream is = activity.getAssets().open("release_notes/notes.json");
                int size;
                size = is.available();
                byte[] buffer = new byte[size];
                is.read(buffer);
                is.close();
                String json = new String(buffer, StandardCharsets.UTF_8);
                Gson gson = new Gson();
                AlertDialog.Builder dialogBuilderOptin = new AlertDialog.Builder(activity, Helper.dialogStyle());
                PopupReleaseNotesBinding binding = PopupReleaseNotesBinding.inflate(activity.getLayoutInflater());
                dialogBuilderOptin.setView(binding.getRoot());
                try {
                    List<ReleaseNote.Note> releaseNotes = gson.fromJson(json, new TypeToken<List<ReleaseNote.Note>>() {
                    }.getType());
                    if (releaseNotes != null && releaseNotes.size() > 0) {
                        ReleaseNoteAdapter adapter = new ReleaseNoteAdapter(releaseNotes);
                        binding.releasenotes.setAdapter(adapter);
                        binding.releasenotes.setLayoutManager(new LinearLayoutManager(activity));
                    }
                } catch (Exception ignored) {
                }
                if (BuildConfig.DONATIONS) {
                    binding.aboutSupport.setVisibility(View.VISIBLE);
                    binding.aboutSupportPaypal.setVisibility(View.VISIBLE);
                } else {
                    binding.aboutSupport.setVisibility(View.GONE);
                    binding.aboutSupportPaypal.setVisibility(View.GONE);
                }
                binding.accountFollow.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(activity));
                binding.accountFollow.setImageResource(R.drawable.ic_baseline_person_add_24);
                binding.aboutSupport.setOnClickListener(v -> {
                    Intent intentLiberapay = new Intent(Intent.ACTION_VIEW);
                    intentLiberapay.setData(Uri.parse("https://liberapay.com/tom79"));
                    try {
                        activity.startActivity(intentLiberapay);
                    } catch (Exception e) {
                        Helper.openBrowser(activity, "https://liberapay.com/tom79");
                    }
                });
                binding.aboutSupportPaypal.setOnClickListener(v -> Helper.openBrowser(activity, "https://www.paypal.me/Mastalab"));
                CrossActionHelper.fetchRemoteAccount(activity, "@apps@toot.fedilab.app", new CrossActionHelper.Callback() {
                    @Override
                    public void federatedStatus(Status status) {

                    }

                    @Override
                    public void federatedAccount(app.fedilab.android.client.entities.api.Account account) {
                        if (account != null && account.username.equalsIgnoreCase("apps")) {

                            MastodonHelper.loadPPMastodon(binding.accountPp, account);
                            binding.accountDn.setText(account.display_name);
                            binding.accountUn.setText(account.acct);
                            binding.accountPp.setOnClickListener(v -> {
                                Intent intent = new Intent(activity, ProfileActivity.class);
                                Bundle b = new Bundle();
                                b.putSerializable(Helper.ARG_ACCOUNT, account);
                                intent.putExtras(b);
                                ActivityOptionsCompat options = ActivityOptionsCompat
                                        .makeSceneTransitionAnimation(activity, binding.accountPp, activity.getString(R.string.activity_porfile_pp));
                                activity.startActivity(intent, options.toBundle());
                            });

                            AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) activity).get(AccountsVM.class);
                            List<String> ids = new ArrayList<>();
                            ids.add(account.id);
                            accountsVM.getRelationships(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, ids)
                                    .observe((LifecycleOwner) activity, relationShips -> {
                                        if (relationShips != null && relationShips.size() > 0) {
                                            if (!relationShips.get(0).following) {
                                                binding.acccountContainer.setVisibility(View.VISIBLE);
                                                binding.accountFollow.setVisibility(View.VISIBLE);
                                                binding.accountFollow.setOnClickListener(v -> accountsVM.follow(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, account.id, true, false)
                                                        .observe((LifecycleOwner) activity, relationShip -> binding.accountFollow.setVisibility(View.GONE)));
                                            }
                                        }
                                    });
                        }
                    }
                });
                dialogBuilderOptin.setPositiveButton(R.string.close, (dialog, id) -> dialog.dismiss());
                try {
                    Handler handler = new Handler();
                    handler.postDelayed(() -> {
                        if (!activity.isFinishing()) {
                            dialogBuilderOptin.show();
                        }
                    }, 1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            SharedPreferences.Editor editor = sharedpreferences.edit();
            editor.putInt(activity.getString(R.string.SET_POPUP_RELEASE_NOTES), versionCode);
            editor.apply();
        }
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -144,9 +144,9 @@ public class SpannableHelper {
        } else {
            content = new SpannableStringBuilder(text);
        }
        if (emojiList != null && emojiList.size() > 0) {
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
        boolean animate = !sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_ANIMATED_EMOJI), false);
        if (emojiList != null && emojiList.size() > 0) {
            for (Emoji emoji : emojiList) {
                Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL)
                        .matcher(content);
@@ -173,7 +173,7 @@ public class SpannableHelper {
                    Glide.with(view)
                            .asDrawable()
                            .load(url)
                            .into(customEmoji.getTarget(true));
                            .into(customEmoji.getTarget(animate));
                }
            }

Loading