diff --git a/app/src/main/java/org/lsposed/manager/repo/RepoLoader.java b/app/src/main/java/org/lsposed/manager/repo/RepoLoader.java index ea99e226..5ed7a9c4 100644 --- a/app/src/main/java/org/lsposed/manager/repo/RepoLoader.java +++ b/app/src/main/java/org/lsposed/manager/repo/RepoLoader.java @@ -20,6 +20,7 @@ package org.lsposed.manager.repo; +import android.content.res.Resources; import android.util.Log; import androidx.annotation.NonNull; @@ -28,16 +29,20 @@ import androidx.annotation.Nullable; import com.google.gson.Gson; import org.lsposed.manager.App; +import org.lsposed.manager.R; import org.lsposed.manager.repo.model.OnlineModule; +import org.lsposed.manager.repo.model.Release; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -74,6 +79,8 @@ public class RepoLoader { private static final String originRepoUrl = "https://modules.lsposed.org/"; private static final String backupRepoUrl = "https://cdn.jsdelivr.net/gh/Xposed-Modules-Repo/modules@gh-pages/"; private static String repoUrl = originRepoUrl; + private final Resources resources = App.getInstance().getResources(); + private final String[] channels = resources.getStringArray(R.array.update_channel_values); public boolean isRepoLoaded() { return repoLoaded; @@ -103,10 +110,18 @@ public class RepoLoader { Map modules = new HashMap<>(); OnlineModule[] repoModules = gson.fromJson(bodyString, OnlineModule[].class); Arrays.stream(repoModules).forEach(onlineModule -> modules.put(onlineModule.getName(), onlineModule)); - + var channel = App.getPreferences().getString("update_channel", channels[0]); Map versions = new ConcurrentHashMap<>(); for (var module : repoModules) { - var release = module.getLatestRelease(); + String release = module.getLatestRelease(); + if (channel.equals(channels[1]) && !(module.getLatestBetaRelease() != null && module.getLatestBetaRelease().isEmpty())) { + release = module.getLatestBetaRelease(); + } else if (channel.equals(channels[2])) { + if (!(module.getLatestSnapshotRelease() != null && module.getLatestSnapshotRelease().isEmpty())) + release = module.getLatestSnapshotRelease(); + else if (!(module.getLatestBetaRelease() != null && module.getLatestBetaRelease().isEmpty())) + release = module.getLatestBetaRelease(); + } if (release == null || release.isEmpty()) continue; var splits = release.split("-", 2); if (splits.length < 2) continue; @@ -156,6 +171,41 @@ public class RepoLoader { return repoLoaded ? latestVersion.getOrDefault(packageName, null) : null; } + @Nullable + public List getReleases(String packageName) { + var channel = App.getPreferences().getString("update_channel", channels[0]); + List releases = new ArrayList<>(); + if (repoLoaded) { + var module = onlineModules.get(packageName); + if (module != null) { + releases = module.getReleases(); + if (!module.releasesLoaded) { + if (channel.equals(channels[1]) && !module.getBetaReleases().isEmpty()) { + releases = module.getBetaReleases(); + } else if (channel.equals(channels[2]) && !module.getSnapshotReleases().isEmpty()) + releases = module.getSnapshotReleases(); + } + } + } + return releases; + } + + @Nullable + public String getLatestReleaseTime(String packageName, String channel) { + String releaseTime = null; + if (repoLoaded) { + var module = onlineModules.get(packageName); + if (module != null) { + releaseTime = module.getLatestReleaseTime(); + if (channel.equals(channels[1]) && module.getLatestBetaReleaseTime() != null) { + releaseTime = module.getLatestBetaReleaseTime(); + } else if (channel.equals(channels[2]) && module.getLatestSnapshotReleaseTime() != null) + releaseTime = module.getLatestSnapshotReleaseTime(); + } + } + return releaseTime; + } + public void loadRemoteReleases(String packageName) { App.getOkHttpClient().newCall(new Request.Builder() .url(String.format(repoUrl + "module/%s.json", packageName)) diff --git a/app/src/main/java/org/lsposed/manager/repo/model/OnlineModule.java b/app/src/main/java/org/lsposed/manager/repo/model/OnlineModule.java index c861a923..e3fe3106 100644 --- a/app/src/main/java/org/lsposed/manager/repo/model/OnlineModule.java +++ b/app/src/main/java/org/lsposed/manager/repo/model/OnlineModule.java @@ -20,6 +20,8 @@ package org.lsposed.manager.repo.model; +import androidx.annotation.Nullable; + import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; @@ -49,9 +51,27 @@ public class OnlineModule { @SerializedName("latestReleaseTime") @Expose private String latestReleaseTime; + @SerializedName("latestBetaRelease") + @Expose + private String latestBetaRelease; + @SerializedName("latestBetaReleaseTime") + @Expose + private String latestBetaReleaseTime; + @SerializedName("latestSnapshotRelease") + @Expose + private String latestSnapshotRelease; + @SerializedName("latestSnapshotReleaseTime") + @Expose + private String latestSnapshotReleaseTime; @SerializedName("releases") @Expose private List releases = new ArrayList<>(); + @SerializedName("betaReleases") + @Expose + private List betaReleases = new ArrayList<>(); + @SerializedName("snapshotReleases") + @Expose + private List snapshotReleases = new ArrayList<>(); @SerializedName("readme") @Expose private String readme; @@ -224,4 +244,32 @@ public class OnlineModule { public void setLatestRelease(String latestRelease) { this.latestRelease = latestRelease; } + + @Nullable + public String getLatestBetaRelease() { + return latestBetaRelease; + } + + @Nullable + public String getLatestBetaReleaseTime() { + return latestBetaReleaseTime; + } + + @Nullable + public String getLatestSnapshotRelease() { + return latestSnapshotRelease; + } + + @Nullable + public String getLatestSnapshotReleaseTime() { + return latestSnapshotReleaseTime; + } + + public List getBetaReleases() { + return betaReleases; + } + + public List getSnapshotReleases() { + return snapshotReleases; + } } diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java index 5a9a8843..5ef6d651 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java @@ -20,6 +20,7 @@ package org.lsposed.manager.ui.fragment; import android.annotation.SuppressLint; +import android.content.res.Resources; import android.graphics.Typeface; import android.os.Build; import android.os.Bundle; @@ -260,6 +261,10 @@ public class RepoFragment extends BaseFragment implements RepoLoader.RepoListene private List fullList, showList; private final LabelComparator labelComparator = new LabelComparator(); private boolean isLoaded = false; + private final Resources resources = App.getInstance().getResources(); + private final String[] channels = resources.getStringArray(R.array.update_channel_values); + private String channel; + private final RepoLoader repoLoader = RepoLoader.getInstance(); RepoAdapter() { fullList = showList = Collections.emptyList(); @@ -286,7 +291,10 @@ public class RepoFragment extends BaseFragment implements RepoLoader.RepoListene OnlineModule module = showList.get(position); holder.appName.setText(module.getDescription()); holder.appPackageName.setText(module.getName()); - var instant = Instant.parse(module.getLatestReleaseTime()); + Instant instant; + channel = App.getPreferences().getString("update_channel", channels[0]); + + instant = Instant.parse(repoLoader.getLatestReleaseTime(module.getName(), channel)); var formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT) .withLocale(App.getLocale()).withZone(ZoneId.systemDefault()); holder.publishedTime.setText(String.format(getString(R.string.module_repo_updated_time), formatter.format(instant))); @@ -344,9 +352,11 @@ public class RepoFragment extends BaseFragment implements RepoLoader.RepoListene public void setData(Collection modules) { if (modules == null) return; setLoaded(null, false); + channel = App.getPreferences().getString("update_channel", channels[0]); int sort = App.getPreferences().getInt("repo_sort", 0); boolean upgradableFirst = App.getPreferences().getBoolean("upgradable_first", true); ConcurrentHashMap upgradable = new ConcurrentHashMap<>(); + fullList = modules.parallelStream().filter((onlineModule -> !onlineModule.isHide() && !onlineModule.getReleases().isEmpty())) .sorted((a, b) -> { if (upgradableFirst) { @@ -358,7 +368,7 @@ public class RepoFragment extends BaseFragment implements RepoLoader.RepoListene if (sort == 0) { return labelComparator.compare(a.getDescription(), b.getDescription()); } else { - return Instant.parse(b.getLatestReleaseTime()).compareTo(Instant.parse(a.getLatestReleaseTime())); + return Instant.parse(repoLoader.getLatestReleaseTime(b.getName(), channel)).compareTo(Instant.parse(repoLoader.getLatestReleaseTime(a.getName(), channel))); } }).collect(Collectors.toList()); String queryStr = searchView != null ? searchView.getQuery().toString() : ""; diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoItemFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoItemFragment.java index d06c6944..327d7223 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoItemFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoItemFragment.java @@ -370,7 +370,8 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.RepoLis public void loadItems() { var channels = resources.getStringArray(R.array.update_channel_values); var channel = App.getPreferences().getString("update_channel", channels[0]); - var releases = module.getReleases(); + var releases = RepoLoader.getInstance().getReleases(module.getName()); + if (releases == null) releases = module.getReleases(); List tmpList; if (channel.equals(channels[0])) { tmpList = releases.parallelStream().filter(t -> { @@ -383,7 +384,9 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.RepoLis var name = t.getName().toLowerCase(LocaleDelegate.getDefaultLocale()); return !name.startsWith("snapshot") && !name.startsWith("nightly"); }).collect(Collectors.toList()); - } else tmpList = releases; + } else { + tmpList = releases; + } runOnUiThread(() -> { items = tmpList; notifyDataSetChanged();