mirror of
https://github.com/nextcloud/android.git
synced 2024-12-19 15:33:00 +03:00
Merge remote-tracking branch 'origin/master' into dev
This commit is contained in:
commit
24f96857b3
30 changed files with 230 additions and 161 deletions
|
@ -69,7 +69,7 @@ complexity:
|
|||
excludes: ['**/androidTest/**']
|
||||
LongParameterList:
|
||||
active: true
|
||||
functionThreshold: 6
|
||||
functionThreshold: 7
|
||||
constructorThreshold: 6
|
||||
ignoreDefaultParameters: false
|
||||
MethodOverloading:
|
||||
|
|
|
@ -107,20 +107,8 @@ public abstract class AbstractIT {
|
|||
}
|
||||
}
|
||||
|
||||
Account temp = new Account("test@https://nextcloud.localhost", MainApp.getAccountType(targetContext));
|
||||
platformAccountManager.addAccountExplicitly(temp, "password", null);
|
||||
platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_BASE_URL, "https://nextcloud.localhost");
|
||||
platformAccountManager.setUserData(temp, KEY_USER_ID, "test");
|
||||
|
||||
final UserAccountManager userAccountManager = UserAccountManagerImpl.fromContext(targetContext);
|
||||
account = userAccountManager.getAccountByName("test@https://nextcloud.localhost");
|
||||
|
||||
if (account == null) {
|
||||
throw new ActivityNotFoundException();
|
||||
}
|
||||
|
||||
Optional<User> optionalUser = userAccountManager.getUser(account.name);
|
||||
user = optionalUser.orElseThrow(IllegalAccessError::new);
|
||||
account = createAccount("test@https://nextcloud.localhost");
|
||||
user = getUser(account);
|
||||
|
||||
client = OwnCloudClientFactory.createOwnCloudClient(account, targetContext);
|
||||
nextcloudClient = OwnCloudClientFactory.createNextcloudClient(user, targetContext);
|
||||
|
@ -447,4 +435,31 @@ public abstract class AbstractIT {
|
|||
public static String getUserId(User user) {
|
||||
return AccountManager.get(targetContext).getUserData(user.toPlatformAccount(), KEY_USER_ID);
|
||||
}
|
||||
|
||||
protected static User getUser(Account account) {
|
||||
Optional<User> optionalUser = UserAccountManagerImpl.fromContext(targetContext).getUser(account.name);
|
||||
return optionalUser.orElseThrow(IllegalAccessError::new);
|
||||
}
|
||||
|
||||
protected static Account createAccount(String name) {
|
||||
AccountManager platformAccountManager = AccountManager.get(targetContext);
|
||||
|
||||
Account temp = new Account(name, MainApp.getAccountType(targetContext));
|
||||
int atPos = name.lastIndexOf('@');
|
||||
platformAccountManager.addAccountExplicitly(temp, "password", null);
|
||||
platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_BASE_URL,
|
||||
name.substring(atPos + 1));
|
||||
platformAccountManager.setUserData(temp, KEY_USER_ID, name.substring(0, atPos));
|
||||
|
||||
Account account = UserAccountManagerImpl.fromContext(targetContext).getAccountByName(name);
|
||||
if (account == null) {
|
||||
throw new ActivityNotFoundException();
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
protected static boolean removeAccount(Account account) {
|
||||
return AccountManager.get(targetContext).removeAccountExplicitly(account);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -269,6 +269,81 @@ class FileMenuFilterIT : AbstractIT() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun filter_select_all() {
|
||||
configureCapability(OCCapability())
|
||||
|
||||
// not in single file fragment -> multi selection is possible under certain circumstances
|
||||
|
||||
launchActivity<TestActivity>().use {
|
||||
it.onActivity { activity ->
|
||||
val filterFactory = FileMenuFilter.Factory(mockStorageManager, activity, editorUtils)
|
||||
|
||||
val files = listOf(OCFile("/foo.bin"), OCFile("/bar.bin"), OCFile("/baz.bin"))
|
||||
|
||||
// single file, not in multi selection
|
||||
// *Select all* and *Deselect all* should stay hidden
|
||||
var sut = filterFactory.newInstance(files.first(), mockComponentsGetter, true, user)
|
||||
|
||||
var toHide = sut.getToHide(false)
|
||||
assertTrue(toHide.contains(R.id.action_select_all_action_menu))
|
||||
assertTrue(toHide.contains(R.id.action_deselect_all_action_menu))
|
||||
|
||||
// multiple files, all selected in multi selection
|
||||
// *Deselect all* shown, *Select all* not
|
||||
sut = filterFactory.newInstance(files.size, files, mockComponentsGetter, false, user)
|
||||
|
||||
toHide = sut.getToHide(false)
|
||||
assertTrue(toHide.contains(R.id.action_select_all_action_menu))
|
||||
assertFalse(toHide.contains(R.id.action_deselect_all_action_menu))
|
||||
|
||||
// multiple files, all but one selected
|
||||
// both *Select all* and *Deselect all* should be shown
|
||||
sut = filterFactory.newInstance(files.size + 1, files, mockComponentsGetter, false, user)
|
||||
|
||||
toHide = sut.getToHide(false)
|
||||
assertFalse(toHide.contains(R.id.action_select_all_action_menu))
|
||||
assertFalse(toHide.contains(R.id.action_deselect_all_action_menu))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun filter_select_all_singleFileFragment() {
|
||||
configureCapability(OCCapability())
|
||||
|
||||
// in single file fragment (e.g. FileDetailFragment or PreviewImageFragment), selecting multiple files
|
||||
// is not possible -> *Select all* and *Deselect all* options should be hidden
|
||||
|
||||
launchActivity<TestActivity>().use {
|
||||
it.onActivity { activity ->
|
||||
val filterFactory = FileMenuFilter.Factory(mockStorageManager, activity, editorUtils)
|
||||
|
||||
val files = listOf(OCFile("/foo.bin"), OCFile("/bar.bin"), OCFile("/baz.bin"))
|
||||
|
||||
// single file
|
||||
var sut = filterFactory.newInstance(files.first(), mockComponentsGetter, true, user)
|
||||
|
||||
var toHide = sut.getToHide(true)
|
||||
assertTrue(toHide.contains(R.id.action_select_all_action_menu))
|
||||
assertTrue(toHide.contains(R.id.action_deselect_all_action_menu))
|
||||
|
||||
// multiple files, all selected
|
||||
sut = filterFactory.newInstance(files.size, files, mockComponentsGetter, false, user)
|
||||
|
||||
toHide = sut.getToHide(true)
|
||||
assertTrue(toHide.contains(R.id.action_select_all_action_menu))
|
||||
assertTrue(toHide.contains(R.id.action_deselect_all_action_menu))
|
||||
|
||||
// multiple files, all but one selected
|
||||
sut = filterFactory.newInstance(files.size + 1, files, mockComponentsGetter, false, user)
|
||||
|
||||
toHide = sut.getToHide(true)
|
||||
assertTrue(toHide.contains(R.id.action_select_all_action_menu))
|
||||
assertTrue(toHide.contains(R.id.action_deselect_all_action_menu))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class ExpectedLockVisibilities(
|
||||
val lockFile: Boolean,
|
||||
val unlockFile: Boolean
|
||||
|
|
|
@ -38,4 +38,12 @@ class ReceiveExternalFilesActivityIT : AbstractIT() {
|
|||
val sut: Activity = activityRule.launchActivity(null)
|
||||
screenshot(sut)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ScreenshotTest
|
||||
fun openMultiAccount() {
|
||||
val secondAccount = createAccount("secondtest@https://nextcloud.localhost")
|
||||
open()
|
||||
removeAccount(secondAccount)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package com.nextcloud.client.errorhandling
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
|
@ -65,17 +64,11 @@ class ShowErrorActivity : AppCompatActivity() {
|
|||
|
||||
private fun reportIssue() {
|
||||
ClipboardUtil.copyToClipboard(this, binding.textViewError.text.toString(), false)
|
||||
val issueLink = getString(R.string.report_issue_link)
|
||||
if (issueLink.isNotEmpty()) {
|
||||
val uriUrl = Uri.parse(
|
||||
String.format(
|
||||
issueLink,
|
||||
URLEncoder.encode(binding.textViewError.text.toString())
|
||||
)
|
||||
)
|
||||
val intent = Intent(Intent.ACTION_VIEW, uriUrl)
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available)
|
||||
}
|
||||
val issueLink = String.format(
|
||||
getString(R.string.report_issue_link),
|
||||
URLEncoder.encode(binding.textViewError.text.toString(), Charsets.UTF_8.name())
|
||||
)
|
||||
DisplayUtils.startLinkIntent(this, issueLink)
|
||||
Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ import android.accounts.Account;
|
|||
import android.accounts.AccountManager;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -117,8 +116,8 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
|
|||
defaultViewThemeUtils.platform.colorTextView(binding.hostOwnServer, ColorRole.ON_PRIMARY);
|
||||
binding.hostOwnServer.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (!isProviderOrOwnInstallationVisible) {
|
||||
binding.hostOwnServer.setOnClickListener(v -> onHostYourOwnServerClick());
|
||||
if (isProviderOrOwnInstallationVisible) {
|
||||
binding.hostOwnServer.setOnClickListener(v -> DisplayUtils.startLinkIntent(this, R.string.url_server_install));
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,11 +152,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
|
|||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
setSlideshowSize(true);
|
||||
} else {
|
||||
setSlideshowSize(false);
|
||||
}
|
||||
setSlideshowSize(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -201,11 +196,6 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
|
|||
// unused but to be implemented due to abstract parent
|
||||
}
|
||||
|
||||
public void onHostYourOwnServerClick() {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.url_server_install)));
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
|
|
@ -324,7 +324,7 @@ class FileActionsBottomSheet : BottomSheetDialogFragment(), Injectable {
|
|||
@IdRes
|
||||
additionalToHide: List<Int>? = null
|
||||
): FileActionsBottomSheet {
|
||||
return newInstance(1, listOf(file), isOverflow, additionalToHide)
|
||||
return newInstance(1, listOf(file), isOverflow, additionalToHide, true)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
@ -334,13 +334,15 @@ class FileActionsBottomSheet : BottomSheetDialogFragment(), Injectable {
|
|||
files: Collection<OCFile>,
|
||||
isOverflow: Boolean,
|
||||
@IdRes
|
||||
additionalToHide: List<Int>? = null
|
||||
additionalToHide: List<Int>? = null,
|
||||
inSingleFileFragment: Boolean = false
|
||||
): FileActionsBottomSheet {
|
||||
return FileActionsBottomSheet().apply {
|
||||
val argsBundle = bundleOf(
|
||||
FileActionsViewModel.ARG_ALL_FILES_COUNT to numberOfAllFiles,
|
||||
FileActionsViewModel.ARG_FILES to ArrayList<OCFile>(files),
|
||||
FileActionsViewModel.ARG_IS_OVERFLOW to isOverflow
|
||||
FileActionsViewModel.ARG_IS_OVERFLOW to isOverflow,
|
||||
FileActionsViewModel.ARG_IN_SINGLE_FILE_FRAGMENT to inSingleFileFragment
|
||||
)
|
||||
additionalToHide?.let {
|
||||
argsBundle.putIntArray(FileActionsViewModel.ARG_ADDITIONAL_FILTER, additionalToHide.toIntArray())
|
||||
|
|
|
@ -69,17 +69,21 @@ class FileActionsViewModel @Inject constructor(
|
|||
@IdRes
|
||||
get() = _clickActionId
|
||||
|
||||
fun load(arguments: Bundle, componentsGetter: ComponentsGetter) {
|
||||
fun load(
|
||||
arguments: Bundle,
|
||||
componentsGetter: ComponentsGetter
|
||||
) {
|
||||
val files: List<OCFile>? = arguments.getParcelableArrayList(ARG_FILES)
|
||||
val numberOfAllFiles: Int = arguments.getInt(ARG_ALL_FILES_COUNT, 1)
|
||||
val isOverflow = arguments.getBoolean(ARG_IS_OVERFLOW, false)
|
||||
val additionalFilter: IntArray? = arguments.getIntArray(ARG_ADDITIONAL_FILTER)
|
||||
val inSingleFileFragment = arguments.getBoolean(ARG_IN_SINGLE_FILE_FRAGMENT)
|
||||
|
||||
if (files.isNullOrEmpty()) {
|
||||
logger.d(TAG, "No valid files argument for loading actions")
|
||||
_uiState.postValue(UiState.Error)
|
||||
} else {
|
||||
load(componentsGetter, files.toList(), numberOfAllFiles, isOverflow, additionalFilter)
|
||||
load(componentsGetter, files.toList(), numberOfAllFiles, isOverflow, additionalFilter, inSingleFileFragment)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,10 +92,11 @@ class FileActionsViewModel @Inject constructor(
|
|||
files: Collection<OCFile>,
|
||||
numberOfAllFiles: Int?,
|
||||
isOverflow: Boolean?,
|
||||
additionalFilter: IntArray?
|
||||
additionalFilter: IntArray?,
|
||||
inSingleFileFragment: Boolean = false
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val toHide = getHiddenActions(componentsGetter, numberOfAllFiles, files, isOverflow)
|
||||
val toHide = getHiddenActions(componentsGetter, numberOfAllFiles, files, isOverflow, inSingleFileFragment)
|
||||
val availableActions = getActionsToShow(additionalFilter, toHide)
|
||||
updateStateLoaded(files, availableActions)
|
||||
}
|
||||
|
@ -101,7 +106,8 @@ class FileActionsViewModel @Inject constructor(
|
|||
componentsGetter: ComponentsGetter,
|
||||
numberOfAllFiles: Int?,
|
||||
files: Collection<OCFile>,
|
||||
isOverflow: Boolean?
|
||||
isOverflow: Boolean?,
|
||||
inSingleFileFragment: Boolean
|
||||
): List<Int> {
|
||||
return filterFactory.newInstance(
|
||||
numberOfAllFiles ?: 1,
|
||||
|
@ -110,7 +116,7 @@ class FileActionsViewModel @Inject constructor(
|
|||
isOverflow ?: false,
|
||||
currentAccountProvider.user
|
||||
)
|
||||
.getToHide(false)
|
||||
.getToHide(inSingleFileFragment)
|
||||
}
|
||||
|
||||
private fun getActionsToShow(
|
||||
|
@ -161,6 +167,7 @@ class FileActionsViewModel @Inject constructor(
|
|||
const val ARG_FILES = "FILES"
|
||||
const val ARG_IS_OVERFLOW = "OVERFLOW"
|
||||
const val ARG_ADDITIONAL_FILTER = "ADDITIONAL_FILTER"
|
||||
const val ARG_IN_SINGLE_FILE_FRAGMENT = "IN_SINGLE_FILE_FRAGMENT"
|
||||
|
||||
private val TAG = FileActionsViewModel::class.simpleName!!
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import kotlin.text.Charsets;
|
||||
|
||||
/**
|
||||
* Manager for concurrent access to thumbnails cache.
|
||||
|
@ -1415,7 +1416,7 @@ public final class ThumbnailsCacheManager {
|
|||
GetMethod getMethod = null;
|
||||
try {
|
||||
String uri = mClient.getBaseUri() + "/index.php/core/preview.png?file="
|
||||
+ URLEncoder.encode(file.getRemotePath())
|
||||
+ URLEncoder.encode(file.getRemotePath(), Charsets.UTF_8.name())
|
||||
+ "&x=" + (pxW / 2) + "&y=" + (pxH / 2) + "&a=1&mode=cover&forceIcon=0";
|
||||
Log_OC.d(TAG, "generate resized image: " + file.getFileName() + " URI: " + uri);
|
||||
getMethod = new GetMethod(uri);
|
||||
|
|
|
@ -185,23 +185,19 @@ public class FileMenuFilter {
|
|||
return toHide;
|
||||
}
|
||||
|
||||
|
||||
private void filterShareFile(List<Integer> toHide, OCCapability capability) {
|
||||
if (containsEncryptedFile() || (!isShareViaLinkAllowed() && !isShareWithUsersAllowed()) ||
|
||||
!isSingleSelection() || !isShareApiEnabled(capability) || !files.iterator().next().canReshare()
|
||||
|| overflowMenu) {
|
||||
if (!isSingleSelection() || containsEncryptedFile() ||
|
||||
(!isShareViaLinkAllowed() && !isShareWithUsersAllowed()) ||
|
||||
!isShareApiEnabled(capability) || !files.iterator().next().canReshare()) {
|
||||
toHide.add(R.id.action_send_share_file);
|
||||
}
|
||||
}
|
||||
|
||||
private void filterSendFiles(List<Integer> toHide, boolean inSingleFileFragment) {
|
||||
boolean show = true;
|
||||
if (overflowMenu || SEND_OFF.equalsIgnoreCase(context.getString(R.string.send_files_to_other_apps)) || containsEncryptedFile()) {
|
||||
show = false;
|
||||
}
|
||||
if (!inSingleFileFragment && (isSingleSelection() || !anyFileDown())) {
|
||||
show = false;
|
||||
}
|
||||
if (!show) {
|
||||
if ((overflowMenu || SEND_OFF.equalsIgnoreCase(context.getString(R.string.send_files_to_other_apps)) || containsEncryptedFile()) ||
|
||||
(!inSingleFileFragment && (isSingleSelection() || !allFileDown())) ||
|
||||
!toHide.contains(R.id.action_send_share_file)) {
|
||||
toHide.add(R.id.action_send_file);
|
||||
}
|
||||
}
|
||||
|
@ -543,6 +539,15 @@ public class FileMenuFilter {
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean allFileDown() {
|
||||
for (OCFile file: files) {
|
||||
if(!file.isDown()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean allFavorites() {
|
||||
for (OCFile file : files) {
|
||||
if (!file.isFavorite()) {
|
||||
|
|
|
@ -580,8 +580,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
for (ExternalLink link : externalLinksProvider.getExternalLink(ExternalLinkType.LINK)) {
|
||||
if (menuItem.getTitle().toString().equalsIgnoreCase(link.getName())) {
|
||||
if (link.getRedirect()) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link.getUrl()));
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available);
|
||||
DisplayUtils.startLinkIntent(this, link.getUrl());
|
||||
} else {
|
||||
Intent externalWebViewIntent = new Intent(getApplicationContext(), ExternalSiteWebView.class);
|
||||
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_TITLE, link.getName());
|
||||
|
|
|
@ -680,19 +680,14 @@ public abstract class FileActivity extends DrawerActivity
|
|||
DisplayUtils.showSnackMessage(activity, R.string.dev_version_no_information_available, Snackbar.LENGTH_LONG);
|
||||
}
|
||||
if (latestVersion > currentVersion) {
|
||||
String devApkLink = activity.getString(R.string.dev_link) + latestVersion + ".apk";
|
||||
if (openDirectly) {
|
||||
String devApkLink = (String) activity.getText(R.string.dev_link) + latestVersion + ".apk";
|
||||
Uri uriUrl = Uri.parse(devApkLink);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, activity, R.string.no_browser_available);
|
||||
DisplayUtils.startLinkIntent(activity, devApkLink);
|
||||
} else {
|
||||
Snackbar.make(activity.findViewById(android.R.id.content), R.string.dev_version_new_version_available,
|
||||
Snackbar.LENGTH_LONG)
|
||||
.setAction(activity.getString(R.string.version_dev_download), v -> {
|
||||
String devApkLink = (String) activity.getText(R.string.dev_link) + latestVersion + ".apk";
|
||||
Uri uriUrl = Uri.parse(devApkLink);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, activity, R.string.no_browser_available);
|
||||
DisplayUtils.startLinkIntent(activity, devApkLink);
|
||||
}).show();
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1093,6 +1093,8 @@ public class FileDisplayActivity extends FileActivity
|
|||
}
|
||||
} else if (leftFragment instanceof PreviewTextStringFragment) {
|
||||
createMinFragments(null);
|
||||
} else if (leftFragment instanceof PreviewPdfFragment) {
|
||||
super.onBackPressed();
|
||||
} else {
|
||||
// pop back
|
||||
resetScrolling(true);
|
||||
|
|
|
@ -41,21 +41,10 @@ import android.os.Looper;
|
|||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.*;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.*;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.nextcloud.client.account.User;
|
||||
|
@ -79,19 +68,11 @@ import com.owncloud.android.operations.UploadFileOperation;
|
|||
import com.owncloud.android.syncadapter.FileSyncAdapter;
|
||||
import com.owncloud.android.ui.adapter.UploaderAdapter;
|
||||
import com.owncloud.android.ui.asynctasks.CopyAndUploadContentUrisTask;
|
||||
import com.owncloud.android.ui.dialog.AccountChooserInterface;
|
||||
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.MultipleAccountsDialog;
|
||||
import com.owncloud.android.ui.dialog.SortingOrderDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.*;
|
||||
import com.owncloud.android.ui.fragment.TaskRetainerFragment;
|
||||
import com.owncloud.android.ui.helpers.FileOperationsHelper;
|
||||
import com.owncloud.android.ui.helpers.UriUploader;
|
||||
import com.owncloud.android.utils.DataHolderUtil;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.ErrorMessageAdapter;
|
||||
import com.owncloud.android.utils.FileSortOrder;
|
||||
import com.owncloud.android.utils.MimeType;
|
||||
import com.owncloud.android.utils.*;
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -99,15 +80,7 @@ import java.io.FileWriter;
|
|||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.Vector;
|
||||
import java.util.*;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -1039,8 +1012,8 @@ public class ReceiveExternalFilesActivity extends FileActivity
|
|||
inflater.inflate(R.menu.activity_receive_external_files, menu);
|
||||
|
||||
if (!isHaveMultipleAccount()) {
|
||||
MenuItem switchAccountMenu = menu.findItem(R.id.action_switch_account);
|
||||
switchAccountMenu.setVisible(false);
|
||||
menu.findItem(R.id.action_switch_account).setVisible(false);
|
||||
menu.findItem(R.id.action_create_dir).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
}
|
||||
|
||||
// tint search event
|
||||
|
|
|
@ -361,9 +361,7 @@ public class SettingsActivity extends PreferenceActivity
|
|||
String imprintWeb = getString(R.string.url_imprint);
|
||||
|
||||
if (!imprintWeb.isEmpty()) {
|
||||
Uri uriUrl = Uri.parse(imprintWeb);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available);
|
||||
DisplayUtils.startLinkIntent(this, imprintWeb);
|
||||
}
|
||||
//ImprintDialog.newInstance(true).show(preference.get, "IMPRINT_DIALOG");
|
||||
return true;
|
||||
|
@ -539,12 +537,7 @@ public class SettingsActivity extends PreferenceActivity
|
|||
if (pHelp != null) {
|
||||
if (helpEnabled) {
|
||||
pHelp.setOnPreferenceClickListener(preference -> {
|
||||
String helpWeb = getString(R.string.url_help);
|
||||
if (!helpWeb.isEmpty()) {
|
||||
Uri uriUrl = Uri.parse(helpWeb);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available);
|
||||
}
|
||||
DisplayUtils.startLinkIntent(this, R.string.url_help);
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
|
@ -897,9 +890,7 @@ public class SettingsActivity extends PreferenceActivity
|
|||
startActivity(installIntent);
|
||||
} else {
|
||||
// no f-droid market app or Play store installed --> launch browser for f-droid url
|
||||
Intent downloadIntent = new Intent(Intent.ACTION_VIEW,
|
||||
Uri.parse("https://f-droid.org/repository/browse/?fdid=at.bitfire.davdroid"));
|
||||
DisplayUtils.startIntentIfAppAvailable(downloadIntent, this, R.string.no_browser_available);
|
||||
DisplayUtils.startLinkIntent(this, "https://f-droid.org/packages/at.bitfire.davdroid/");
|
||||
|
||||
DisplayUtils.showSnackMessage(this, R.string.prefs_calendar_contacts_no_store_error);
|
||||
}
|
||||
|
|
|
@ -123,7 +123,8 @@ public class NotificationListAdapter extends RecyclerView.Adapter<NotificationLi
|
|||
subject = subject + " ↗";
|
||||
holder.binding.subject.setTypeface(holder.binding.subject.getTypeface(),
|
||||
Typeface.BOLD);
|
||||
holder.binding.subject.setOnClickListener(v -> openLink(notification.getLink()));
|
||||
holder.binding.subject.setOnClickListener(v -> DisplayUtils.startLinkIntent(notificationsActivity,
|
||||
notification.getLink()));
|
||||
holder.binding.subject.setText(subject);
|
||||
} else {
|
||||
if (!TextUtils.isEmpty(notification.subjectRich)) {
|
||||
|
@ -329,8 +330,7 @@ public class NotificationListAdapter extends RecyclerView.Adapter<NotificationLi
|
|||
closingBrace = openingBrace + name.length();
|
||||
|
||||
ssb.setSpan(styleSpanBold, openingBrace, closingBrace, 0);
|
||||
ssb.setSpan(foregroundColorSpanBlack, openingBrace, closingBrace,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
ssb.setSpan(foregroundColorSpanBlack, openingBrace, closingBrace, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
openingBrace = text.indexOf('{', closingBrace);
|
||||
}
|
||||
|
@ -382,12 +382,6 @@ public class NotificationListAdapter extends RecyclerView.Adapter<NotificationLi
|
|||
.into(itemViewType);
|
||||
}
|
||||
|
||||
private void openLink(String link) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
|
||||
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, notificationsActivity, R.string.no_browser_available);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return notificationsList.size();
|
||||
|
|
|
@ -87,6 +87,7 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
|
|||
private static final String TAG = ChooseRichDocumentsTemplateDialogFragment.class.getSimpleName();
|
||||
private static final String DOT = ".";
|
||||
public static final int SINGLE_TEMPLATE = 1;
|
||||
private static final String WAIT_DIALOG_TAG = "WAIT";
|
||||
|
||||
private Set<String> fileNames;
|
||||
|
||||
|
@ -99,6 +100,7 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
|
|||
private OCFile parentFolder;
|
||||
private OwnCloudClient client;
|
||||
private Button positiveButton;
|
||||
private DialogFragment waitDialog;
|
||||
|
||||
public enum Type {
|
||||
DOCUMENT,
|
||||
|
@ -234,6 +236,8 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
|
|||
}
|
||||
|
||||
private void createFromTemplate(Template template, String path) {
|
||||
waitDialog = IndeterminateProgressDialog.newInstance(R.string.wait_a_moment, false);
|
||||
waitDialog.show(getParentFragmentManager(), WAIT_DIALOG_TAG);
|
||||
new CreateFileFromTemplateTask(this, client, template, path, currentAccount.getUser()).execute();
|
||||
}
|
||||
|
||||
|
@ -364,8 +368,13 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
|
|||
ChooseRichDocumentsTemplateDialogFragment fragment = chooseTemplateDialogFragmentWeakReference.get();
|
||||
|
||||
if (fragment != null && fragment.isAdded()) {
|
||||
if (fragment.waitDialog != null) {
|
||||
fragment.waitDialog.dismiss();
|
||||
}
|
||||
|
||||
if (url.isEmpty()) {
|
||||
DisplayUtils.showSnackMessage(fragment.binding.list, R.string.error_creating_file_from_template);
|
||||
fragment.dismiss();
|
||||
DisplayUtils.showSnackMessage(fragment.requireActivity(), R.string.error_creating_file_from_template);
|
||||
} else {
|
||||
Intent collaboraWebViewIntent = new Intent(MainApp.getAppContext(), RichDocumentsEditorWebView.class);
|
||||
collaboraWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_TITLE, "Collabora");
|
||||
|
@ -416,7 +425,8 @@ public class ChooseRichDocumentsTemplateDialogFragment extends DialogFragment im
|
|||
|
||||
if (fragment != null) {
|
||||
if (templateList.isEmpty()) {
|
||||
DisplayUtils.showSnackMessage(fragment.binding.list, R.string.error_retrieving_templates);
|
||||
fragment.dismiss();
|
||||
DisplayUtils.showSnackMessage(fragment.requireActivity(), R.string.error_retrieving_templates);
|
||||
} else {
|
||||
if (templateList.size() == SINGLE_TEMPLATE) {
|
||||
fragment.onTemplateChosen(templateList.get(0));
|
||||
|
|
|
@ -282,7 +282,8 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
|
|||
R.id.action_copy,
|
||||
R.id.action_stream_media,
|
||||
R.id.action_send_share_file,
|
||||
R.id.action_select_all_action_menu));
|
||||
R.id.action_pin_to_homescreen
|
||||
));
|
||||
if (getFile().isFolder()) {
|
||||
additionalFilter.add(R.id.action_send_file);
|
||||
additionalFilter.add(R.id.action_sync_file);
|
||||
|
|
|
@ -1524,7 +1524,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
setTitle(R.string.drawer_item_shared);
|
||||
break;
|
||||
default:
|
||||
setTitle(themeUtils.getDefaultDisplayNameForRootFolder(getContext()));
|
||||
setTitle(themeUtils.getDefaultDisplayNameForRootFolder(getContext()), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1591,7 +1591,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
((FileDisplayActivity) activity).initSyncBroadcastReceiver();
|
||||
}
|
||||
|
||||
setTitle(themeUtils.getDefaultDisplayNameForRootFolder(getContext()));
|
||||
setTitle(themeUtils.getDefaultDisplayNameForRootFolder(getContext()), false);
|
||||
activity.getIntent().removeExtra(OCFileListFragment.SEARCH_EVENT);
|
||||
}
|
||||
|
||||
|
@ -1843,18 +1843,30 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme default action bar according to provided parameters.
|
||||
* Replaces back arrow with hamburger menu icon.
|
||||
*
|
||||
* @param title string res id of title to be shown in action bar
|
||||
*/
|
||||
protected void setTitle(@StringRes final int title) {
|
||||
setTitle(getContext().getString(title));
|
||||
setTitle(requireContext().getString(title), true);
|
||||
}
|
||||
|
||||
protected void setTitle(final String title) {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
/**
|
||||
* Theme default action bar according to provided parameters.
|
||||
*
|
||||
* @param title title to be shown in action bar
|
||||
* @param showBackAsMenu iff true replace back arrow with hamburger menu icon
|
||||
*/
|
||||
protected void setTitle(final String title, Boolean showBackAsMenu) {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
if (getActivity() != null) {
|
||||
final ActionBar actionBar = ((FileDisplayActivity) getActivity()).getSupportActionBar();
|
||||
final Context context = getContext();
|
||||
|
||||
if (actionBar != null && context != null) {
|
||||
viewThemeUtils.files.themeActionBar(context, actionBar, title, true);
|
||||
viewThemeUtils.files.themeActionBar(context, actionBar, title, showBackAsMenu);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -375,11 +375,11 @@ public class PreviewImageFragment extends FileFragment implements Injectable {
|
|||
Arrays.asList(
|
||||
R.id.action_rename_file,
|
||||
R.id.action_sync_file,
|
||||
R.id.action_select_all,
|
||||
R.id.action_move,
|
||||
R.id.action_copy,
|
||||
R.id.action_favorite,
|
||||
R.id.action_unset_favorite
|
||||
R.id.action_unset_favorite,
|
||||
R.id.action_pin_to_homescreen
|
||||
));
|
||||
if (getFile() != null && getFile().isSharedWithMe() && !getFile().canReshare()) {
|
||||
additionalFilter.add(R.id.action_send_share_file);
|
||||
|
|
|
@ -424,7 +424,6 @@ public class PreviewMediaFragment extends FileFragment implements OnTouchListene
|
|||
Arrays.asList(
|
||||
R.id.action_rename_file,
|
||||
R.id.action_sync_file,
|
||||
R.id.action_select_all,
|
||||
R.id.action_move,
|
||||
R.id.action_copy,
|
||||
R.id.action_favorite,
|
||||
|
|
|
@ -300,11 +300,11 @@ public class PreviewTextFileFragment extends PreviewTextFragment {
|
|||
Arrays.asList(
|
||||
R.id.action_rename_file,
|
||||
R.id.action_sync_file,
|
||||
R.id.action_select_all,
|
||||
R.id.action_move,
|
||||
R.id.action_copy,
|
||||
R.id.action_favorite,
|
||||
R.id.action_unset_favorite
|
||||
R.id.action_unset_favorite,
|
||||
R.id.action_pin_to_homescreen
|
||||
));
|
||||
if (getFile() != null && getFile().isSharedWithMe() && !getFile().canReshare()) {
|
||||
additionalFilter.add(R.id.action_send_share_file);
|
||||
|
|
|
@ -20,10 +20,8 @@
|
|||
package com.owncloud.android.ui.preview;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.Html;
|
||||
|
@ -195,10 +193,7 @@ public abstract class PreviewTextFragment extends FileFragment implements Search
|
|||
|
||||
@Override
|
||||
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
||||
builder.linkResolver((view, link) -> {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, activity, R.string.no_browser_available);
|
||||
});
|
||||
builder.linkResolver((view, link) -> DisplayUtils.startLinkIntent(activity, link));
|
||||
}
|
||||
})
|
||||
.usePlugin(TablePlugin.create(activity))
|
||||
|
|
|
@ -150,6 +150,9 @@ class PreviewVideoFullscreenDialog(
|
|||
}
|
||||
mExoPlayer.addListener(playListener)
|
||||
playingStateListener = playListener
|
||||
|
||||
// Run once to set initial state of play or pause buttons
|
||||
playListener.onIsPlayingChanged(sourceExoPlayer.isPlaying)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
|
|
|
@ -775,13 +775,15 @@ public final class DisplayUtils {
|
|||
startLinkIntent(activity, activity.getString(link));
|
||||
}
|
||||
|
||||
static public void startLinkIntent(Activity activity, Uri url) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, url);
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, activity, R.string.no_browser_available);
|
||||
static public void startLinkIntent(Activity activity, String url) {
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
startLinkIntent(activity, Uri.parse(url));
|
||||
}
|
||||
}
|
||||
|
||||
static public void startLinkIntent(Activity activity, String url) {
|
||||
startLinkIntent(activity, Uri.parse(url));
|
||||
static public void startLinkIntent(Activity activity, Uri uri) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
DisplayUtils.startIntentIfAppAvailable(intent, activity, R.string.no_browser_available);
|
||||
}
|
||||
|
||||
static public void startIntentIfAppAvailable(Intent intent, Activity activity, @StringRes int error) {
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/bg_default"
|
||||
android:divider="@color/transparent"
|
||||
android:dividerHeight="0dip"
|
||||
android:nestedScrollingEnabled="true"
|
||||
|
@ -58,6 +59,7 @@
|
|||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/bg_default"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:padding="@dimen/standard_padding">
|
||||
|
|
|
@ -36,5 +36,6 @@
|
|||
android:icon="@drawable/ic_action_create_dir"
|
||||
android:orderInCategory="1"
|
||||
android:title="@string/actionbar_mkdir"
|
||||
app:showAsAction="never" />
|
||||
app:iconTint="?attr/colorOnSurface"
|
||||
app:showAsAction="ifRoom"/>
|
||||
</menu>
|
||||
|
|
|
@ -39,13 +39,7 @@
|
|||
android:icon="@drawable/ic_action_create_dir"
|
||||
android:orderInCategory="1"
|
||||
android:title="@string/actionbar_mkdir"
|
||||
app:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_select_all"
|
||||
android:contentDescription="@string/select_all"
|
||||
android:icon="@drawable/ic_select_all"
|
||||
android:orderInCategory="1"
|
||||
android:title="@string/select_all"
|
||||
app:iconTint="?attr/colorOnSurface"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
|
|
|
@ -17,7 +17,7 @@ buildscript {
|
|||
fidoVersion = "4.1.0-patch1"
|
||||
checkerVersion = "3.21.2"
|
||||
exoplayerVersion = "2.19.0"
|
||||
documentScannerVersion = "1.0.1"
|
||||
documentScannerVersion = "1.1.1"
|
||||
roomVersion = "2.5.2"
|
||||
|
||||
ciBuild = System.getenv("CI") == "true"
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
DO NOT TOUCH; GENERATED BY DRONE
|
||||
<span class="mdl-layout-title">Lint Report: 77 warnings</span>
|
||||
<span class="mdl-layout-title">Lint Report: 79 warnings</span>
|
||||
|
|
Loading…
Reference in a new issue