[app] Check modules' update (#778)
This commit is contained in:
parent
da3e026760
commit
129249b797
|
|
@ -184,6 +184,8 @@ public class RepoLoader {
|
|||
default void moduleReleasesLoaded(OnlineModule module) {
|
||||
}
|
||||
|
||||
void onThrowable(Throwable t);
|
||||
default void onThrowable(Throwable t) {
|
||||
Log.e(App.TAG, "load repo failed", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ public class OnlineModule implements Serializable, Parcelable {
|
|||
@SerializedName("collaborators")
|
||||
@Expose
|
||||
private List<Collaborator> collaborators = new ArrayList<>();
|
||||
@SerializedName("latestRelease")
|
||||
@Expose
|
||||
private String latestRelease;
|
||||
@SerializedName("releases")
|
||||
@Expose
|
||||
private List<Release> releases = new ArrayList<>();
|
||||
|
|
@ -111,6 +114,7 @@ public class OnlineModule implements Serializable, Parcelable {
|
|||
this.createdAt = ((String) in.readValue((String.class.getClassLoader())));
|
||||
this.stargazerCount = ((Integer) in.readValue((Integer.class.getClassLoader())));
|
||||
this.readmeHTML = ((String) in.readValue((String.class.getClassLoader())));
|
||||
this.latestRelease = ((String) in.readValue((String.class.getClassLoader())));
|
||||
}
|
||||
|
||||
public OnlineModule() {
|
||||
|
|
@ -262,10 +266,18 @@ public class OnlineModule implements Serializable, Parcelable {
|
|||
dest.writeValue(createdAt);
|
||||
dest.writeValue(stargazerCount);
|
||||
dest.writeValue(readmeHTML);
|
||||
dest.writeValue(latestRelease);
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getLatestRelease() {
|
||||
return latestRelease;
|
||||
}
|
||||
|
||||
public void setLatestRelease(String latestRelease) {
|
||||
this.latestRelease = latestRelease;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
package org.lsposed.manager.ui.fragment;
|
||||
|
||||
import static android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS;
|
||||
|
||||
import static androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
|
@ -40,6 +39,7 @@ import android.text.TextUtils;
|
|||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.text.style.TypefaceSpan;
|
||||
import android.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
|
@ -87,6 +87,8 @@ import org.lsposed.manager.util.ModuleUtil;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -96,8 +98,7 @@ import rikka.insets.WindowInsetsHelperKt;
|
|||
import rikka.recyclerview.RecyclerViewKt;
|
||||
import rikka.widget.borderview.BorderRecyclerView;
|
||||
|
||||
public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleListener {
|
||||
|
||||
public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleListener, RepoLoader.Listener {
|
||||
private static final Handler workHandler;
|
||||
private static final PackageManager pm = App.getInstance().getPackageManager();
|
||||
private static final ModuleUtil moduleUtil = ModuleUtil.getInstance();
|
||||
|
|
@ -108,6 +109,8 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
|
|||
private final ArrayList<ModuleAdapter> adapters = new ArrayList<>();
|
||||
private final ArrayList<String> tabTitles = new ArrayList<>();
|
||||
|
||||
private final Map<String, Pair<Integer, String>> latestVersion = new ConcurrentHashMap<>();
|
||||
|
||||
private ModuleUtil.InstalledModule selectedModule;
|
||||
|
||||
static {
|
||||
|
|
@ -133,6 +136,8 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
|
|||
return false;
|
||||
}
|
||||
};
|
||||
RepoLoader.getInstance().addListener(this);
|
||||
repoLoaded();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
@ -339,6 +344,28 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
|
|||
binding = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void repoLoaded() {
|
||||
latestVersion.clear();
|
||||
for (var module : RepoLoader.getInstance().getOnlineModules()) {
|
||||
var release = module.getLatestRelease();
|
||||
if (release == null || release.isEmpty()) continue;
|
||||
var splits = release.split("-", 2);
|
||||
if (splits.length < 2) continue;
|
||||
int verCode;
|
||||
String verName;
|
||||
try {
|
||||
verCode = Integer.parseInt(splits[0]);
|
||||
verName = splits[1];
|
||||
} catch (NumberFormatException ignored) {
|
||||
continue;
|
||||
}
|
||||
String pkgName = module.getName();
|
||||
latestVersion.put(pkgName, new Pair<>(verCode, verName));
|
||||
}
|
||||
adapters.forEach(ModuleAdapter::notifyDataSetChanged);
|
||||
}
|
||||
|
||||
public static class ModuleListFragment extends Fragment {
|
||||
@Nullable
|
||||
@Override
|
||||
|
|
@ -487,6 +514,24 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
|
|||
}
|
||||
sb.setSpan(foregroundColorSpan, sb.length() - warningText.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
}
|
||||
|
||||
if (latestVersion.containsKey(item.packageName)) {
|
||||
var ver = latestVersion.get(item.packageName);
|
||||
if (ver != null && ver.first > item.versionCode) {
|
||||
sb.append("\n");
|
||||
String recommended = getString(R.string.update_available, ver.second);
|
||||
sb.append(recommended);
|
||||
final ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(ResourcesKt.resolveColor(requireActivity().getTheme(), R.attr.colorAccent));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
final TypefaceSpan typefaceSpan = new TypefaceSpan(Typeface.create("sans-serif-medium", Typeface.NORMAL));
|
||||
sb.setSpan(typefaceSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
} else {
|
||||
final StyleSpan styleSpan = new StyleSpan(Typeface.BOLD);
|
||||
sb.setSpan(styleSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
}
|
||||
sb.setSpan(foregroundColorSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
}
|
||||
}
|
||||
holder.appDescription.setText(sb);
|
||||
|
||||
if (!isPick) {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@
|
|||
<string name="menu_restore">Wiederherstellen</string>
|
||||
<string name="xposed_module_updated_notification_content">%s wurde aktualisiert</string>
|
||||
<string name="module_repo">Module Repo</string>
|
||||
<string name="module_repo_summary">Modul-Repository (Alpha)</string>
|
||||
<string name="module_repo_summary">Modul-Repository (Beta)</string>
|
||||
<string name="module_readme">Liesmich</string>
|
||||
<string name="module_releases">Veröffentlichungen</string>
|
||||
<string name="module_information">Info</string>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">Configuración</string>
|
||||
<string name="About">Acerca de</string>
|
||||
<string name="module_repo">Repositorio</string>
|
||||
<string name="module_repo_summary">Repositorio de módulos (alpha)</string>
|
||||
<string name="module_repo_summary">Repositorio de módulos (Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[Ve el código fuente en %1$s<br/>Únete a nuestro %2$s canal]]></string>
|
||||
<string name="about_translators">Traductores: %s</string>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">Réglages</string>
|
||||
<string name="About">A propos</string>
|
||||
<string name="module_repo">Dépôt</string>
|
||||
<string name="module_repo_summary">Dépôts de modules (Alpha)</string>
|
||||
<string name="module_repo_summary">Dépôts de modules (Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[Voir le code source sur %1$s<br/>Rejoindre notre canal %2$s]]></string>
|
||||
<string name="about_translators">Traducteur: %s</string>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">Impostazioni</string>
|
||||
<string name="About">Informazioni</string>
|
||||
<string name="module_repo">Repository</string>
|
||||
<string name="module_repo_summary">Repository moduli (Alpha)</string>
|
||||
<string name="module_repo_summary">Repository moduli (Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[Visualizza il codice sorgente su %1$s<br/>Unisciti al nostro canale %2$s]]></string>
|
||||
<string name="about_translators">Traduttori: %s</string>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">설정</string>
|
||||
<string name="About">About</string>
|
||||
<string name="module_repo">저장소</string>
|
||||
<string name="module_repo_summary">모듈 저장소 (Alpha)</string>
|
||||
<string name="module_repo_summary">모듈 저장소 (Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[%1$s에서 소스 코드 보기<br/>%2$s 채널에 가입하십시오.]]></string>
|
||||
<string name="about_translators">번역가: %s</string>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">Instellingen</string>
|
||||
<string name="About">Over</string>
|
||||
<string name="module_repo">Opslagplaats</string>
|
||||
<string name="module_repo_summary">Module opslagplaats (Alpha)</string>
|
||||
<string name="module_repo_summary">Module opslagplaats (Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[Bekijk de broncode op %1$s<br/>Sluit je aan bij onze %2$s kanaal]]></string>
|
||||
<string name="about_translators">Vertaler: %1$s</string>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">Configurações</string>
|
||||
<string name="About">Sobre</string>
|
||||
<string name="module_repo">Repositório</string>
|
||||
<string name="module_repo_summary">Repositório de Módulos (Alpha)</string>
|
||||
<string name="module_repo_summary">Repositório de Módulos (Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[Veja o código fonte no %1$s<br/>Entre em nosso canal no %2$s]]></string>
|
||||
<string name="about_translators">Tradutor: %s</string>
|
||||
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@
|
|||
<string name="menu_restore">Восстановить</string>
|
||||
<string name="xposed_module_updated_notification_content">%s обновлён</string>
|
||||
<string name="module_repo">Репозиторий</string>
|
||||
<string name="module_repo_summary">Репозиторий модулей (Альфа)</string>
|
||||
<string name="module_repo_summary">Репозиторий модулей (Бета)</string>
|
||||
<string name="module_readme">Readme</string>
|
||||
<string name="module_releases">Релизаты</string>
|
||||
<string name="module_information">Информация</string>
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@
|
|||
<string name="warning_xposed_min_version">Цей модуль вимагає новішої версії LSP (%d), тому його неможливо активувати</string>
|
||||
<string name="xposed_module_updated_notification_title">Модуль LSPosed оновлено</string>
|
||||
<string name="module_repo">Репозиторій</string>
|
||||
<string name="module_repo_summary">Репозиторій модулів</string>
|
||||
<string name="module_repo_summary">Репозиторій модулів (Бета)</string>
|
||||
<string name="module_readme">Readme</string>
|
||||
<string name="module_releases">Релізи</string>
|
||||
<string name="module_information">Інформація</string>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">设置</string>
|
||||
<string name="About">关于</string>
|
||||
<string name="module_repo">仓库</string>
|
||||
<string name="module_repo_summary">模块仓库(Alpha)</string>
|
||||
<string name="module_repo_summary">模块仓库(Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[在 %1$s 查看源码<br/>加入我们的 %2$s 频道]]></string>
|
||||
<string name="about_translators">译者:%s</string>
|
||||
|
||||
|
|
@ -122,6 +122,7 @@
|
|||
<string name="no_scope_selected_has_recommended">未选择任何应用。选择推荐的应用?</string>
|
||||
<string name="use_recommended_message">选择推荐的应用?</string>
|
||||
<string name="requested_by_module">推荐的应用</string>
|
||||
<string name="update_available">可用更新:%1$s</string>
|
||||
<string name="module_disabled_no_selection">由于未选择任何应用,模块 %s 已被禁用。</string>
|
||||
<string name="android_framework">系统框架</string>
|
||||
<string name="menu_backup_and_restore">备份…</string>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">設置</string>
|
||||
<string name="About">關於</string>
|
||||
<string name="module_repo">倉庫</string>
|
||||
<string name="module_repo_summary">模組倉庫(Alpha)</string>
|
||||
<string name="module_repo_summary">模組倉庫(Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[在 %1$s 查看源碼<br/>加入我們的 %2$s 頻道]]></string>
|
||||
<string name="about_translators">Translators: %s</string>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">設定</string>
|
||||
<string name="About">關於</string>
|
||||
<string name="module_repo">倉庫</string>
|
||||
<string name="module_repo_summary">模組倉庫(Alpha)</string>
|
||||
<string name="module_repo_summary">模組倉庫(Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[在 %1$s 檢視原始碼<br/>加入我們的 %2$s 頻道]]></string>
|
||||
<string name="about_translators">翻譯者:%s</string>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<string name="Settings">Settings</string>
|
||||
<string name="About">About</string>
|
||||
<string name="module_repo">Repository</string>
|
||||
<string name="module_repo_summary">Module repository (Alpha)</string>
|
||||
<string name="module_repo_summary">Module repository (Beta)</string>
|
||||
<string name="about_view_source_code"><![CDATA[View source code at %1$s<br/>Join our %2$s channel]]></string>
|
||||
<string name="about_translators">Translators: %s</string>
|
||||
|
||||
|
|
@ -122,6 +122,7 @@
|
|||
<string name="no_scope_selected_has_recommended">You did not select any app. Select recommended apps?</string>
|
||||
<string name="use_recommended_message">Select recommended apps?</string>
|
||||
<string name="requested_by_module">Recommended</string>
|
||||
<string name="update_available">Update available: %1$s</string>
|
||||
<string name="module_disabled_no_selection">Module %s has been disabled since no app selected.</string>
|
||||
<string name="android_framework">System Framework</string>
|
||||
<string name="menu_backup_and_restore">Backup…</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue