Skip to content

Commit

Permalink
Feat[launcher]: add "Open game directory" button
Browse files Browse the repository at this point in the history
- Also refactors the file sending mechanism.
  • Loading branch information
artdeell committed Oct 14, 2024
1 parent 6474015 commit b16396b
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -510,38 +510,20 @@ public void onStopTrackingTouch(SeekBar seekBar) {}
b.show();
}

private static void setUri(Context context, String input, Intent intent) {
if(input.startsWith("file:")) {
int truncLength = 5;
if(input.startsWith("file://")) truncLength = 7;
input = input.substring(truncLength);
Log.i("MainActivity", input);
boolean isDirectory = new File(input).isDirectory();
if(isDirectory) {
intent.setType(DocumentsContract.Document.MIME_TYPE_DIR);
}else{
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(input);
if(extension != null) type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if(type == null) type = "*/*";
intent.setType(type);
}
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setData(DocumentsContract.buildDocumentUri(
context.getString(R.string.storageProviderAuthorities), input
));
return;
}
intent.setDataAndType(Uri.parse(input), "*/*");
}

public static void openLink(String link) {
Context ctx = touchpad.getContext(); // no more better way to obtain a context statically
((Activity)ctx).runOnUiThread(() -> {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
setUri(ctx, link, intent);
ctx.startActivity(intent);
if(link.startsWith("file:")) {
int truncLength = 5;
if(link.startsWith("file://")) truncLength = 7;
String path = link.substring(truncLength);
Tools.openPath(ctx, new File(path), false);
}else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(link), "*/*");
ctx.startActivity(intent);
}
} catch (Throwable th) {
Tools.showError(ctx, th);
}
Expand All @@ -552,9 +534,7 @@ public static void openPath(String path) {
Context ctx = touchpad.getContext(); // no more better way to obtain a context statically
((Activity)ctx).runOnUiThread(() -> {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(DocumentsContract.buildDocumentUri(ctx.getString(R.string.storageProviderAuthorities), path), "*/*");
ctx.startActivity(intent);
Tools.openPath(ctx, new File(path), false);
} catch (Throwable th) {
Tools.showError(ctx, th);
}
Expand Down
58 changes: 49 additions & 9 deletions app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import org.apache.commons.io.IOUtils;
import org.lwjgl.glfw.CallbackBridge;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
Expand All @@ -82,6 +83,7 @@
import java.io.StringWriter;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.ArrayList;
Expand Down Expand Up @@ -1108,17 +1110,55 @@ public static void runOnUiThread(Runnable runnable) {

/** Triggers the share intent chooser, with the latestlog file attached to it */
public static void shareLog(Context context){
Uri contentUri = DocumentsContract.buildDocumentUri(context.getString(R.string.storageProviderAuthorities), Tools.DIR_GAME_HOME + "/latestlog.txt");
openPath(context, new File(Tools.DIR_GAME_HOME, "latestlog.txt"), true);
}

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.setType("text/plain");
/**
* Determine the MIME type of a File.
* @param file The file to determine the type of
* @return the type, or the default value *slash* if cannot be determined
*/
public static String getMimeType(File file) {
if(file.isDirectory()) return DocumentsContract.Document.MIME_TYPE_DIR;
String mimeType = null;
try (FileInputStream fileInputStream = new FileInputStream(file)){
// Theoretically we don't even need the buffer since we don't care about the
// contents of the file after the guess, but mark-supported streams
// are a requirement of URLConnection.guessContentTypeFromStream()
try(BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream)) {
mimeType = URLConnection.guessContentTypeFromStream(bufferedInputStream);
}
}catch (IOException e) {
Log.w("FileMimeType", "Failed to determine MIME type by stream", e);
}
if(mimeType != null) return mimeType;
mimeType = URLConnection.guessContentTypeFromName(file.getName());
if(mimeType != null) return mimeType;
return "*/*";
}

Intent sendIntent = Intent.createChooser(shareIntent, "latestlog.txt");
context.startActivity(sendIntent);
/**
* Open the path specified by a File in a file explorer or in a relevant application.
* @param context the current Context
* @param file the File to open
* @param share whether to open a "Share" or an "Open" dialog.
*/
public static void openPath(Context context, File file, boolean share) {
Uri contentUri = DocumentsContract.buildDocumentUri(context.getString(R.string.storageProviderAuthorities), file.getAbsolutePath());
String mimeType = getMimeType(file);
Intent intent = new Intent();
if(share) {
intent.setAction(Intent.ACTION_SEND);
intent.setType(getMimeType(file));
intent.putExtra(Intent.EXTRA_STREAM, contentUri);
}else {
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(contentUri, mimeType);
}
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent chooserIntent = Intent.createChooser(intent, file.getName());
context.startActivity(chooserIntent);
}

/** Mesure the textview height, given its current parameters */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.kdt.pojavlaunch.fragments;

import static net.kdt.pojavlaunch.Tools.openPath;
import static net.kdt.pojavlaunch.Tools.shareLog;

import android.content.Intent;
Expand All @@ -20,7 +21,12 @@
import net.kdt.pojavlaunch.Tools;
import net.kdt.pojavlaunch.extra.ExtraConstants;
import net.kdt.pojavlaunch.extra.ExtraCore;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;

import java.io.File;

public class MainMenuFragment extends Fragment {
public static final String TAG = "MainMenuFragment";
Expand All @@ -38,6 +44,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
Button mCustomControlButton = view.findViewById(R.id.custom_control_button);
Button mInstallJarButton = view.findViewById(R.id.install_jar_button);
Button mShareLogsButton = view.findViewById(R.id.share_logs_button);
Button mOpenDirectoryButton = view.findViewById(R.id.open_files_button);

ImageButton mEditProfileButton = view.findViewById(R.id.edit_profile_button);
Button mPlayButton = view.findViewById(R.id.play_button);
Expand All @@ -57,12 +64,24 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat

mShareLogsButton.setOnClickListener((v) -> shareLog(requireContext()));

mOpenDirectoryButton.setOnClickListener((v)-> openPath(v.getContext(), getCurrentProfileDirectory(), false));


mNewsButton.setOnLongClickListener((v)->{
Tools.swapFragment(requireActivity(), GamepadMapperFragment.class, GamepadMapperFragment.TAG, null);
return true;
});
}

private File getCurrentProfileDirectory() {
String currentProfile = LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, null);
if(!Tools.isValidString(currentProfile)) return new File(Tools.DIR_GAME_NEW);
LauncherProfiles.load();
MinecraftProfile profileObject = LauncherProfiles.mainProfileJson.profiles.get(currentProfile);
if(profileObject == null) return new File(Tools.DIR_GAME_NEW);
return Tools.getGameDirPath(profileObject);
}

@Override
public void onResume() {
super.onResume();
Expand Down
56 changes: 30 additions & 26 deletions app_pojavlauncher/src/main/res/layout-land/fragment_launcher.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,25 @@
app:layout_constraintGuide_percent="0.5"/>
<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/news_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
android:drawableStart="@drawable/ic_menu_news"
android:text="@string/mcl_tab_wiki"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/social_divider"/>
<View
android:id="@+id/social_divider"
android:layout_width="@dimen/padding_tiny"
android:layout_height="0dp"
android:background="@color/divider"
style="@style/LauncherFragment_Divider"
android:layout_marginVertical="@dimen/padding_heavy"
app:layout_constraintTop_toTopOf="@id/news_button"
app:layout_constraintStart_toStartOf="@id/center_guideline"
app:layout_constraintEnd_toEndOf="@id/center_guideline"
app:layout_constraintBottom_toBottomOf="@id/news_button"/>
<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/discord_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
android:drawableStart="@drawable/ic_discord"
android:text="@string/mcl_button_discord"
app:layout_constraintTop_toTopOf="parent"
Expand All @@ -65,36 +57,48 @@

<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/custom_control_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
android:drawableStart="@drawable/ic_menu_custom_controls"
android:text="@string/mcl_option_customcontrol"
app:layout_constraintTop_toBottomOf="@id/news_button"/>

<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/install_jar_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
android:drawableStart="@drawable/ic_menu_install_jar"
android:text="@string/main_install_jar_file"
app:layout_constraintTop_toBottomOf="@id/custom_control_button"/>
app:layout_constraintTop_toBottomOf="@id/custom_control_button"
tools:layout_editor_absoluteX="0dp" />

<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/share_logs_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
style="@style/LauncherMenuButton.Universal"
android:layout_width="0dp"
android:drawableStart="@android:drawable/ic_menu_share"
android:text="@string/main_share_logs"
app:layout_constraintTop_toBottomOf="@id/install_jar_button"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/install_jar_button"
app:layout_constraintEnd_toStartOf="@id/files_divider"/>
<View
android:id="@+id/files_divider"
style="@style/LauncherFragment_Divider"
android:layout_marginVertical="@dimen/padding_heavy"
app:layout_constraintTop_toTopOf="@id/share_logs_button"
app:layout_constraintStart_toStartOf="@id/center_guideline"
app:layout_constraintEnd_toEndOf="@id/center_guideline"
app:layout_constraintBottom_toBottomOf="@id/share_logs_button"/>

<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/open_files_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="0dp"
android:drawableStart="@drawable/ic_folder"
android:text="@string/mcl_button_open_directory"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/files_divider"
app:layout_constraintTop_toBottomOf="@id/install_jar_button" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

Expand Down
54 changes: 30 additions & 24 deletions app_pojavlauncher/src/main/res/layout/fragment_launcher.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,25 @@
app:layout_constraintGuide_percent="0.5"/>
<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/news_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="0dp"
android:layout_height="@dimen/_66sdp"
android:background="?android:attr/selectableItemBackground"

android:text="@string/mcl_tab_wiki"
android:drawableStart="@drawable/ic_menu_news"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/social_divider" />
<View
android:id="@+id/social_divider"
android:layout_width="@dimen/padding_tiny"
android:layout_height="0dp"
android:background="@color/divider"
style="@style/LauncherFragment_Divider"
android:layout_marginVertical="@dimen/padding_large"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="@id/center_guideline"
app:layout_constraintEnd_toEndOf="@id/center_guideline"
app:layout_constraintBottom_toBottomOf="@id/news_button"/>
<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/discord_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="0dp"
android:layout_height="@dimen/_66sdp"
android:background="?android:attr/selectableItemBackground"

android:text="@string/mcl_button_discord"
android:drawableStart="@drawable/ic_discord"
app:layout_constraintTop_toTopOf="parent"
Expand All @@ -60,36 +54,48 @@

<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/custom_control_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="match_parent"
android:layout_height="@dimen/_66sdp"
android:background="?android:attr/selectableItemBackground"
android:drawableStart="@drawable/ic_menu_custom_controls"
android:text="@string/mcl_option_customcontrol"
app:layout_constraintTop_toBottomOf="@id/news_button"

/>
app:layout_constraintTop_toBottomOf="@id/news_button" />

<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/install_jar_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="match_parent"
android:layout_height="@dimen/_66sdp"
android:background="?android:attr/selectableItemBackground"
android:drawableStart="@drawable/ic_menu_install_jar"
android:text="@string/main_install_jar_file"

app:layout_constraintTop_toBottomOf="@id/custom_control_button"
/>
app:layout_constraintTop_toBottomOf="@id/custom_control_button" />

<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/share_logs_button"
android:layout_width="match_parent"
android:layout_height="@dimen/_66sdp"
android:background="?android:attr/selectableItemBackground"
style="@style/LauncherMenuButton.Universal"
android:layout_width="0dp"
android:drawableStart="@android:drawable/ic_menu_share"
android:text="@string/main_share_logs"

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/install_jar_button"
/>
app:layout_constraintEnd_toStartOf="@id/files_divider"/>

<View
android:id="@+id/files_divider"
style="@style/LauncherFragment_Divider"
android:layout_marginVertical="@dimen/padding_large"
app:layout_constraintTop_toTopOf="@id/share_logs_button"
app:layout_constraintStart_toStartOf="@id/center_guideline"
app:layout_constraintEnd_toEndOf="@id/center_guideline"
app:layout_constraintBottom_toBottomOf="@id/share_logs_button"/>

<com.kdt.mcgui.LauncherMenuButton
android:id="@+id/open_files_button"
style="@style/LauncherMenuButton.Universal"
android:layout_width="0dp"
android:drawableStart="@drawable/ic_folder"
android:text="@string/mcl_button_open_directory"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/files_divider"
app:layout_constraintTop_toBottomOf="@id/install_jar_button" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

Expand Down
Loading

0 comments on commit b16396b

Please sign in to comment.