Allow clicks on submodules and symlinks (#1018)

Allows clicks on submodules and symlinks in the file browser.
Symlinks opens the file viewer which will view the link target (same behavior as Gitea)
Submodules will redirect to the repository from where they are

Co-authored-by: qwerty287 <ndev@web.de>
Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/1018
Reviewed-by: 6543 <6543@obermui.de>
Co-authored-by: qwerty287 <qwerty287@noreply.codeberg.org>
Co-committed-by: qwerty287 <qwerty287@noreply.codeberg.org>
This commit is contained in:
qwerty287 2022-01-01 00:46:10 +01:00 committed by 6543
parent b31a36d880
commit 23704e62d8
5 changed files with 134 additions and 5 deletions

View File

@ -88,8 +88,10 @@ public class DeepLinksActivity extends BaseActivity {
currentInstance = userAccount.getInstanceUrl();
instanceToken = userAccount.getToken();
String host = data.getHost();
if (host == null) host = "";
if(hostUri.toLowerCase().contains(Objects.requireNonNull(data.getHost().toLowerCase()))) {
if(hostUri.toLowerCase().contains(host.toLowerCase())) {
accountFound = true;
@ -151,8 +153,13 @@ public class DeepLinksActivity extends BaseActivity {
finish();
}
else if(!data.getPathSegments().get(0).equals("") & !data.getLastPathSegment().equals("")) { // go to repo
String repo = data.getLastPathSegment();
if (repo.endsWith(".git")) { // Git clone URL
repo = repo.substring(0, repo.length() - 4);
}
String finalRepo = repo;
new Handler(Looper.getMainLooper()).postDelayed(() ->
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), data.getLastPathSegment(), "repo"), 500);
goToRepoSection(currentInstance, instanceToken, data.getPathSegments().get(0), finalRepo, "repo"), 500);
}
else { // no action, show options
showNoActionButtons();

View File

@ -19,9 +19,13 @@ import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.gitnex.tea4j.models.Files;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.DeepLinksActivity;
import org.mian.gitnex.activities.FileViewActivity;
import org.mian.gitnex.activities.RepoDetailActivity;
import org.mian.gitnex.adapters.FilesAdapter;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.databinding.FragmentFilesBinding;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.Authorization;
@ -29,6 +33,7 @@ import org.mian.gitnex.helpers.Path;
import org.mian.gitnex.viewmodels.FilesViewModel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import moe.feng.common.view.breadcrumbs.DefaultBreadcrumbsCallback;
import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem;
@ -183,12 +188,46 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
break;
case "file":
case "symlink":
Intent intent = new Intent(getContext(), FileViewActivity.class);
intent.putExtra("file", file);
requireContext().startActivity(intent);
break;
case "submodule":
String rawUrl = file.getSubmodule_git_url();
if(rawUrl == null) {
return;
}
Uri url = AppUtil.getUriFromGitUrl(rawUrl);
String host = url.getHost();
UserAccountsApi userAccountsApi = BaseApi.getInstance(requireContext(), UserAccountsApi.class);
List<UserAccount> userAccounts = userAccountsApi.usersAccounts();
boolean accountFound = false;
for(UserAccount userAccount : userAccounts) {
Uri instanceUri = Uri.parse(userAccount.getInstanceUrl());
if(instanceUri.getHost().toLowerCase().equals(host)) {
accountFound = true;
// if scheme is wrong fix it
if (!url.getScheme().equals(instanceUri.getScheme())) {
url = AppUtil.changeScheme(url,instanceUri.getScheme());
}
break;
}
}
if(accountFound) {
Intent iLink = new Intent(requireContext(), DeepLinksActivity.class);
iLink.setData(url);
startActivity(iLink);
} else {
AppUtil.openUrlInBrowser(requireContext(), url.toString());
}
break;
}
}
@ -229,7 +268,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter
FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class);
filesModel.getFilesList2(instanceToken, owner, repo, filesDir, ref, getContext(), binding.progressBar, binding.noDataFiles).observe(this, filesListMain2 -> {
filesModel.getFilesList2(instanceToken, owner, repo, filesDir, ref, getContext(), binding.progressBar, binding.noDataFiles).observe(getViewLifecycleOwner(), filesListMain2 -> {
filesAdapter.getOriginalFiles().clear();
filesAdapter.getOriginalFiles().addAll(filesListMain2);

View File

@ -1,5 +1,6 @@
package org.mian.gitnex.helpers;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@ -8,7 +9,6 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.net.Uri;
import android.util.Base64;
import android.util.DisplayMetrics;
@ -370,9 +370,45 @@ public class AppUtil {
i.addCategory(Intent.CATEGORY_BROWSABLE);
context.startActivity(i);
}
} catch(Exception e) {
} catch(ActivityNotFoundException e) {
Toasty.error(context, context.getString(R.string.browserOpenFailed));
} catch (Exception e) {
Toasty.error(context, context.getString(R.string.genericError));
}
}
public static Uri getUriFromGitUrl(String url) {
Uri uri = Uri.parse(url);
String host = uri.getHost();
if(host != null) {
return uri;
}
// must be a SSH URL now
return Uri.parse(getUriHostFromSSHUrl(url));
}
public static String getUriHostFromSSHUrl(String url) {
int scheme = url.indexOf("://");
if (scheme >= 0) {
url = url.substring(scheme+3);
}
String result = "";
String[] userHost = url.split("@"); // for a full URL this should be ["//user", "host.tld"]
if(userHost.length < 2) {
result = userHost[0].replace("//", "");
} else {
result = userHost[1];
}
return "https://" + result.replace(":", "/");
}
public static Uri changeScheme(Uri origin, String scheme) {
String raw = origin.toString();
int schemeIndex = raw.indexOf("://");
if (schemeIndex >= 0) {
raw = raw.substring(schemeIndex);
}
return Uri.parse(scheme+raw);
}
}

View File

@ -751,4 +751,5 @@
<string name="selectUpdateStrategy">Select Update Strategy</string>
<string name="userAvatar">Avatar</string>
<string name="useCustomTabs">Use Custom Tabs</string>
<string name="browserOpenFailed">No application found to open this link. SSH URLs and URLs with another prefix the http:// or https:// are not supported by most browser</string>
</resources>

View File

@ -0,0 +1,46 @@
package org.mian.gitnex.helpers;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author qwerty287
*/
public class AppUtilTest {
@Test
public void getFileType() {
assertEquals(AppUtil.FileType.AUDIO, AppUtil.getFileType("mp3"));
assertEquals(AppUtil.FileType.IMAGE, AppUtil.getFileType("png"));
assertEquals(AppUtil.FileType.EXECUTABLE, AppUtil.getFileType("deb"));
assertEquals(AppUtil.FileType.TEXT, AppUtil.getFileType("JSON"));
assertEquals(AppUtil.FileType.DOCUMENT, AppUtil.getFileType("PDF"));
}
@Test
public void checkStringsWithAlphaNumeric() {
assertEquals(AppUtil.checkStringsWithAlphaNumeric("string"), true);
assertEquals(AppUtil.checkStringsWithAlphaNumeric("123"), true);
assertEquals(AppUtil.checkStringsWithAlphaNumeric("123 with string"), false);
assertEquals(AppUtil.checkStringsWithAlphaNumeric("string 123"), false);
assertEquals(AppUtil.checkStringsWithAlphaNumeric("string-123"), false);
}
@Test
public void checkIntegers() {
assertEquals(AppUtil.checkIntegers("string"), false);
assertEquals(AppUtil.checkIntegers("123"), true);
assertEquals(AppUtil.checkIntegers("123 with string"), false);
assertEquals(AppUtil.checkIntegers("string 123"), false);
}
@Test
public void parseSSHUrl() {
assertEquals("https://codeberg.org/gitnex/GitNex", AppUtil.getUriHostFromSSHUrl("ssh://git@codeberg.org:gitnex/GitNex"));
assertEquals("https://codeberg.org/gitnex/GitNex", AppUtil.getUriHostFromSSHUrl("codeberg.org:gitnex/GitNex"));
assertEquals("https://codeberg.org/gitnex/GitNex", AppUtil.getUriHostFromSSHUrl("ssh://git@codeberg.org/gitnex/GitNex"));
assertEquals("https://codeberg.org/gitnex/GitNex.git", AppUtil.getUriHostFromSSHUrl("ssh://git@codeberg.org:gitnex/GitNex.git"));
assertEquals("https://codeberg.org/gitnex/GitNex.git", AppUtil.getUriHostFromSSHUrl("codeberg.org:gitnex/GitNex.git"));
}
}