refactor: switch a couple data calls to use Graphql if configured
This commit is contained in:
parent
fb68c7f002
commit
122b064f0b
13 changed files with 450 additions and 67 deletions
|
@ -34,3 +34,4 @@ This changelog only contains the changes that are unreleased. For changes for in
|
|||
### Misc
|
||||
- Implement view model for InstancesTab [#675]
|
||||
- Implement view model for ServersTab [#674]
|
||||
- Switch a couple data calls to use Graphql if configured
|
||||
|
|
11
build.gradle
11
build.gradle
|
@ -27,6 +27,7 @@ plugins {
|
|||
id 'de.undercouch.download' version '5.1.0'
|
||||
id 'com.github.johnrengelman.shadow' version '7.1.2'
|
||||
id 'com.github.ben-manes.versions' version '0.42.0'
|
||||
id 'com.apollographql.apollo' version '2.5.14'
|
||||
}
|
||||
|
||||
apply plugin: 'org.mini2Dx.gettext'
|
||||
|
@ -81,6 +82,8 @@ dependencies {
|
|||
implementation 'org.apache.commons:commons-compress:1.21'
|
||||
implementation 'org.commonmark:commonmark:0.19.0'
|
||||
implementation 'com.github.hypfvieh:dbus-java:3.3.1'
|
||||
implementation 'com.apollographql.apollo:apollo-runtime:2.5.14'
|
||||
implementation 'com.apollographql.apollo:apollo-http-cache:2.5.14'
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.mockito:mockito-core:4.6.1'
|
||||
|
@ -122,7 +125,14 @@ jar {
|
|||
'Multi-Release': 'true'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
apollo {
|
||||
customTypeMapping = [
|
||||
"ID" : "java.lang.String",
|
||||
"DateTime" : "java.util.Date"
|
||||
]
|
||||
packageName = "com.atlauncher.graphql"
|
||||
}
|
||||
|
||||
gettext {
|
||||
|
@ -149,6 +159,7 @@ license {
|
|||
include '**/*.java'
|
||||
exclude 'io/github/**/*.java'
|
||||
exclude 'net/minecraft/**/*.java'
|
||||
exclude 'com/atlauncher/graphql/**/*.java'
|
||||
exclude 'com/atlauncher/gui/layouts/WrapLayout.java'
|
||||
newLine = false
|
||||
properties {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
query GetLoaderVersionsForMinecraftVersion($minecraftVersion: String!) {
|
||||
loaderVersions(minecraftVersion: $minecraftVersion) {
|
||||
fabric {
|
||||
version
|
||||
}
|
||||
forge {
|
||||
version
|
||||
rawVersion
|
||||
recommended
|
||||
installerSha1Hash
|
||||
installerSize
|
||||
universalSha1Hash
|
||||
universalSize
|
||||
clientSha1Hash
|
||||
clientSize
|
||||
serverSha1Hash
|
||||
serverSize
|
||||
}
|
||||
quilt {
|
||||
version
|
||||
}
|
||||
}
|
||||
}
|
7
src/main/graphql/com/atlauncher/GetNews.graphql
Normal file
7
src/main/graphql/com/atlauncher/GetNews.graphql
Normal file
|
@ -0,0 +1,7 @@
|
|||
query GetNews($first: Int!) {
|
||||
generalNews(first: $first) {
|
||||
title
|
||||
content
|
||||
createdAt
|
||||
}
|
||||
}
|
1
src/main/graphql/com/atlauncher/schema.json
Normal file
1
src/main/graphql/com/atlauncher/schema.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -36,6 +36,7 @@ public final class FileSystem {
|
|||
public static final Path LOGS = BASE_DIR.resolve("logs");
|
||||
public static final Path BACKUPS = BASE_DIR.resolve("backups");
|
||||
public static final Path CACHE = BASE_DIR.resolve("cache");
|
||||
public static final Path APOLLO_CACHE = CACHE.resolve("apolloCache");
|
||||
public static final Path REMOTE_IMAGE_CACHE = CACHE.resolve("remote_image");
|
||||
public static final Path LOADERS = BASE_DIR.resolve("loaders");
|
||||
public static final Path RUNTIMES = BASE_DIR.resolve("runtimes");
|
||||
|
|
|
@ -32,6 +32,7 @@ import javax.net.ssl.SSLSocketFactory;
|
|||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import com.apollographql.apollo.ApolloClientAwarenessInterceptor;
|
||||
import com.atlauncher.constants.Constants;
|
||||
import com.atlauncher.interfaces.NetworkProgressable;
|
||||
import com.atlauncher.listener.ProgressListener;
|
||||
|
@ -61,6 +62,10 @@ public final class Network {
|
|||
.readTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS)
|
||||
.writeTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS).build();
|
||||
|
||||
public static OkHttpClient GRAPHQL_CLIENT = CLIENT.newBuilder()
|
||||
.addInterceptor(new ApolloClientAwarenessInterceptor("Launcher", Constants.VERSION.toStringForLogging()))
|
||||
.build();
|
||||
|
||||
public static OkHttpClient CACHED_CLIENT = CLIENT.newBuilder().cache(CACHE).build();
|
||||
|
||||
public static final String ANALYTICS_USER_AGENT = String.format(
|
||||
|
@ -81,6 +86,10 @@ public final class Network {
|
|||
.readTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS)
|
||||
.writeTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS).build();
|
||||
|
||||
GRAPHQL_CLIENT = GRAPHQL_CLIENT.newBuilder().connectTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS)
|
||||
.readTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS)
|
||||
.writeTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS).build();
|
||||
|
||||
CACHED_CLIENT = CACHED_CLIENT.newBuilder().connectTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS)
|
||||
.readTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS)
|
||||
.writeTimeout(App.settings.connectionTimeout, TimeUnit.SECONDS).build();
|
||||
|
@ -91,6 +100,7 @@ public final class Network {
|
|||
: Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1);
|
||||
|
||||
CLIENT = CLIENT.newBuilder().protocols(protocols).build();
|
||||
GRAPHQL_CLIENT = GRAPHQL_CLIENT.newBuilder().protocols(protocols).build();
|
||||
CACHED_CLIENT = CACHED_CLIENT.newBuilder().protocols(protocols).build();
|
||||
}
|
||||
|
||||
|
@ -115,6 +125,9 @@ public final class Network {
|
|||
CLIENT = CLIENT.newBuilder().sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager())
|
||||
.build();
|
||||
|
||||
GRAPHQL_CLIENT = GRAPHQL_CLIENT.newBuilder()
|
||||
.sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager()).build();
|
||||
|
||||
CACHED_CLIENT = CACHED_CLIENT.newBuilder()
|
||||
.sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager()).build();
|
||||
}
|
||||
|
@ -152,6 +165,15 @@ public final class Network {
|
|||
}
|
||||
}).build();
|
||||
|
||||
GRAPHQL_CLIENT = GRAPHQL_CLIENT.newBuilder()
|
||||
.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
|
||||
.hostnameVerifier(new HostnameVerifier() {
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
}).build();
|
||||
|
||||
CACHED_CLIENT = CACHED_CLIENT.newBuilder()
|
||||
.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
|
||||
.hostnameVerifier(new HostnameVerifier() {
|
||||
|
|
|
@ -59,6 +59,7 @@ public class Constants {
|
|||
public static String BASE_LAUNCHER_PROTOCOL = "https://";
|
||||
public static String BASE_LAUNCHER_DOMAIN = "atlauncher.com";
|
||||
public static String API_BASE_URL = BASE_LAUNCHER_PROTOCOL + "api." + BASE_LAUNCHER_DOMAIN + "/v1/launcher/";
|
||||
public static String GRAPHQL_ENDPOINT = BASE_LAUNCHER_PROTOCOL + "api." + BASE_LAUNCHER_DOMAIN + "/v2/graphql";
|
||||
public static String API_HOST = "api." + BASE_LAUNCHER_DOMAIN;
|
||||
public static String PASTE_CHECK_URL = BASE_LAUNCHER_PROTOCOL + "paste." + BASE_LAUNCHER_DOMAIN;
|
||||
public static String PASTE_HOST = "paste." + BASE_LAUNCHER_DOMAIN;
|
||||
|
|
|
@ -28,6 +28,8 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
|
@ -50,11 +52,17 @@ import javax.swing.event.ListSelectionListener;
|
|||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
import org.mini2Dx.gettext.GetText;
|
||||
|
||||
import com.apollographql.apollo.ApolloCall;
|
||||
import com.apollographql.apollo.api.Response;
|
||||
import com.apollographql.apollo.api.cache.http.HttpCachePolicy;
|
||||
import com.apollographql.apollo.api.cache.http.HttpCachePolicy.FetchStrategy;
|
||||
import com.apollographql.apollo.exception.ApolloException;
|
||||
import com.atlauncher.App;
|
||||
import com.atlauncher.builders.HTMLBuilder;
|
||||
import com.atlauncher.constants.UIConstants;
|
||||
|
@ -68,12 +76,15 @@ import com.atlauncher.data.minecraft.loaders.fabric.FabricLoader;
|
|||
import com.atlauncher.data.minecraft.loaders.forge.ForgeLoader;
|
||||
import com.atlauncher.data.minecraft.loaders.quilt.QuiltLoader;
|
||||
import com.atlauncher.exceptions.InvalidMinecraftVersion;
|
||||
import com.atlauncher.graphql.GetLoaderVersionsForMinecraftVersionQuery;
|
||||
import com.atlauncher.managers.ConfigManager;
|
||||
import com.atlauncher.managers.DialogManager;
|
||||
import com.atlauncher.managers.InstanceManager;
|
||||
import com.atlauncher.managers.LogManager;
|
||||
import com.atlauncher.managers.MinecraftManager;
|
||||
import com.atlauncher.network.GraphqlClient;
|
||||
import com.atlauncher.utils.ComboItem;
|
||||
import com.atlauncher.utils.Pair;
|
||||
import com.atlauncher.utils.Utils;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
|
@ -587,80 +598,236 @@ public final class VanillaPacksTab extends JPanel implements Tab {
|
|||
boolean enableCreateServers = selectedLoader != LoaderType.FORGE
|
||||
|| !Utils.matchVersion(selectedMinecraftVersion, "1.5", true, true);
|
||||
|
||||
Runnable r = () -> {
|
||||
List<LoaderVersion> loaderVersions = new ArrayList<>();
|
||||
if (ConfigManager.getConfigItem("useGraphql.vanillaLoaderVersions", false) == true) {
|
||||
GraphqlClient.apolloClient.query(new GetLoaderVersionsForMinecraftVersionQuery(selectedMinecraftVersion))
|
||||
.toBuilder()
|
||||
.httpCachePolicy(new HttpCachePolicy.Policy(FetchStrategy.CACHE_FIRST, 5, TimeUnit.MINUTES, false))
|
||||
.build()
|
||||
.enqueue(new ApolloCall.Callback<GetLoaderVersionsForMinecraftVersionQuery.Data>() {
|
||||
@Override
|
||||
public void onResponse(
|
||||
@NotNull Response<GetLoaderVersionsForMinecraftVersionQuery.Data> response) {
|
||||
List<LoaderVersion> loaderVersions = new ArrayList<>();
|
||||
|
||||
if (selectedLoader == LoaderType.FABRIC) {
|
||||
loaderVersions.addAll(FabricLoader.getChoosableVersions(selectedMinecraftVersion));
|
||||
} else if (selectedLoader == LoaderType.FORGE) {
|
||||
loaderVersions.addAll(ForgeLoader.getChoosableVersions(selectedMinecraftVersion));
|
||||
} else if (selectedLoader == LoaderType.QUILT) {
|
||||
loaderVersions.addAll(QuiltLoader.getChoosableVersions(selectedMinecraftVersion));
|
||||
}
|
||||
if (selectedLoader == LoaderType.FABRIC) {
|
||||
List<String> disabledVersions = ConfigManager.getConfigItem(
|
||||
"loaders.fabric.disabledVersions",
|
||||
new ArrayList<String>());
|
||||
|
||||
loaderVersions.addAll(response.getData().loaderVersions().fabric().stream()
|
||||
.filter(fv -> !disabledVersions.contains(fv.version()))
|
||||
.map(version -> new LoaderVersion(version.version(), false, "Fabric"))
|
||||
.collect(Collectors.toList()));
|
||||
} else if (selectedLoader == LoaderType.FORGE) {
|
||||
List<String> disabledVersions = ConfigManager.getConfigItem(
|
||||
"loaders.forge.disabledVersions",
|
||||
new ArrayList<String>());
|
||||
|
||||
loaderVersions.addAll(response.getData().loaderVersions().forge().stream()
|
||||
.filter(fv -> !disabledVersions.contains(fv.version()))
|
||||
.map(version -> {
|
||||
LoaderVersion lv = new LoaderVersion(version.version(),
|
||||
version.rawVersion(),
|
||||
version.recommended(),
|
||||
"Forge");
|
||||
|
||||
if (version.installerSha1Hash() != null
|
||||
&& version.installerSize() != null) {
|
||||
lv.downloadables.put("installer",
|
||||
new Pair<String, Long>(version.installerSha1Hash(),
|
||||
version.installerSize().longValue()));
|
||||
}
|
||||
|
||||
if (version.universalSha1Hash() != null
|
||||
&& version.universalSize() != null) {
|
||||
lv.downloadables.put("universal",
|
||||
new Pair<String, Long>(version.universalSha1Hash(),
|
||||
version.universalSize().longValue()));
|
||||
}
|
||||
|
||||
if (version.clientSha1Hash() != null && version.clientSize() != null) {
|
||||
lv.downloadables.put("client",
|
||||
new Pair<String, Long>(version.clientSha1Hash(),
|
||||
version.clientSize().longValue()));
|
||||
}
|
||||
|
||||
if (version.serverSha1Hash() != null && version.serverSize() != null) {
|
||||
lv.downloadables.put("server",
|
||||
new Pair<String, Long>(version.serverSha1Hash(),
|
||||
version.serverSize().longValue()));
|
||||
}
|
||||
|
||||
return lv;
|
||||
})
|
||||
.collect(Collectors.toList()));
|
||||
} else if (selectedLoader == LoaderType.QUILT) {
|
||||
List<String> disabledVersions = ConfigManager.getConfigItem(
|
||||
"loaders.quilt.disabledVersions",
|
||||
new ArrayList<String>());
|
||||
|
||||
loaderVersions.addAll(response.getData().loaderVersions().quilt().stream()
|
||||
.filter(fv -> !disabledVersions.contains(fv.version()))
|
||||
.map(version -> new LoaderVersion(version.version(), false, "Quilt"))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
if (loaderVersions.size() == 0) {
|
||||
loaderVersionsDropDown.removeAllItems();
|
||||
loaderVersionsDropDown
|
||||
.addItem(new ComboItem<LoaderVersion>(null, GetText.tr("No Versions Found")));
|
||||
loaderTypeNoneRadioButton.setEnabled(true);
|
||||
loaderTypeFabricRadioButton.setEnabled(true);
|
||||
loaderTypeForgeRadioButton.setEnabled(true);
|
||||
loaderTypeQuiltRadioButton.setEnabled(true);
|
||||
createServerButton.setEnabled(enableCreateServers);
|
||||
createInstanceButton.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int loaderVersionLength = 0;
|
||||
|
||||
// ensures that font width is taken into account
|
||||
for (LoaderVersion version : loaderVersions) {
|
||||
loaderVersionLength = Math.max(loaderVersionLength,
|
||||
getFontMetrics(App.THEME.getNormalFont()).stringWidth(version.toString()) + 25);
|
||||
}
|
||||
|
||||
loaderVersionsDropDown.removeAllItems();
|
||||
|
||||
loaderVersions.forEach(version -> loaderVersionsDropDown
|
||||
.addItem(new ComboItem<LoaderVersion>(version, version.toString())));
|
||||
|
||||
if (selectedLoader == LoaderType.FORGE) {
|
||||
Optional<LoaderVersion> recommendedVersion = loaderVersions.stream()
|
||||
.filter(lv -> lv.recommended)
|
||||
.findFirst();
|
||||
|
||||
if (recommendedVersion.isPresent()) {
|
||||
loaderVersionsDropDown
|
||||
.setSelectedIndex(loaderVersions.indexOf(recommendedVersion.get()));
|
||||
}
|
||||
}
|
||||
|
||||
// ensures that the dropdown is at least 200 px wide
|
||||
loaderVersionLength = Math.max(200, loaderVersionLength);
|
||||
|
||||
// ensures that there is a maximum width of 400 px to prevent overflow
|
||||
loaderVersionLength = Math.min(400, loaderVersionLength);
|
||||
|
||||
loaderVersionsDropDown.setPreferredSize(new Dimension(loaderVersionLength, 23));
|
||||
|
||||
loaderTypeNoneRadioButton.setEnabled(true);
|
||||
loaderTypeFabricRadioButton.setEnabled(true);
|
||||
loaderTypeForgeRadioButton.setEnabled(true);
|
||||
loaderTypeQuiltRadioButton.setEnabled(true);
|
||||
loaderVersionsDropDown.setEnabled(true);
|
||||
createServerButton.setEnabled(enableCreateServers);
|
||||
createInstanceButton.setEnabled(true);
|
||||
|
||||
// update the name and description fields if they're not dirty
|
||||
String defaultNameFieldValue = String.format("Minecraft %s with %s",
|
||||
selectedMinecraftVersion,
|
||||
selectedLoader.toString());
|
||||
if (!nameFieldDirty) {
|
||||
nameField.setText(defaultNameFieldValue);
|
||||
}
|
||||
|
||||
if (!descriptionFieldDirty) {
|
||||
descriptionField.setText(defaultNameFieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull ApolloException e) {
|
||||
LogManager.logStackTrace("Error fetching loading versions", e);
|
||||
loaderVersionsDropDown.removeAllItems();
|
||||
loaderVersionsDropDown
|
||||
.addItem(new ComboItem<LoaderVersion>(null, GetText.tr("Error Getting Versions")));
|
||||
loaderTypeNoneRadioButton.setEnabled(true);
|
||||
loaderTypeFabricRadioButton.setEnabled(true);
|
||||
loaderTypeForgeRadioButton.setEnabled(true);
|
||||
loaderTypeQuiltRadioButton.setEnabled(true);
|
||||
createServerButton.setEnabled(enableCreateServers);
|
||||
createInstanceButton.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Runnable r = () -> {
|
||||
List<LoaderVersion> loaderVersions = new ArrayList<>();
|
||||
|
||||
if (selectedLoader == LoaderType.FABRIC) {
|
||||
loaderVersions.addAll(FabricLoader.getChoosableVersions(selectedMinecraftVersion));
|
||||
} else if (selectedLoader == LoaderType.FORGE) {
|
||||
loaderVersions.addAll(ForgeLoader.getChoosableVersions(selectedMinecraftVersion));
|
||||
} else if (selectedLoader == LoaderType.QUILT) {
|
||||
loaderVersions.addAll(QuiltLoader.getChoosableVersions(selectedMinecraftVersion));
|
||||
}
|
||||
|
||||
if (loaderVersions.size() == 0) {
|
||||
loaderVersionsDropDown.removeAllItems();
|
||||
loaderVersionsDropDown.addItem(new ComboItem<LoaderVersion>(null, GetText.tr("No Versions Found")));
|
||||
loaderTypeNoneRadioButton.setEnabled(true);
|
||||
loaderTypeFabricRadioButton.setEnabled(true);
|
||||
loaderTypeForgeRadioButton.setEnabled(true);
|
||||
loaderTypeQuiltRadioButton.setEnabled(true);
|
||||
createServerButton.setEnabled(enableCreateServers);
|
||||
createInstanceButton.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int loaderVersionLength = 0;
|
||||
|
||||
// ensures that font width is taken into account
|
||||
for (LoaderVersion version : loaderVersions) {
|
||||
loaderVersionLength = Math.max(loaderVersionLength,
|
||||
getFontMetrics(App.THEME.getNormalFont()).stringWidth(version.toString()) + 25);
|
||||
}
|
||||
|
||||
if (loaderVersions.size() == 0) {
|
||||
loaderVersionsDropDown.removeAllItems();
|
||||
loaderVersionsDropDown.addItem(new ComboItem<LoaderVersion>(null, GetText.tr("No Versions Found")));
|
||||
|
||||
loaderVersions.forEach(version -> loaderVersionsDropDown
|
||||
.addItem(new ComboItem<LoaderVersion>(version, version.toString())));
|
||||
|
||||
if (selectedLoader == LoaderType.FORGE) {
|
||||
Optional<LoaderVersion> recommendedVersion = loaderVersions.stream().filter(lv -> lv.recommended)
|
||||
.findFirst();
|
||||
|
||||
if (recommendedVersion.isPresent()) {
|
||||
loaderVersionsDropDown.setSelectedIndex(loaderVersions.indexOf(recommendedVersion.get()));
|
||||
}
|
||||
}
|
||||
|
||||
// ensures that the dropdown is at least 200 px wide
|
||||
loaderVersionLength = Math.max(200, loaderVersionLength);
|
||||
|
||||
// ensures that there is a maximum width of 400 px to prevent overflow
|
||||
loaderVersionLength = Math.min(400, loaderVersionLength);
|
||||
|
||||
loaderVersionsDropDown.setPreferredSize(new Dimension(loaderVersionLength, 23));
|
||||
|
||||
loaderTypeNoneRadioButton.setEnabled(true);
|
||||
loaderTypeFabricRadioButton.setEnabled(true);
|
||||
loaderTypeForgeRadioButton.setEnabled(true);
|
||||
loaderTypeQuiltRadioButton.setEnabled(true);
|
||||
loaderVersionsDropDown.setEnabled(true);
|
||||
createServerButton.setEnabled(enableCreateServers);
|
||||
createInstanceButton.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int loaderVersionLength = 0;
|
||||
|
||||
// ensures that font width is taken into account
|
||||
for (LoaderVersion version : loaderVersions) {
|
||||
loaderVersionLength = Math.max(loaderVersionLength,
|
||||
getFontMetrics(App.THEME.getNormalFont()).stringWidth(version.toString()) + 25);
|
||||
}
|
||||
|
||||
loaderVersionsDropDown.removeAllItems();
|
||||
|
||||
loaderVersions.forEach(version -> loaderVersionsDropDown
|
||||
.addItem(new ComboItem<LoaderVersion>(version, version.toString())));
|
||||
|
||||
if (selectedLoader == LoaderType.FORGE) {
|
||||
Optional<LoaderVersion> recommendedVersion = loaderVersions.stream().filter(lv -> lv.recommended)
|
||||
.findFirst();
|
||||
|
||||
if (recommendedVersion.isPresent()) {
|
||||
loaderVersionsDropDown.setSelectedIndex(loaderVersions.indexOf(recommendedVersion.get()));
|
||||
// update the name and description fields if they're not dirty
|
||||
String defaultNameFieldValue = String.format("Minecraft %s with %s", selectedMinecraftVersion,
|
||||
selectedLoader.toString());
|
||||
if (!nameFieldDirty) {
|
||||
nameField.setText(defaultNameFieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
// ensures that the dropdown is at least 200 px wide
|
||||
loaderVersionLength = Math.max(200, loaderVersionLength);
|
||||
if (!descriptionFieldDirty) {
|
||||
descriptionField.setText(defaultNameFieldValue);
|
||||
}
|
||||
};
|
||||
|
||||
// ensures that there is a maximum width of 400 px to prevent overflow
|
||||
loaderVersionLength = Math.min(400, loaderVersionLength);
|
||||
|
||||
loaderVersionsDropDown.setPreferredSize(new Dimension(loaderVersionLength, 23));
|
||||
|
||||
loaderTypeNoneRadioButton.setEnabled(true);
|
||||
loaderTypeFabricRadioButton.setEnabled(true);
|
||||
loaderTypeForgeRadioButton.setEnabled(true);
|
||||
loaderTypeQuiltRadioButton.setEnabled(true);
|
||||
loaderVersionsDropDown.setEnabled(true);
|
||||
createServerButton.setEnabled(enableCreateServers);
|
||||
createInstanceButton.setEnabled(true);
|
||||
|
||||
// update the name and description fields if they're not dirty
|
||||
String defaultNameFieldValue = String.format("Minecraft %s with %s", selectedMinecraftVersion,
|
||||
selectedLoader.toString());
|
||||
if (!nameFieldDirty) {
|
||||
nameField.setText(defaultNameFieldValue);
|
||||
}
|
||||
|
||||
if (!descriptionFieldDirty) {
|
||||
descriptionField.setText(defaultNameFieldValue);
|
||||
}
|
||||
};
|
||||
|
||||
new Thread(r).start();
|
||||
new Thread(r).start();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupBottomPanel() {
|
||||
|
|
|
@ -17,13 +17,22 @@
|
|||
*/
|
||||
package com.atlauncher.gui.tabs.news;
|
||||
|
||||
import com.atlauncher.managers.NewsManager;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 14 / 06 / 2022
|
||||
*/
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.apollographql.apollo.ApolloCall;
|
||||
import com.apollographql.apollo.api.Response;
|
||||
import com.apollographql.apollo.api.cache.http.HttpCachePolicy;
|
||||
import com.apollographql.apollo.api.cache.http.HttpCachePolicy.FetchStrategy;
|
||||
import com.apollographql.apollo.exception.ApolloException;
|
||||
import com.atlauncher.graphql.GetNewsQuery;
|
||||
import com.atlauncher.managers.ConfigManager;
|
||||
import com.atlauncher.managers.LogManager;
|
||||
import com.atlauncher.managers.NewsManager;
|
||||
import com.atlauncher.network.GraphqlClient;
|
||||
|
||||
public class NewsViewModel implements INewsViewModel {
|
||||
private Consumer<String> _onReload;
|
||||
|
||||
|
@ -34,6 +43,25 @@ public class NewsViewModel implements INewsViewModel {
|
|||
|
||||
@Override
|
||||
public void reload() {
|
||||
_onReload.accept(NewsManager.getNewsHTML());
|
||||
if (ConfigManager.getConfigItem("useGraphql.news", false) == true) {
|
||||
GraphqlClient.apolloClient.query(new GetNewsQuery(10))
|
||||
.toBuilder()
|
||||
.httpCachePolicy(new HttpCachePolicy.Policy(FetchStrategy.CACHE_FIRST, 30, TimeUnit.MINUTES, false))
|
||||
.build()
|
||||
.enqueue(new ApolloCall.Callback<GetNewsQuery.Data>() {
|
||||
@Override
|
||||
public void onResponse(@NotNull Response<GetNewsQuery.Data> response) {
|
||||
_onReload.accept(NewsManager.getNewsHTML(response.getData().generalNews()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull ApolloException e) {
|
||||
LogManager.logStackTrace("Error fetching news", e);
|
||||
_onReload.accept(NewsManager.getNewsHTML());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_onReload.accept(NewsManager.getNewsHTML());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,15 @@ import java.io.FileInputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
|
||||
import com.atlauncher.App;
|
||||
import com.atlauncher.Data;
|
||||
import com.atlauncher.FileSystem;
|
||||
import com.atlauncher.Gsons;
|
||||
import com.atlauncher.data.News;
|
||||
import com.atlauncher.graphql.GetNewsQuery;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
@ -85,4 +88,25 @@ public class NewsManager {
|
|||
|
||||
return news.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a list of news items from GraphQL query and transforms into HTML.
|
||||
*
|
||||
* @return The HTML for displaying on the News Panel
|
||||
*/
|
||||
public static String getNewsHTML(List<GetNewsQuery.GeneralNew> newsItems) {
|
||||
StringBuilder news = new StringBuilder("<html>");
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(App.settings.dateFormat + " HH:mm:ss a");
|
||||
|
||||
for (GetNewsQuery.GeneralNew newsItem : newsItems) {
|
||||
news.append("<h2>" + newsItem.title() + " (" + formatter.format(newsItem.createdAt()) + ")</h2>" + "<p>"
|
||||
+ newsItem.content() + "</p><hr/>");
|
||||
}
|
||||
|
||||
// remove the last <hr/>
|
||||
news = new StringBuilder(news.substring(0, news.length() - 5));
|
||||
news.append("</html>");
|
||||
|
||||
return news.toString();
|
||||
}
|
||||
}
|
||||
|
|
93
src/main/java/com/atlauncher/network/GraphqlClient.java
Normal file
93
src/main/java/com/atlauncher/network/GraphqlClient.java
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* ATLauncher - https://github.com/ATLauncher/ATLauncher
|
||||
* Copyright (C) 2013-2022 ATLauncher
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.atlauncher.network;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.apollographql.apollo.ApolloClient;
|
||||
import com.apollographql.apollo.api.CustomTypeAdapter;
|
||||
import com.apollographql.apollo.api.CustomTypeValue;
|
||||
import com.apollographql.apollo.api.CustomTypeValue.GraphQLString;
|
||||
import com.apollographql.apollo.api.cache.http.HttpCachePolicy;
|
||||
import com.apollographql.apollo.api.cache.http.HttpCachePolicy.FetchStrategy;
|
||||
import com.apollographql.apollo.cache.http.ApolloHttpCache;
|
||||
import com.apollographql.apollo.cache.http.DiskLruHttpCacheStore;
|
||||
import com.apollographql.apollo.internal.batch.BatchConfig;
|
||||
import com.atlauncher.FileSystem;
|
||||
import com.atlauncher.Network;
|
||||
import com.atlauncher.constants.Constants;
|
||||
import com.atlauncher.graphql.type.CustomType;
|
||||
import com.atlauncher.managers.LogManager;
|
||||
|
||||
public class GraphqlClient {
|
||||
|
||||
static {
|
||||
|
||||
CustomTypeAdapter<String> idCustomTypeAdapter = new CustomTypeAdapter<String>() {
|
||||
@Override
|
||||
public String decode(CustomTypeValue<?> value) {
|
||||
return value.value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomTypeValue<?> encode(String value) {
|
||||
return new GraphQLString(value);
|
||||
}
|
||||
};
|
||||
|
||||
CustomTypeAdapter<Date> dateCustomTypeAdapter = new CustomTypeAdapter<Date>() {
|
||||
DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
|
||||
|
||||
@Override
|
||||
public Date decode(CustomTypeValue<?> value) {
|
||||
try {
|
||||
return iso8601Format.parse(value.value.toString());
|
||||
} catch (ParseException e) {
|
||||
LogManager.logStackTrace(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomTypeValue<?> encode(Date value) {
|
||||
return new GraphQLString(iso8601Format.format(value));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
DiskLruHttpCacheStore cacheStore = new DiskLruHttpCacheStore(FileSystem.APOLLO_CACHE.toFile(),
|
||||
100 * 1024 * 1024);
|
||||
|
||||
apolloClient = ApolloClient.builder()
|
||||
.serverUrl(Constants.GRAPHQL_ENDPOINT)
|
||||
.addCustomTypeAdapter(CustomType.ID, idCustomTypeAdapter)
|
||||
.addCustomTypeAdapter(CustomType.DATETIME, dateCustomTypeAdapter)
|
||||
.okHttpClient(Network.GRAPHQL_CLIENT)
|
||||
.httpCache(new ApolloHttpCache(cacheStore))
|
||||
.defaultHttpCachePolicy(
|
||||
new HttpCachePolicy.Policy(FetchStrategy.CACHE_FIRST, 1, TimeUnit.MINUTES, false))
|
||||
.batchingConfiguration(new BatchConfig(true, 500, 10))
|
||||
.build();
|
||||
}
|
||||
|
||||
public final static ApolloClient apolloClient;
|
||||
}
|
|
@ -1508,6 +1508,10 @@ public class Utils {
|
|||
}
|
||||
|
||||
public static boolean matchVersion(String version, String matches, boolean lessThan, boolean equal) {
|
||||
if (version.contains("_")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] versionParts = version.split("\\.", 3);
|
||||
String[] matchedParts = matches.split("\\.", 2);
|
||||
|
||||
|
|
Loading…
Reference in a new issue