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
3de6dfb9a6
24 changed files with 452 additions and 316 deletions
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.files
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2020 Chris Narkiewicz <hello@ezaquarii.com>
|
||||
* SPDX-FileCopyrightText: 2019 Tobias Kaminsky
|
||||
* SPDX-FileCopyrightText: 2019 Tobias Kaminsky <tobias@kaminsky.me>
|
||||
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Jonas Mayer <jonas.mayer@nextcloud.com>
|
||||
* SPDX-FileCopyrightText: 2020 Chris Narkiewicz <hello@ezaquarii.com>
|
||||
* SPDX-FileCopyrightText: 2017 Mario Danic <mario@lovelyhq.com>
|
||||
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH
|
||||
|
@ -64,7 +65,7 @@ class FilesSyncWork(
|
|||
|
||||
private lateinit var syncedFolder: SyncedFolder
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
@Suppress("MagicNumber", "ReturnCount")
|
||||
override fun doWork(): Result {
|
||||
val syncFolderId = inputData.getLong(SYNCED_FOLDER_ID, -1)
|
||||
val changedFiles = inputData.getStringArray(CHANGED_FILES)
|
||||
|
@ -72,25 +73,39 @@ class FilesSyncWork(
|
|||
backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class) + "_" + syncFolderId)
|
||||
Log_OC.d(TAG, "File-sync worker started for folder ID: $syncFolderId")
|
||||
|
||||
if (canExitEarly(changedFiles, syncFolderId)) {
|
||||
val result = Result.success()
|
||||
backgroundJobManager.logEndOfWorker(
|
||||
BackgroundJobManagerImpl.formatClassTag(this::class) +
|
||||
"_" + syncFolderId,
|
||||
result
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
// Create all the providers we'll need
|
||||
val resources = context.resources
|
||||
val lightVersion = resources.getBoolean(R.bool.syncedFolder_light)
|
||||
FilesSyncHelper.restartUploadsIfNeeded(
|
||||
uploadsStorageManager,
|
||||
userAccountManager,
|
||||
connectivityService,
|
||||
powerManagementService
|
||||
val filesystemDataProvider = FilesystemDataProvider(contentResolver)
|
||||
val currentLocale = resources.configuration.locale
|
||||
val dateFormat = SimpleDateFormat("yyyy:MM:dd HH:mm:ss", currentLocale)
|
||||
dateFormat.timeZone = TimeZone.getTimeZone(TimeZone.getDefault().id)
|
||||
|
||||
if (!setSyncedFolder(syncFolderId)) {
|
||||
Log_OC.d(TAG, "File-sync kill worker since syncedFolder ($syncFolderId) is not enabled!")
|
||||
return logEndOfWorker(syncFolderId)
|
||||
}
|
||||
|
||||
// Always first try to schedule uploads to make sure files are uploaded even if worker was killed to early
|
||||
uploadFilesFromFolder(
|
||||
context,
|
||||
resources,
|
||||
lightVersion,
|
||||
filesystemDataProvider,
|
||||
currentLocale,
|
||||
dateFormat,
|
||||
syncedFolder
|
||||
)
|
||||
|
||||
if (canExitEarly(changedFiles, syncFolderId)) {
|
||||
return logEndOfWorker(syncFolderId)
|
||||
}
|
||||
|
||||
val user = userAccountManager.getUser(syncedFolder.account)
|
||||
if (user.isPresent) {
|
||||
backgroundJobManager.startFilesUploadJob(user.get())
|
||||
}
|
||||
|
||||
// Get changed files from ContentObserverWork (only images and videos) or by scanning filesystem
|
||||
Log_OC.d(
|
||||
TAG,
|
||||
|
@ -100,13 +115,7 @@ class FilesSyncWork(
|
|||
collectChangedFiles(changedFiles)
|
||||
Log_OC.d(TAG, "File-sync worker (${syncedFolder.remotePath}) finished checking files.")
|
||||
|
||||
// Create all the providers we'll need
|
||||
val filesystemDataProvider = FilesystemDataProvider(contentResolver)
|
||||
val currentLocale = resources.configuration.locale
|
||||
val dateFormat = SimpleDateFormat("yyyy:MM:dd HH:mm:ss", currentLocale)
|
||||
dateFormat.timeZone = TimeZone.getTimeZone(TimeZone.getDefault().id)
|
||||
|
||||
syncFolder(
|
||||
uploadFilesFromFolder(
|
||||
context,
|
||||
resources,
|
||||
lightVersion,
|
||||
|
@ -116,6 +125,17 @@ class FilesSyncWork(
|
|||
syncedFolder
|
||||
)
|
||||
|
||||
FilesSyncHelper.restartUploadsIfNeeded(
|
||||
uploadsStorageManager,
|
||||
userAccountManager,
|
||||
connectivityService,
|
||||
powerManagementService
|
||||
)
|
||||
|
||||
return logEndOfWorker(syncFolderId)
|
||||
}
|
||||
|
||||
private fun logEndOfWorker(syncFolderId: Long): Result {
|
||||
Log_OC.d(TAG, "File-sync worker (${syncedFolder.remotePath}) finished")
|
||||
val result = Result.success()
|
||||
backgroundJobManager.logEndOfWorker(
|
||||
|
@ -140,6 +160,7 @@ class FilesSyncWork(
|
|||
// If we are in power save mode better to postpone scan and upload
|
||||
val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false)
|
||||
if ((powerManagementService.isPowerSavingEnabled && !overridePowerSaving)) {
|
||||
Log_OC.d(TAG, "File-sync kill worker since powerSaving is enabled!")
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -148,9 +169,8 @@ class FilesSyncWork(
|
|||
return true
|
||||
}
|
||||
|
||||
// or sync worker already running and no changed files to be processed
|
||||
val alreadyRunning = backgroundJobManager.bothFilesSyncJobsRunning(syncedFolderID)
|
||||
if (alreadyRunning && changedFiles.isNullOrEmpty()) {
|
||||
// or sync worker already running
|
||||
if (backgroundJobManager.bothFilesSyncJobsRunning(syncedFolderID)) {
|
||||
Log_OC.d(
|
||||
TAG,
|
||||
"File-sync kill worker since another instance of the worker " +
|
||||
|
@ -159,8 +179,17 @@ class FilesSyncWork(
|
|||
return true
|
||||
}
|
||||
|
||||
if (!setSyncedFolder(syncedFolderID)) {
|
||||
Log_OC.d(TAG, "File-sync kill worker since syncedFolder ($syncedFolderID) is not enabled!")
|
||||
val passedScanInterval = (
|
||||
syncedFolder.lastScanTimestampMs +
|
||||
FilesSyncHelper.calculateScanInterval(syncedFolder, connectivityService, powerManagementService)
|
||||
) <= System.currentTimeMillis()
|
||||
|
||||
if (!passedScanInterval && changedFiles.isNullOrEmpty() && !overridePowerSaving) {
|
||||
Log_OC.d(
|
||||
TAG,
|
||||
"File-sync kill worker since started before scan " +
|
||||
"Interval and nothing todo (${syncedFolder.localPath})!"
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -184,10 +213,12 @@ class FilesSyncWork(
|
|||
// filesystemDataProvider database (potentially needs a long time)
|
||||
FilesSyncHelper.insertAllDBEntriesForSyncedFolder(syncedFolder)
|
||||
}
|
||||
syncedFolder.lastScanTimestampMs = System.currentTimeMillis()
|
||||
syncedFolderProvider.updateSyncFolder(syncedFolder)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod") // legacy code
|
||||
private fun syncFolder(
|
||||
private fun uploadFilesFromFolder(
|
||||
context: Context,
|
||||
resources: Resources,
|
||||
lightVersion: Boolean,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Chris Narkiewicz <hello@ezaquarii.com>
|
||||
* SPDX-FileCopyrightText: 2018 Tobias Kaminsky
|
||||
* SPDX-FileCopyrightText: 2018 Tobias Kaminsky <tobias@kaminsky.me>
|
||||
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
*/
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.ui.adapter
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.ui.dialog
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.ui.events
|
||||
|
||||
|
|
|
@ -407,14 +407,19 @@ public class GalleryFragment extends OCFileListFragment implements GalleryFragme
|
|||
|
||||
private void updateSubtitle(GalleryFragmentBottomSheetDialog.MediaState mediaState) {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
String subTitle = requireContext().getResources().getString(R.string.subtitle_photos_videos);
|
||||
if (mediaState == GalleryFragmentBottomSheetDialog.MediaState.MEDIA_STATE_PHOTOS_ONLY) {
|
||||
subTitle = requireContext().getResources().getString(R.string.subtitle_photos_only);
|
||||
} else if (mediaState == GalleryFragmentBottomSheetDialog.MediaState.MEDIA_STATE_VIDEOS_ONLY) {
|
||||
subTitle = requireContext().getResources().getString(R.string.subtitle_videos_only);
|
||||
if (!isAdded()) {
|
||||
return;
|
||||
}
|
||||
if (requireActivity() instanceof ToolbarActivity) {
|
||||
((ToolbarActivity) requireActivity()).updateToolbarSubtitle(subTitle);
|
||||
|
||||
String subTitle = getResources().getString(R.string.subtitle_photos_videos);
|
||||
if (mediaState == GalleryFragmentBottomSheetDialog.MediaState.MEDIA_STATE_PHOTOS_ONLY) {
|
||||
subTitle = getResources().getString(R.string.subtitle_photos_only);
|
||||
} else if (mediaState == GalleryFragmentBottomSheetDialog.MediaState.MEDIA_STATE_VIDEOS_ONLY) {
|
||||
subTitle = getResources().getString(R.string.subtitle_videos_only);
|
||||
}
|
||||
|
||||
if (requireActivity() instanceof ToolbarActivity toolbarActivity) {
|
||||
toolbarActivity.updateToolbarSubtitle(subTitle);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.ui.fragment
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.ui.preview
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import android.widget.FrameLayout;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.nextcloud.client.account.User;
|
||||
import com.nextcloud.client.account.UserAccountManager;
|
||||
import com.nextcloud.ui.fileactions.FileActionsBottomSheet;
|
||||
import com.nextcloud.utils.extensions.BundleExtensionsKt;
|
||||
import com.nextcloud.utils.extensions.FileExtensionsKt;
|
||||
|
@ -29,7 +28,6 @@ import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
|
|||
import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils;
|
||||
|
||||
import org.mozilla.universalchardet.ReaderFactory;
|
||||
|
||||
|
@ -45,8 +43,6 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
|
@ -64,9 +60,6 @@ public class PreviewTextFileFragment extends PreviewTextFragment {
|
|||
private TextLoadAsyncTask textLoadAsyncTask;
|
||||
private User user;
|
||||
|
||||
@Inject UserAccountManager accountManager;
|
||||
@Inject ViewThemeUtils viewThemeUtils;
|
||||
|
||||
public static PreviewTextFileFragment create(User user, OCFile file, boolean openSearch, String searchQuery) {
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_FILE, file);
|
||||
|
@ -144,7 +137,7 @@ public class PreviewTextFileFragment extends PreviewTextFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
void loadAndShowTextPreview() {
|
||||
public void loadAndShowTextPreview() {
|
||||
textLoadAsyncTask = new TextLoadAsyncTask(new WeakReference<>(binding.textPreview),
|
||||
new WeakReference<>(binding.emptyListProgress));
|
||||
textLoadAsyncTask.execute(getFile().getStoragePath());
|
||||
|
@ -228,7 +221,7 @@ public class PreviewTextFileFragment extends PreviewTextFragment {
|
|||
if (searchView != null) {
|
||||
searchView.setOnQueryTextListener(PreviewTextFileFragment.this);
|
||||
|
||||
if (searchOpen) {
|
||||
if (searchOpen && searchView != null) {
|
||||
searchView.setQuery(searchQuery, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,229 +0,0 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019-2022 Tobias Kaminsky <tobias@kaminsky.me>
|
||||
* SPDX-FileCopyrightText: 2019-2022 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
* SPDX-FileCopyrightText: 2019 Chris Narkiewicz <hello@ezaquarii.com>
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud Inc.
|
||||
* SPDX-FileCopyrightText: 2014 Jorge Antonio Diaz-Benito Soriano <jorge.diazbenitosoriano@gmail.com>
|
||||
* SPDX-License-Identifier: GPL-2.0-only AND (AGPL-3.0-or-later OR GPL-2.0-only)
|
||||
*/
|
||||
package com.owncloud.android.ui.preview;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.nextcloud.client.account.UserAccountManager;
|
||||
import com.nextcloud.client.device.DeviceInfo;
|
||||
import com.nextcloud.client.di.Injectable;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.TextFilePreviewBinding;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
||||
import com.owncloud.android.ui.fragment.FileFragment;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
import com.owncloud.android.utils.StringUtils;
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||
import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.MarkwonConfiguration;
|
||||
import io.noties.markwon.core.MarkwonTheme;
|
||||
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
|
||||
import io.noties.markwon.ext.tables.TablePlugin;
|
||||
import io.noties.markwon.ext.tasklist.TaskListDrawable;
|
||||
import io.noties.markwon.ext.tasklist.TaskListPlugin;
|
||||
import io.noties.markwon.html.HtmlPlugin;
|
||||
import io.noties.markwon.syntax.Prism4jTheme;
|
||||
import io.noties.markwon.syntax.Prism4jThemeDefault;
|
||||
import io.noties.markwon.syntax.SyntaxHighlightPlugin;
|
||||
import io.noties.prism4j.Prism4j;
|
||||
import io.noties.prism4j.annotations.PrismBundle;
|
||||
|
||||
@PrismBundle(
|
||||
include = {
|
||||
"c", "clike", "clojure", "cpp", "csharp", "css", "dart", "git", "go", "groovy", "java", "javascript", "json",
|
||||
"kotlin", "latex", "makefile", "markdown", "markup", "python", "scala", "sql", "swift", "yaml"
|
||||
},
|
||||
grammarLocatorClassName = ".MarkwonGrammarLocator"
|
||||
)
|
||||
public abstract class PreviewTextFragment extends FileFragment implements SearchView.OnQueryTextListener, Injectable {
|
||||
private static final String TAG = PreviewTextFragment.class.getSimpleName();
|
||||
|
||||
protected SearchView searchView;
|
||||
protected String searchQuery = "";
|
||||
protected boolean searchOpen;
|
||||
protected Handler handler;
|
||||
protected String originalText;
|
||||
|
||||
@Inject UserAccountManager accountManager;
|
||||
@Inject DeviceInfo deviceInfo;
|
||||
@Inject ViewThemeUtils viewThemeUtils;
|
||||
|
||||
protected TextFilePreviewBinding binding;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
Log_OC.e(TAG, "onCreateView");
|
||||
|
||||
binding = TextFilePreviewBinding.inflate(inflater, container, false);
|
||||
View view = binding.getRoot();
|
||||
|
||||
binding.emptyListProgress.setVisibility(View.VISIBLE);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
Log_OC.e(TAG, "onStart");
|
||||
|
||||
loadAndShowTextPreview();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
|
||||
abstract void loadAndShowTextPreview();
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
performSearch(query, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(final String newText) {
|
||||
performSearch(newText, 500);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void performSearch(final String query, int delay) {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
|
||||
if (originalText != null) {
|
||||
if (getActivity() instanceof FileDisplayActivity) {
|
||||
FileDisplayActivity fileDisplayActivity = (FileDisplayActivity) getActivity();
|
||||
fileDisplayActivity.setSearchQuery(query);
|
||||
}
|
||||
handler.postDelayed(() -> markText(query), delay);
|
||||
}
|
||||
|
||||
if (delay == 0 && searchView != null) {
|
||||
searchView.clearFocus();
|
||||
}
|
||||
}
|
||||
|
||||
private void markText(String query) {
|
||||
// called asynchronously - must check preconditions in case of UI detachment
|
||||
if (binding == null) {
|
||||
return;
|
||||
}
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
final Resources resources = activity.getResources();
|
||||
if (resources == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(query)) {
|
||||
String coloredText = StringUtils.searchAndColor(originalText,
|
||||
query,
|
||||
resources.getColor(R.color.primary));
|
||||
binding.textPreview.setText(Html.fromHtml(coloredText.replace("\n", "<br \\>")));
|
||||
} else {
|
||||
setText(binding.textPreview, originalText, getFile(), activity, false, false, viewThemeUtils);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Spanned getRenderedMarkdownText(Activity activity,
|
||||
String markdown,
|
||||
ViewThemeUtils viewThemeUtils) {
|
||||
Prism4j prism4j = new Prism4j(new MarkwonGrammarLocator());
|
||||
Prism4jTheme prism4jTheme = Prism4jThemeDefault.create();
|
||||
TaskListDrawable drawable = new TaskListDrawable(Color.GRAY, Color.GRAY, Color.WHITE);
|
||||
viewThemeUtils.platform.tintPrimaryDrawable(activity, drawable);
|
||||
|
||||
final Markwon markwon = Markwon.builder(activity)
|
||||
.usePlugin(new AbstractMarkwonPlugin() {
|
||||
@Override
|
||||
public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
|
||||
builder.linkColor(viewThemeUtils.platform.primaryColor(activity));
|
||||
builder.headingBreakHeight(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
||||
builder.linkResolver((view, link) -> DisplayUtils.startLinkIntent(activity, link));
|
||||
}
|
||||
})
|
||||
.usePlugin(TablePlugin.create(activity))
|
||||
.usePlugin(TaskListPlugin.create(drawable))
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(HtmlPlugin.create())
|
||||
.usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme))
|
||||
.build();
|
||||
|
||||
return markwon.toMarkdown(markdown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the preview
|
||||
*/
|
||||
protected void finish() {
|
||||
requireActivity().runOnUiThread(() -> requireActivity().onBackPressed());
|
||||
}
|
||||
|
||||
public static void setText(TextView textView,
|
||||
@Nullable String text,
|
||||
@Nullable OCFile file,
|
||||
Activity activity,
|
||||
boolean ignoreMimetype,
|
||||
boolean preview,
|
||||
ViewThemeUtils viewThemeUtils) {
|
||||
if (text == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ignoreMimetype || file != null && MimeTypeUtil.MIMETYPE_TEXT_MARKDOWN.equals(file.getMimeType()))
|
||||
&& activity != null) {
|
||||
if (!preview) {
|
||||
// clickable links prevent to open full view of rich workspace
|
||||
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
textView.setText(getRenderedMarkdownText(activity, text, viewThemeUtils));
|
||||
} else {
|
||||
textView.setText(text);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-FileCopyrightText: 2019-2022 Tobias Kaminsky <tobias@kaminsky.me>
|
||||
* SPDX-FileCopyrightText: 2019-2022 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
* SPDX-FileCopyrightText: 2019 Chris Narkiewicz <hello@ezaquarii.com>
|
||||
* SPDX-FileCopyrightText: 2016 ownCloud Inc.
|
||||
* SPDX-FileCopyrightText: 2014 Jorge Antonio Diaz-Benito Soriano <jorge.diazbenitosoriano@gmail.com>
|
||||
* SPDX-License-Identifier: GPL-2.0-only AND (AGPL-3.0-or-later OR GPL-2.0-only)
|
||||
*/
|
||||
package com.owncloud.android.ui.preview
|
||||
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.text.Spanned
|
||||
import android.text.TextUtils
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.nextcloud.android.common.ui.theme.utils.ColorRole
|
||||
import com.nextcloud.client.account.UserAccountManager
|
||||
import com.nextcloud.client.device.DeviceInfo
|
||||
import com.nextcloud.client.di.Injectable
|
||||
import com.nextcloud.utils.extensions.setHtmlContent
|
||||
import com.owncloud.android.MainApp
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.databinding.TextFilePreviewBinding
|
||||
import com.owncloud.android.datamodel.OCFile
|
||||
import com.owncloud.android.lib.common.utils.Log_OC
|
||||
import com.owncloud.android.ui.activity.FileDisplayActivity
|
||||
import com.owncloud.android.ui.fragment.FileFragment
|
||||
import com.owncloud.android.utils.DisplayUtils
|
||||
import com.owncloud.android.utils.MimeTypeUtil
|
||||
import com.owncloud.android.utils.StringUtils
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils
|
||||
import io.noties.markwon.AbstractMarkwonPlugin
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.MarkwonConfiguration
|
||||
import io.noties.markwon.core.MarkwonTheme
|
||||
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin
|
||||
import io.noties.markwon.ext.tables.TablePlugin
|
||||
import io.noties.markwon.ext.tasklist.TaskListDrawable
|
||||
import io.noties.markwon.ext.tasklist.TaskListPlugin
|
||||
import io.noties.markwon.html.HtmlPlugin
|
||||
import io.noties.markwon.syntax.Prism4jTheme
|
||||
import io.noties.markwon.syntax.Prism4jThemeDefault
|
||||
import io.noties.markwon.syntax.SyntaxHighlightPlugin
|
||||
import io.noties.prism4j.Prism4j
|
||||
import io.noties.prism4j.annotations.PrismBundle
|
||||
import javax.inject.Inject
|
||||
|
||||
@PrismBundle(
|
||||
include = [
|
||||
"c", "clike", "clojure", "cpp", "csharp", "css", "dart", "git", "go", "groovy", "java",
|
||||
"javascript", "json", "kotlin", "latex", "makefile", "markdown", "markup", "python", "scala",
|
||||
"sql", "swift", "yaml"
|
||||
],
|
||||
grammarLocatorClassName = ".MarkwonGrammarLocator"
|
||||
)
|
||||
abstract class PreviewTextFragment : FileFragment(), SearchView.OnQueryTextListener, Injectable {
|
||||
|
||||
@JvmField
|
||||
protected var searchView: SearchView? = null
|
||||
|
||||
@JvmField
|
||||
protected var searchQuery: String = ""
|
||||
|
||||
@JvmField
|
||||
protected var searchOpen: Boolean = false
|
||||
|
||||
@JvmField
|
||||
protected var handler: Handler? = null
|
||||
|
||||
@JvmField
|
||||
protected var originalText: String? = null
|
||||
|
||||
@Inject
|
||||
lateinit var accountManager: UserAccountManager
|
||||
|
||||
@Inject
|
||||
lateinit var deviceInfo: DeviceInfo
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
protected lateinit var binding: TextFilePreviewBinding
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
Log_OC.e(TAG, "onCreateView")
|
||||
|
||||
binding = TextFilePreviewBinding.inflate(inflater, container, false)
|
||||
|
||||
binding.emptyListProgress.visibility = View.VISIBLE
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
Log_OC.e(TAG, "onStart")
|
||||
|
||||
loadAndShowTextPreview()
|
||||
}
|
||||
|
||||
abstract fun loadAndShowTextPreview()
|
||||
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
performSearch(query, 0)
|
||||
return true
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
override fun onQueryTextChange(newText: String): Boolean {
|
||||
performSearch(newText, 500)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun performSearch(query: String, delay: Int) {
|
||||
handler?.removeCallbacksAndMessages(null)
|
||||
|
||||
if (originalText != null) {
|
||||
if (activity is FileDisplayActivity) {
|
||||
val fileDisplayActivity = activity as FileDisplayActivity?
|
||||
fileDisplayActivity?.setSearchQuery(query)
|
||||
}
|
||||
handler?.postDelayed({ markText(query) }, delay.toLong())
|
||||
}
|
||||
|
||||
if (delay == 0 && searchView != null) {
|
||||
searchView?.clearFocus()
|
||||
}
|
||||
}
|
||||
|
||||
private fun markText(query: String) {
|
||||
if (!TextUtils.isEmpty(query)) {
|
||||
val coloredText = StringUtils.searchAndColor(
|
||||
originalText,
|
||||
query,
|
||||
ContextCompat.getColor(requireContext(), R.color.primary)
|
||||
)
|
||||
|
||||
binding.textPreview.setHtmlContent(coloredText.replace("\n", "<br \\>"))
|
||||
} else {
|
||||
val activity = activity ?: return
|
||||
setText(binding.textPreview, originalText, file, activity, false, false, viewThemeUtils)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the preview
|
||||
*/
|
||||
protected fun finish() {
|
||||
requireActivity().runOnUiThread { requireActivity().onBackPressed() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG: String = PreviewTextFragment::class.java.simpleName
|
||||
|
||||
protected fun getRenderedMarkdownText(
|
||||
activity: Activity?,
|
||||
markdown: String?,
|
||||
viewThemeUtils: ViewThemeUtils?
|
||||
): Spanned {
|
||||
val prism4j = Prism4j(MarkwonGrammarLocator())
|
||||
val prism4jTheme: Prism4jTheme = Prism4jThemeDefault.create()
|
||||
val drawable = TaskListDrawable(Color.GRAY, Color.GRAY, Color.WHITE)
|
||||
|
||||
if (activity == null || markdown == null) {
|
||||
return Markwon.builder(MainApp.getAppContext()).build().toMarkdown(markdown ?: "")
|
||||
}
|
||||
|
||||
viewThemeUtils?.platform?.tintDrawable(activity, drawable, ColorRole.PRIMARY)
|
||||
|
||||
val markwon = Markwon.builder(activity)
|
||||
.usePlugin(object : AbstractMarkwonPlugin() {
|
||||
override fun configureTheme(builder: MarkwonTheme.Builder) {
|
||||
val linkColor = viewThemeUtils?.platform?.primaryColor(activity)
|
||||
linkColor?.let {
|
||||
builder.linkColor(it)
|
||||
}
|
||||
|
||||
builder.headingBreakHeight(0)
|
||||
}
|
||||
|
||||
override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
|
||||
builder.linkResolver { _: View?, link: String? ->
|
||||
DisplayUtils.startLinkIntent(
|
||||
activity,
|
||||
link
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
.usePlugin(TablePlugin.create(activity))
|
||||
.usePlugin(TaskListPlugin.create(drawable))
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(HtmlPlugin.create())
|
||||
.usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme))
|
||||
.build()
|
||||
|
||||
return markwon.toMarkdown(markdown)
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList", "ComplexCondition")
|
||||
@JvmStatic
|
||||
fun setText(
|
||||
textView: TextView,
|
||||
text: String?,
|
||||
file: OCFile?,
|
||||
activity: Activity?,
|
||||
ignoreMimetype: Boolean,
|
||||
preview: Boolean,
|
||||
viewThemeUtils: ViewThemeUtils?
|
||||
) {
|
||||
if (text == null) {
|
||||
return
|
||||
}
|
||||
|
||||
if ((ignoreMimetype || file != null && MimeTypeUtil.MIMETYPE_TEXT_MARKDOWN == file.mimeType) &&
|
||||
activity != null
|
||||
) {
|
||||
if (!preview) {
|
||||
// clickable links prevent to open full view of rich workspace
|
||||
textView.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
textView.text = getRenderedMarkdownText(activity, text, viewThemeUtils)
|
||||
} else {
|
||||
textView.text = text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,15 +18,11 @@ import android.view.ViewGroup;
|
|||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.nextcloud.android.lib.richWorkspace.RichWorkspaceDirectEditingRemoteOperation;
|
||||
import com.nextcloud.client.account.UserAccountManager;
|
||||
import com.nextcloud.utils.extensions.FileExtensionsKt;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
|
@ -35,9 +31,6 @@ import androidx.core.view.MenuItemCompat;
|
|||
public class PreviewTextStringFragment extends PreviewTextFragment {
|
||||
private static final String EXTRA_FILE = "FILE";
|
||||
|
||||
@Inject UserAccountManager accountManager;
|
||||
@Inject ViewThemeUtils viewThemeUtils;
|
||||
|
||||
private final static String TAG = "PreviewTextStringFragment";
|
||||
private boolean isEditorWebviewLaunched = false;
|
||||
|
||||
|
@ -128,7 +121,7 @@ public class PreviewTextStringFragment extends PreviewTextFragment {
|
|||
}
|
||||
}
|
||||
|
||||
void loadAndShowTextPreview() {
|
||||
public void loadAndShowTextPreview() {
|
||||
originalText = getFile().getRichWorkspace();
|
||||
setText(binding.textPreview, originalText, getFile(), requireActivity(), true, false, viewThemeUtils);
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.ui.preview.pdf
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.ui.preview.pdf
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.ui.preview.pdf
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Jonas Mayer <jonas.mayer@nextcloud.com>
|
||||
* SPDX-FileCopyrightText: 2020 Chris Narkiewicz <hello@ezaquarii.com>
|
||||
* SPDX-FileCopyrightText: 2017 Mario Danic <mario@lovelyhq.com>
|
||||
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH
|
||||
|
@ -17,6 +18,7 @@ import android.provider.MediaStore;
|
|||
import com.nextcloud.client.account.UserAccountManager;
|
||||
import com.nextcloud.client.device.PowerManagementService;
|
||||
import com.nextcloud.client.jobs.BackgroundJobManager;
|
||||
import com.nextcloud.client.jobs.BackgroundJobManagerImpl;
|
||||
import com.nextcloud.client.jobs.upload.FileUploadHelper;
|
||||
import com.nextcloud.client.network.ConnectivityService;
|
||||
import com.owncloud.android.MainApp;
|
||||
|
@ -27,15 +29,20 @@ import com.owncloud.android.datamodel.SyncedFolderProvider;
|
|||
import com.owncloud.android.datamodel.UploadsStorageManager;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import org.lukhnos.nnio.file.AccessDeniedException;
|
||||
import org.lukhnos.nnio.file.FileVisitResult;
|
||||
import org.lukhnos.nnio.file.FileVisitor;
|
||||
import org.lukhnos.nnio.file.Path;
|
||||
import org.lukhnos.nnio.file.Paths;
|
||||
import org.lukhnos.nnio.file.SimpleFileVisitor;
|
||||
import org.lukhnos.nnio.file.attribute.BasicFileAttributes;
|
||||
import org.lukhnos.nnio.file.Files;
|
||||
import org.lukhnos.nnio.file.impl.FileBasedPathImpl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR;
|
||||
|
||||
|
@ -51,16 +58,50 @@ public final class FilesSyncHelper {
|
|||
// utility class -> private constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy of {@link Files#walkFileTree(Path, FileVisitor)} that walks the file tree in random order.
|
||||
*
|
||||
* @see org.lukhnos.nnio.file.Files#walkFileTree(Path, FileVisitor)
|
||||
*/
|
||||
public static void walkFileTreeRandomly(Path start, FileVisitor<? super Path> visitor) throws IOException {
|
||||
File file = start.toFile();
|
||||
if (!file.canRead()) {
|
||||
visitor.visitFileFailed(start, new AccessDeniedException(file.toString()));
|
||||
} else {
|
||||
if (Files.isDirectory(start)) {
|
||||
FileVisitResult preVisitDirectoryResult = visitor.preVisitDirectory(start, (BasicFileAttributes)null);
|
||||
if (preVisitDirectoryResult == FileVisitResult.CONTINUE) {
|
||||
File[] children = start.toFile().listFiles();
|
||||
Collections.shuffle(Arrays.asList(children));
|
||||
if (children != null) {
|
||||
File[] var5 = children;
|
||||
int var6 = children.length;
|
||||
|
||||
for(int var7 = 0; var7 < var6; ++var7) {
|
||||
File child = var5[var7];
|
||||
walkFileTreeRandomly(FileBasedPathImpl.get(child), visitor);
|
||||
}
|
||||
|
||||
visitor.postVisitDirectory(start, (IOException)null);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
visitor.visitFile(start, new BasicFileAttributes(file));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void insertCustomFolderIntoDB(Path path,
|
||||
SyncedFolder syncedFolder,
|
||||
FilesystemDataProvider filesystemDataProvider,
|
||||
long lastCheck,
|
||||
long thisCheck) {
|
||||
long lastCheck) {
|
||||
|
||||
final long enabledTimestampMs = syncedFolder.getEnabledTimestampMs();
|
||||
|
||||
try {
|
||||
Files.walkFileTree(path, new SimpleFileVisitor<>() {
|
||||
|
||||
walkFileTreeRandomly(path, new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
|
||||
File file = path.toFile();
|
||||
|
@ -98,7 +139,6 @@ public final class FilesSyncHelper {
|
|||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
syncedFolder.setLastScanTimestampMs(thisCheck);
|
||||
} catch (IOException e) {
|
||||
Log_OC.e(TAG, "Something went wrong while indexing files for auto upload", e);
|
||||
}
|
||||
|
@ -113,7 +153,6 @@ public final class FilesSyncHelper {
|
|||
if (syncedFolder.isEnabled() && (syncedFolder.isExisting() || enabledTimestampMs >= 0)) {
|
||||
MediaFolderType mediaType = syncedFolder.getType();
|
||||
final long lastCheckTimestampMs = syncedFolder.getLastScanTimestampMs();
|
||||
final long thisCheckTimestampMs = System.currentTimeMillis();
|
||||
|
||||
Log_OC.d(TAG,"File-sync start check folder "+syncedFolder.getLocalPath());
|
||||
long startTime = System.nanoTime();
|
||||
|
@ -121,21 +160,21 @@ public final class FilesSyncHelper {
|
|||
if (mediaType == MediaFolderType.IMAGE) {
|
||||
FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
|
||||
syncedFolder,
|
||||
lastCheckTimestampMs, thisCheckTimestampMs);
|
||||
lastCheckTimestampMs);
|
||||
FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||
syncedFolder,
|
||||
lastCheckTimestampMs, thisCheckTimestampMs);
|
||||
lastCheckTimestampMs);
|
||||
} else if (mediaType == MediaFolderType.VIDEO) {
|
||||
FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.INTERNAL_CONTENT_URI,
|
||||
syncedFolder,
|
||||
lastCheckTimestampMs, thisCheckTimestampMs);
|
||||
lastCheckTimestampMs);
|
||||
FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
||||
syncedFolder,
|
||||
lastCheckTimestampMs, thisCheckTimestampMs);
|
||||
lastCheckTimestampMs);
|
||||
} else {
|
||||
FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver);
|
||||
Path path = Paths.get(syncedFolder.getLocalPath());
|
||||
FilesSyncHelper.insertCustomFolderIntoDB(path, syncedFolder, filesystemDataProvider, lastCheckTimestampMs, thisCheckTimestampMs);
|
||||
FilesSyncHelper.insertCustomFolderIntoDB(path, syncedFolder, filesystemDataProvider, lastCheckTimestampMs);
|
||||
}
|
||||
|
||||
Log_OC.d(TAG,"File-sync finished full check for custom folder "+syncedFolder.getLocalPath()+" within "+(System.nanoTime() - startTime)+ "ns");
|
||||
|
@ -177,7 +216,7 @@ public final class FilesSyncHelper {
|
|||
}
|
||||
|
||||
private static void insertContentIntoDB(Uri uri, SyncedFolder syncedFolder,
|
||||
long lastCheckTimestampMs, long thisCheckTimestampMs) {
|
||||
long lastCheckTimestampMs) {
|
||||
final Context context = MainApp.getAppContext();
|
||||
final ContentResolver contentResolver = context.getContentResolver();
|
||||
|
||||
|
@ -224,7 +263,6 @@ public final class FilesSyncHelper {
|
|||
}
|
||||
}
|
||||
cursor.close();
|
||||
syncedFolder.setLastScanTimestampMs(thisCheckTimestampMs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,5 +298,34 @@ public final class FilesSyncHelper {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static long calculateScanInterval(
|
||||
SyncedFolder syncedFolder,
|
||||
ConnectivityService connectivityService,
|
||||
PowerManagementService powerManagementService
|
||||
) {
|
||||
long defaultInterval = BackgroundJobManagerImpl.DEFAULT_PERIODIC_JOB_INTERVAL_MINUTES * 1000 * 60;
|
||||
if (!connectivityService.isConnected() || connectivityService.isInternetWalled()) {
|
||||
return defaultInterval * 2;
|
||||
}
|
||||
|
||||
if ((syncedFolder.isWifiOnly() && !connectivityService.getConnectivity().isWifi())) {
|
||||
return defaultInterval * 4;
|
||||
}
|
||||
|
||||
if (powerManagementService.getBattery().getLevel() < 80){
|
||||
return defaultInterval * 2;
|
||||
}
|
||||
|
||||
if (powerManagementService.getBattery().getLevel() < 50){
|
||||
return defaultInterval * 4;
|
||||
}
|
||||
|
||||
if (powerManagementService.getBattery().getLevel() < 20){
|
||||
return defaultInterval * 8;
|
||||
}
|
||||
|
||||
return defaultInterval;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -516,6 +516,7 @@
|
|||
|
||||
قد تستغرق هذه العملية بعض الوقت.</string>
|
||||
<string name="manage_space_title">إدارة المساحة</string>
|
||||
<string name="max_file_count_warning_message">تجاوزت الحد الأقصى المسموح به لزمن رفع الملفات. رجاءً، لا تقم برفع عدد يزيد عن 500 ملف في كل مرة.</string>
|
||||
<string name="media_err_invalid_progressive_playback">ملف الوسائط لا يمكن بثه</string>
|
||||
<string name="media_err_io">تعذرت قراءة ملف الوسائط</string>
|
||||
<string name="media_err_malformed">يحتوي ملف الوسائط على ترميز غير صحيح</string>
|
||||
|
@ -670,8 +671,11 @@
|
|||
<string name="prefs_value_theme_light">فاتح</string>
|
||||
<string name="prefs_value_theme_system">اتبع النظام</string>
|
||||
<string name="preview_image_description">معاينة الصورة</string>
|
||||
<string name="preview_image_downloading_image_for_edit">جارٍ تنزيل الصورة لبدء شاشة التعديل، يرجى الانتظار...</string>
|
||||
<string name="preview_image_error_no_local_file">لا يوجد ملف محلي للمعاينة</string>
|
||||
<string name="preview_image_error_unknown_format">تعذرت عملية عرض الصورة</string>
|
||||
<string name="preview_image_file_is_not_downloaded">لم يتم تنزيل الملف</string>
|
||||
<string name="preview_image_file_is_not_exist">الملف غير موجود</string>
|
||||
<string name="preview_media_unhandled_http_code_message">الملف مقفلٌ حالياً من قِبَل مستخدِمٍ أو عمليةٍ أخرى؛ وبالتالي لا يمكن حذفه. الرجاء معاودة المحاولة في وقتٍ لاحقٍ.</string>
|
||||
<string name="preview_sorry">آسف</string>
|
||||
<string name="privacy">الخصوصية</string>
|
||||
|
@ -911,6 +915,9 @@
|
|||
<string name="trashbin_file_remove">حذف نهائي</string>
|
||||
<string name="trashbin_loading_failed">فشل تحميل سلة المحذوفات</string>
|
||||
<string name="trashbin_not_emptied">تعذر حذف الملفات نهائياً!</string>
|
||||
<string name="unified_search_fragment_calendar_event_not_found">لم يمكن العثور على الحدث. يمكنك دائمًا المزامنة للتحديث. جارٍ إعادة التوجيه إلى الويب...</string>
|
||||
<string name="unified_search_fragment_contact_not_found">لم يمكن العثور على جهة الاتصال. يمكنك دائمًا المزامنة للتحديث. جارٍ إعادة التوجيه إلى الويب...</string>
|
||||
<string name="unified_search_fragment_permission_needed">مطلوب أذونات لفتح نتيجة البحث و إلّا ستتم إعادة توجيهها إلى الويب...</string>
|
||||
<string name="unlock_file">فتح قفل الملف</string>
|
||||
<string name="unread_comments">توجد تعليقات غير مقروءة</string>
|
||||
<string name="unset_encrypted">لم يتم تحديد التشفير</string>
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
<string name="manage_space_clear_data">Daten löschen</string>
|
||||
<string name="manage_space_description">Einstellungen, Datenbank und Server-Zertifikate von %1$s\'s Daten werden dauerhaft gelöscht.\n\nHerunter geladene Dateien bleiben unangetastet.\n\nDieser Vorgang kann eine Zeit dauern.</string>
|
||||
<string name="manage_space_title">Verwalte Speicherplatz</string>
|
||||
<string name="max_file_count_warning_message">Sie haben die maximale Anzahl an Datei-Uploads erreicht. Bitte laden Sie weniger als 500 Dateien gleichzeitig hoch.</string>
|
||||
<string name="media_err_invalid_progressive_playback">Die Mediendatei kann nicht gestreamt werden</string>
|
||||
<string name="media_err_io">Konnte die Mediendatei nicht lesen</string>
|
||||
<string name="media_err_malformed">Mediendatei ist nicht korrekt encodiert</string>
|
||||
|
@ -666,8 +667,11 @@
|
|||
<string name="prefs_value_theme_light">Hell</string>
|
||||
<string name="prefs_value_theme_system">Systemvorgaben verwenden</string>
|
||||
<string name="preview_image_description">Bildvorschau</string>
|
||||
<string name="preview_image_downloading_image_for_edit">Bild wird für das Bearbeiten heruntergeladen, bitte warten…</string>
|
||||
<string name="preview_image_error_no_local_file">Keine lokale Datei für die Vorschau vorhanden</string>
|
||||
<string name="preview_image_error_unknown_format">Bild kann nicht angezeigt werden</string>
|
||||
<string name="preview_image_file_is_not_downloaded">Datei nicht heruntergeladen</string>
|
||||
<string name="preview_image_file_is_not_exist">Datei existiert nicht</string>
|
||||
<string name="preview_media_unhandled_http_code_message">Die Datei ist derzeit von einem anderen Benutzer oder Prozess gesperrt und kann daher nicht gelöscht werden. Bitte später noch einmal versuchen.</string>
|
||||
<string name="preview_sorry">Entschuldigung</string>
|
||||
<string name="privacy">Datenschutz</string>
|
||||
|
@ -885,6 +889,9 @@
|
|||
<string name="trashbin_file_remove">Endgültig löschen</string>
|
||||
<string name="trashbin_loading_failed">Laden des Papierkorbs fehlgeschlagen!</string>
|
||||
<string name="trashbin_not_emptied">Dateien konnten nicht endgültig gelöscht werden!</string>
|
||||
<string name="unified_search_fragment_calendar_event_not_found">Termin nicht gefunden, Sie können jederzeit die Synchronisierung wiederholen. Weiterleiten zum Web…</string>
|
||||
<string name="unified_search_fragment_contact_not_found">Kontakt nicht gefunden, Sie können jederzeit synchronisieren für eine Aktualisierung. Weiterleiten zum Web…</string>
|
||||
<string name="unified_search_fragment_permission_needed">Berechtigungen für das Öffnen der Suchergebnisse notwendig, ansonsten werden Sie zum Web weitergeleitet</string>
|
||||
<string name="unlock_file">Datei entsperren</string>
|
||||
<string name="unread_comments">Es gibt ungelesene Kommentare</string>
|
||||
<string name="unset_encrypted">Verschlüsselung aufheben</string>
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
<string name="manage_space_clear_data">Borrar datos</string>
|
||||
<string name="manage_space_description">Las configuraciones, base de datos y certificados del servidor de los datos de %1$s serán eliminados permanentemente.\n\nLos archivos descargados se mantendrán sin cambios.\n\nEste proceso puede tomar algo de tiempo. </string>
|
||||
<string name="manage_space_title">Administrar espacio</string>
|
||||
<string name="max_file_count_warning_message">Ha alcanzado el límite de carga máxima de archivos. Por favor, cargue menos de 500 archivos a la vez.</string>
|
||||
<string name="media_err_invalid_progressive_playback">No se puede transmitir el archivo multimedia</string>
|
||||
<string name="media_err_io">No fue posible leer el archivo de medios</string>
|
||||
<string name="media_err_malformed">El archivo de medios tiene una codificación incorrecta</string>
|
||||
|
@ -666,8 +667,11 @@
|
|||
<string name="prefs_value_theme_light">Claro</string>
|
||||
<string name="prefs_value_theme_system">Seguir el del sistema</string>
|
||||
<string name="preview_image_description">Vista previa de imagen</string>
|
||||
<string name="preview_image_downloading_image_for_edit">Descargando la imagen para abrir la pantalla de edición, por favor espere...</string>
|
||||
<string name="preview_image_error_no_local_file">No existe un archivo local a previsualizar</string>
|
||||
<string name="preview_image_error_unknown_format">No es posible mostrar la imagen</string>
|
||||
<string name="preview_image_file_is_not_downloaded">El archivo no está descargado</string>
|
||||
<string name="preview_image_file_is_not_exist">El archivo no existe</string>
|
||||
<string name="preview_media_unhandled_http_code_message">El archivo se encuentra bloqueado actualmente por otro usuario o proceso y, por lo tanto, no es posible eliminarlo. Por favor, intente de nuevo más tarde.</string>
|
||||
<string name="preview_sorry">Disculpa</string>
|
||||
<string name="privacy">Privacidad</string>
|
||||
|
@ -677,6 +681,7 @@
|
|||
<string name="push_notifications_temp_error">En este momento las notificaciones push no están disponibles.</string>
|
||||
<string name="qr_could_not_be_read">¡No se pudo leer el código QR!</string>
|
||||
<string name="receive_external_files_activity_start_sync_folder_is_not_exists_message">No se pudo encontrar la carpeta, la sincronización se ha cancelado</string>
|
||||
<string name="receive_external_files_activity_unable_to_find_file_to_upload">No se pudo encontrar el archivo a cargar</string>
|
||||
<string name="recommend_subject">¡Prueba %1$s en tu dispositivo!</string>
|
||||
<string name="recommend_text">Quiero invitarte a usar %1$s en tu dispositivo\nDescárgalo aquí:%2$s </string>
|
||||
<string name="recommend_urls">%1$s ó %2$s</string>
|
||||
|
@ -884,6 +889,9 @@
|
|||
<string name="trashbin_file_remove">Borrar permanentemente</string>
|
||||
<string name="trashbin_loading_failed">¡No se pudo cargar la papelera de reciclaje!</string>
|
||||
<string name="trashbin_not_emptied">¡Los archivos no pudieron ser eliminados permanentemente!</string>
|
||||
<string name="unified_search_fragment_calendar_event_not_found">Evento no encontrado, siempre puede sincronizar para actualizar. Redirigiendo a la web...</string>
|
||||
<string name="unified_search_fragment_contact_not_found">Contacto no encontrado, siempre puede sincronizar para actualizar. Redirigiendo a la web...</string>
|
||||
<string name="unified_search_fragment_permission_needed">Permisos requeridos para abrir los resultados de búsqueda, de lo contrario se redirigirá a la web...</string>
|
||||
<string name="unlock_file">Archivo desbloqueado</string>
|
||||
<string name="unread_comments">Existen comentarios sin leer</string>
|
||||
<string name="unset_encrypted">Desestablecer encripción</string>
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
<string name="manage_space_clear_data">Limpar os datos</string>
|
||||
<string name="manage_space_description">Van ser eliminados definitivamente os axustes , base de datos e certificados do servidor de %1$s.\n\nOs ficheiros descargados conservaranse sen cambios.\n\nEste proceso pode levar bastante tempo.</string>
|
||||
<string name="manage_space_title">Xestionar o espazo</string>
|
||||
<string name="max_file_count_warning_message">Acadou o límite máximo de envío de ficheiros. Envíe menos de 500 ficheiros dunha sentada.</string>
|
||||
<string name="media_err_invalid_progressive_playback">Non é posíbel transmitir o ficheiro multimedia</string>
|
||||
<string name="media_err_io">Non foi posíbel ler o ficheiro multimedia</string>
|
||||
<string name="media_err_malformed">O ficheiro multimedia ten unha codificación incorrecta</string>
|
||||
|
@ -594,7 +595,7 @@
|
|||
<string name="permission_storage_access">Precísanse permisos adicionais para enviar e descargar ficheiros.</string>
|
||||
<string name="picture_set_as_no_app">Non se atopou unha aplicación coa que definir unha imaxe</string>
|
||||
<string name="pin_home">Fixar na pantalla de Inicio</string>
|
||||
<string name="pin_shortcut_label">Aberto %1$s</string>
|
||||
<string name="pin_shortcut_label">Abrir %1$s</string>
|
||||
<string name="placeholder_fileSize">389 KB</string>
|
||||
<string name="placeholder_filename">marcadordeposición.txt</string>
|
||||
<string name="placeholder_media_time">12:23:45</string>
|
||||
|
@ -667,8 +668,11 @@
|
|||
<string name="prefs_value_theme_light">Claro</string>
|
||||
<string name="prefs_value_theme_system">Seguir o sistema</string>
|
||||
<string name="preview_image_description">Vista previa da imaxe</string>
|
||||
<string name="preview_image_downloading_image_for_edit">Descargando a imaxe para iniciar a pantalla de edición, agarde…</string>
|
||||
<string name="preview_image_error_no_local_file">Non hai ficheiro local que ver</string>
|
||||
<string name="preview_image_error_unknown_format">Non é posíbel amosar a imaxe</string>
|
||||
<string name="preview_image_file_is_not_downloaded">O ficheiro non está descargado</string>
|
||||
<string name="preview_image_file_is_not_exist">O ficheiro non existe</string>
|
||||
<string name="preview_media_unhandled_http_code_message">O ficheiro está bloqueado actualmente por outro usuario ou proceso e, polo tanto, non é posíbel eliminalo. Ténteo de novo máis tarde.</string>
|
||||
<string name="preview_sorry">Desculpe.</string>
|
||||
<string name="privacy">Privacidade</string>
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
<string name="manage_space_clear_data">清除資料</string>
|
||||
<string name="manage_space_description">來自 %1$s 的設定,資料庫與伺服器憑證相關資料將被永久刪除,已下載的檔案將不會變動,此過程需要花費一些時間。</string>
|
||||
<string name="manage_space_title">管理空間</string>
|
||||
<string name="max_file_count_warning_message">您已達最大檔案上傳限制。一次上傳僅能上傳少於 500 個檔案。</string>
|
||||
<string name="media_err_invalid_progressive_playback">此媒體檔案無法被串流播放</string>
|
||||
<string name="media_err_io">無法讀取媒體檔案</string>
|
||||
<string name="media_err_malformed">媒體檔案編碼不正確</string>
|
||||
|
@ -666,8 +667,11 @@
|
|||
<string name="prefs_value_theme_light">淺色</string>
|
||||
<string name="prefs_value_theme_system">跟隨系統</string>
|
||||
<string name="preview_image_description">圖片預覽</string>
|
||||
<string name="preview_image_downloading_image_for_edit">正在下載影像以啟動編輯畫面,請稍候……</string>
|
||||
<string name="preview_image_error_no_local_file">沒有可供預覽的本機檔案</string>
|
||||
<string name="preview_image_error_unknown_format">無法顯示圖片</string>
|
||||
<string name="preview_image_file_is_not_downloaded">檔案未下載</string>
|
||||
<string name="preview_image_file_is_not_exist">檔案不存在</string>
|
||||
<string name="preview_media_unhandled_http_code_message">檔案目前已被其他使用者或處理程序鎖定,因此無法刪除。請稍後再試。</string>
|
||||
<string name="preview_sorry">很抱歉</string>
|
||||
<string name="privacy">隱私權</string>
|
||||
|
@ -885,6 +889,9 @@
|
|||
<string name="trashbin_file_remove">永久刪除</string>
|
||||
<string name="trashbin_loading_failed">載入回收桶失敗!</string>
|
||||
<string name="trashbin_not_emptied">無法永久刪除檔案!</string>
|
||||
<string name="unified_search_fragment_calendar_event_not_found">找不到活動,您隨時可以同步更新。正在重新導向至網路……</string>
|
||||
<string name="unified_search_fragment_contact_not_found">找不到聯絡人,您隨時可以同步更新。正在重新導向至網路……</string>
|
||||
<string name="unified_search_fragment_permission_needed">開啟搜尋結果需要權限,否則其將會重新導向至網路……</string>
|
||||
<string name="unlock_file">解鎖檔案</string>
|
||||
<string name="unread_comments">有未讀留言</string>
|
||||
<string name="unset_encrypted">取消加密</string>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* SPDX-FileCopyrightText: 2022 Álvaro Brey <alvaro@alvarobrey.com>
|
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
package com.owncloud.android.ui.adapter
|
||||
|
||||
|
|
Loading…
Reference in a new issue