forked from mirrors/Fedilab
Add release notes
This commit is contained in:
parent
c033064d13
commit
3488795520
12 changed files with 559 additions and 4 deletions
47
app/src/main/assets/release_notes/notes.json
Normal file
47
app/src/main/assets/release_notes/notes.json
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
|
@ -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.BaseMainActivity.status.UNKNOWN;
|
||||||
import static app.fedilab.android.helper.CacheHelper.deleteDir;
|
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.PREF_USER_TOKEN;
|
||||||
|
import static app.fedilab.android.helper.Helper.displayReleaseNotesIfNeeded;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
|
@ -504,6 +505,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
||||||
} else if (id == R.id.nav_about) {
|
} else if (id == R.id.nav_about) {
|
||||||
Intent intent = new Intent(this, AboutActivity.class);
|
Intent intent = new Intent(this, AboutActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
} else if (id == R.id.nav_release_notes) {
|
||||||
|
displayReleaseNotesIfNeeded(BaseMainActivity.this, true);
|
||||||
} else if (id == R.id.nav_partnership) {
|
} else if (id == R.id.nav_partnership) {
|
||||||
Intent intent = new Intent(this, PartnerShipActivity.class);
|
Intent intent = new Intent(this, PartnerShipActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
@ -523,6 +526,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
||||||
binding.drawerLayout.close();
|
binding.drawerLayout.close();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
headerMainBinding.instanceInfo.setOnClickListener(v -> startActivity(new Intent(BaseMainActivity.this, InstanceHealthActivity.class)));
|
headerMainBinding.instanceInfo.setOnClickListener(v -> startActivity(new Intent(BaseMainActivity.this, InstanceHealthActivity.class)));
|
||||||
headerMainBinding.accountProfilePicture.setOnClickListener(v -> {
|
headerMainBinding.accountProfilePicture.setOnClickListener(v -> {
|
||||||
Intent intent = new Intent(BaseMainActivity.this, ProfileActivity.class);
|
Intent intent = new Intent(BaseMainActivity.this, ProfileActivity.class);
|
||||||
|
@ -758,6 +763,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
||||||
|
|
||||||
currentInstance = currentAccount.instance;
|
currentInstance = currentAccount.instance;
|
||||||
currentUserID = currentAccount.user_id;
|
currentUserID = currentAccount.user_id;
|
||||||
|
|
||||||
show_boosts = sharedpreferences.getBoolean(getString(R.string.SET_SHOW_BOOSTS) + currentUserID + currentInstance, true);
|
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);
|
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);
|
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 -> {
|
.observe(BaseMainActivity.this, mastodonAccount -> {
|
||||||
//Initialize static var
|
//Initialize static var
|
||||||
currentAccount.mastodon_account = mastodonAccount;
|
currentAccount.mastodon_account = mastodonAccount;
|
||||||
|
displayReleaseNotesIfNeeded(BaseMainActivity.this, false);
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
//Update account in db
|
//Update account in db
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,6 +74,7 @@ import androidx.annotation.IdRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.core.app.ActivityOptionsCompat;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
import androidx.core.app.NotificationManagerCompat;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
@ -81,10 +82,12 @@ import androidx.core.graphics.drawable.DrawableCompat;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.lifecycle.ViewModelStoreOwner;
|
import androidx.lifecycle.ViewModelStoreOwner;
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.bumptech.glide.RequestBuilder;
|
import com.bumptech.glide.RequestBuilder;
|
||||||
|
@ -95,6 +98,7 @@ import com.bumptech.glide.request.RequestOptions;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.TypeAdapter;
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
import com.google.gson.stream.JsonToken;
|
import com.google.gson.stream.JsonToken;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
@ -115,10 +119,12 @@ import java.net.InetSocketAddress;
|
||||||
import java.net.PasswordAuthentication;
|
import java.net.PasswordAuthentication;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -133,19 +139,26 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import app.fedilab.android.BaseMainActivity;
|
import app.fedilab.android.BaseMainActivity;
|
||||||
|
import app.fedilab.android.BuildConfig;
|
||||||
import app.fedilab.android.MainApplication;
|
import app.fedilab.android.MainApplication;
|
||||||
import app.fedilab.android.R;
|
import app.fedilab.android.R;
|
||||||
import app.fedilab.android.activities.ComposeActivity;
|
import app.fedilab.android.activities.ComposeActivity;
|
||||||
import app.fedilab.android.activities.LoginActivity;
|
import app.fedilab.android.activities.LoginActivity;
|
||||||
import app.fedilab.android.activities.MainActivity;
|
import app.fedilab.android.activities.MainActivity;
|
||||||
|
import app.fedilab.android.activities.ProfileActivity;
|
||||||
import app.fedilab.android.activities.WebviewActivity;
|
import app.fedilab.android.activities.WebviewActivity;
|
||||||
import app.fedilab.android.broadcastreceiver.ToastMessage;
|
import app.fedilab.android.broadcastreceiver.ToastMessage;
|
||||||
import app.fedilab.android.client.entities.api.Attachment;
|
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.Account;
|
||||||
import app.fedilab.android.client.entities.app.BaseAccount;
|
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.exception.DBException;
|
||||||
import app.fedilab.android.interfaces.OnDownloadInterface;
|
import app.fedilab.android.interfaces.OnDownloadInterface;
|
||||||
import app.fedilab.android.sqlite.Sqlite;
|
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.viewmodel.mastodon.OauthVM;
|
||||||
import app.fedilab.android.watermark.androidwm.WatermarkBuilder;
|
import app.fedilab.android.watermark.androidwm.WatermarkBuilder;
|
||||||
import app.fedilab.android.watermark.androidwm.bean.WatermarkText;
|
import app.fedilab.android.watermark.androidwm.bean.WatermarkText;
|
||||||
|
@ -1749,4 +1762,111 @@ public class Helper {
|
||||||
return null;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,9 +144,9 @@ public class SpannableHelper {
|
||||||
} else {
|
} else {
|
||||||
content = new SpannableStringBuilder(text);
|
content = new SpannableStringBuilder(text);
|
||||||
}
|
}
|
||||||
|
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
boolean animate = !sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_ANIMATED_EMOJI), false);
|
||||||
if (emojiList != null && emojiList.size() > 0) {
|
if (emojiList != null && emojiList.size() > 0) {
|
||||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
boolean animate = !sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_ANIMATED_EMOJI), false);
|
|
||||||
for (Emoji emoji : emojiList) {
|
for (Emoji emoji : emojiList) {
|
||||||
Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL)
|
Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL)
|
||||||
.matcher(content);
|
.matcher(content);
|
||||||
|
@ -173,7 +173,7 @@ public class SpannableHelper {
|
||||||
Glide.with(view)
|
Glide.with(view)
|
||||||
.asDrawable()
|
.asDrawable()
|
||||||
.load(url)
|
.load(url)
|
||||||
.into(customEmoji.getTarget(true));
|
.into(customEmoji.getTarget(animate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
package app.fedilab.android.ui.drawer;
|
||||||
|
/* 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 android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.github.stom79.mytransl.MyTransL;
|
||||||
|
import com.github.stom79.mytransl.client.HttpsConnectionException;
|
||||||
|
import com.github.stom79.mytransl.client.Results;
|
||||||
|
import com.github.stom79.mytransl.translate.Params;
|
||||||
|
import com.github.stom79.mytransl.translate.Translate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import app.fedilab.android.R;
|
||||||
|
import app.fedilab.android.client.entities.app.ReleaseNote;
|
||||||
|
import app.fedilab.android.databinding.DrawerReleaseNoteBinding;
|
||||||
|
import es.dmoral.toasty.Toasty;
|
||||||
|
|
||||||
|
|
||||||
|
public class ReleaseNoteAdapter extends RecyclerView.Adapter<ReleaseNoteAdapter.ReleaseNoteViewHolder> {
|
||||||
|
|
||||||
|
private final List<ReleaseNote.Note> notes;
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
public ReleaseNoteAdapter(List<ReleaseNote.Note> notes) {
|
||||||
|
this.notes = notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return notes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ReleaseNoteViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
context = parent.getContext();
|
||||||
|
DrawerReleaseNoteBinding itemBinding = DrawerReleaseNoteBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||||
|
return new ReleaseNoteViewHolder(itemBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ReleaseNoteViewHolder holder, int position) {
|
||||||
|
ReleaseNote.Note note = notes.get(position);
|
||||||
|
holder.binding.note.setText(note.note);
|
||||||
|
holder.binding.version.setText(String.format(Locale.getDefault(), "%s (%s)", note.version, note.code));
|
||||||
|
if (note.noteTranslated != null) {
|
||||||
|
holder.binding.noteTranslated.setText(note.noteTranslated);
|
||||||
|
holder.binding.containerTrans.setVisibility(View.VISIBLE);
|
||||||
|
holder.binding.translate.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
holder.binding.containerTrans.setVisibility(View.GONE);
|
||||||
|
holder.binding.translate.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
holder.binding.translate.setOnClickListener(v -> {
|
||||||
|
MyTransL.translatorEngine et = MyTransL.translatorEngine.LIBRETRANSLATE;
|
||||||
|
final MyTransL myTransL = MyTransL.getInstance(et);
|
||||||
|
myTransL.setObfuscation(true);
|
||||||
|
Params params = new Params();
|
||||||
|
params.setSplit_sentences(false);
|
||||||
|
params.setFormat(Params.fType.TEXT);
|
||||||
|
params.setSource_lang("auto");
|
||||||
|
myTransL.setLibretranslateDomain("translate.fedilab.app");
|
||||||
|
myTransL.translate(note.note, MyTransL.getLocale(), params, new Results() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Translate translate) {
|
||||||
|
if (translate.getTranslatedContent() != null) {
|
||||||
|
note.noteTranslated = translate.getTranslatedContent();
|
||||||
|
notifyItemChanged(holder.getBindingAdapterPosition());
|
||||||
|
} else {
|
||||||
|
Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFail(HttpsConnectionException httpsConnectionException) {
|
||||||
|
Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class ReleaseNoteViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
DrawerReleaseNoteBinding binding;
|
||||||
|
|
||||||
|
ReleaseNoteViewHolder(DrawerReleaseNoteBinding itemView) {
|
||||||
|
super(itemView.getRoot());
|
||||||
|
binding = itemView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
app/src/main/res/drawable/ic_baseline_notes_24.xml
Normal file
11
app/src/main/res/drawable/ic_baseline_notes_24.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:autoMirrored="true"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M3,18h12v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h18v-2L3,11v2z" />
|
||||||
|
</vector>
|
10
app/src/main/res/drawable/ic_baseline_translate_24.xml
Normal file
10
app/src/main/res/drawable/ic_baseline_translate_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z" />
|
||||||
|
</vector>
|
86
app/src/main/res/layout/drawer_release_note.xml
Normal file
86
app/src/main/res/layout/drawer_release_note.xml
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/version"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:lines="1"
|
||||||
|
android:padding="2dp"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/note"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/translate"
|
||||||
|
style="@style/Widget.App.Button.IconOnly.Outline"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:contentDescription="@string/translate"
|
||||||
|
app:icon="@drawable/ic_baseline_translate_24"
|
||||||
|
app:iconPadding="0dp" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/container_trans"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/translation_border_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@drawable/translation_border"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/translation_border_top" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Placeholder
|
||||||
|
android:id="@+id/translation_border_top"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/translation_label"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/translation_label"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/translation_label" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/translation_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:background="?backgroundColorLight"
|
||||||
|
android:paddingStart="2dp"
|
||||||
|
android:paddingEnd="2dp"
|
||||||
|
android:text="@string/translation"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/note_translated"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/translation_label"
|
||||||
|
app:layout_goneMarginBottom="8dp" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
111
app/src/main/res/layout/popup_release_notes.xml
Normal file
111
app/src/main/res/layout/popup_release_notes.xml
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
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>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/releasenotes"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:id="@+id/acccount_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="invisible"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/about_support"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/account_pp"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:contentDescription="@string/profile_picture" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/account_dn"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/account_un"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
android:id="@+id/account_follow"
|
||||||
|
style="@style/Widget.AppCompat.Button.Colored"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:contentDescription="@string/make_an_action"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/avatar_container"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/banner_container"
|
||||||
|
tools:src="@drawable/ic_baseline_person_add_24"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/about_support"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:text="@string/support_the_app_on_liberapay"
|
||||||
|
android:textColor="@color/cyanea_accent_dark_reference"
|
||||||
|
app:strokeColor="@color/cyanea_accent_dark_reference" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/about_support_paypal"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:text="PayPal"
|
||||||
|
android:textColor="@color/cyanea_accent_dark_reference"
|
||||||
|
app:strokeColor="@color/cyanea_accent_dark_reference"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
|
@ -89,7 +89,10 @@
|
||||||
android:id="@+id/nav_about"
|
android:id="@+id/nav_about"
|
||||||
android:icon="@drawable/ic_baseline_info_24"
|
android:icon="@drawable/ic_baseline_info_24"
|
||||||
android:title="@string/action_about" />
|
android:title="@string/action_about" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_release_notes"
|
||||||
|
android:icon="@drawable/ic_baseline_notes_24"
|
||||||
|
android:title="@string/release_notes" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_partnership"
|
android:id="@+id/nav_partnership"
|
||||||
android:icon="@drawable/ic_baseline_account_circle_24"
|
android:icon="@drawable/ic_baseline_account_circle_24"
|
||||||
|
|
|
@ -923,6 +923,7 @@
|
||||||
<string name="DEFAULT_REPLACE_WIKIPEDIA_HOST" translatable="false">wikiless.org</string>
|
<string name="DEFAULT_REPLACE_WIKIPEDIA_HOST" translatable="false">wikiless.org</string>
|
||||||
<string name="LAST_NOTIFICATION_ID" translatable="false">LAST_NOTIFICATION_ID</string>
|
<string name="LAST_NOTIFICATION_ID" translatable="false">LAST_NOTIFICATION_ID</string>
|
||||||
<string name="SET_MAX_INSTANCE_CHAR" translatable="false">SET_MAX_INSTANCE_CHAR</string>
|
<string name="SET_MAX_INSTANCE_CHAR" translatable="false">SET_MAX_INSTANCE_CHAR</string>
|
||||||
|
<string name="SET_POPUP_RELEASE_NOTES" translatable="false">SET_POPUP_RELEASE_NOTES</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="type_of_notifications">Type of notifications</string>
|
<string name="type_of_notifications">Type of notifications</string>
|
||||||
|
@ -989,6 +990,7 @@
|
||||||
<string name="my_app">My app</string>
|
<string name="my_app">My app</string>
|
||||||
<string name="my_account">My account</string>
|
<string name="my_account">My account</string>
|
||||||
<string name="set_your_max_char_count">Set your max char count</string>
|
<string name="set_your_max_char_count">Set your max char count</string>
|
||||||
|
<string name="release_notes">Release notes</string>
|
||||||
|
|
||||||
<string-array name="photo_editor_emoji" translatable="false">
|
<string-array name="photo_editor_emoji" translatable="false">
|
||||||
<!-- Smiles -->
|
<!-- Smiles -->
|
||||||
|
|
Loading…
Reference in a new issue