Merge remote-tracking branch 'origin/master' into dev

This commit is contained in:
Tobias Kaminsky 2023-07-29 02:31:13 +02:00
commit 24f96857b3
30 changed files with 230 additions and 161 deletions

View file

@ -69,7 +69,7 @@ complexity:
excludes: ['**/androidTest/**']
LongParameterList:
active: true
functionThreshold: 6
functionThreshold: 7
constructorThreshold: 6
ignoreDefaultParameters: false
MethodOverloading:

View file

@ -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);
}
}

View file

@ -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

View file

@ -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)
}
}

View file

@ -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()
}

View file

@ -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);

View file

@ -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())

View file

@ -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!!
}

View file

@ -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);

View file

@ -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()) {

View file

@ -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());

View file

@ -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 {

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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();

View file

@ -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));

View file

@ -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);

View 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);
}
}
});

View file

@ -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);

View 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,

View file

@ -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);

View 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))

View file

@ -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() {

View file

@ -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) {

View file

@ -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">

View file

@ -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>

View file

@ -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>

View file

@ -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"

View file

@ -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>