mirror of https://github.com/nextcloud/android
Glide 4
Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
This commit is contained in:
parent
df3bb79365
commit
b80bba82c1
|
@ -239,9 +239,8 @@ dependencies {
|
|||
|
||||
implementation 'org.parceler:parceler-api:1.1.11'
|
||||
annotationProcessor 'org.parceler:parceler:1.1.11'
|
||||
implementation ('com.github.bumptech.glide:glide:3.7.0') {
|
||||
exclude group: "com.android.support"
|
||||
}
|
||||
implementation 'com.github.bumptech.glide:glide:4.8.0'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
|
||||
implementation 'com.caverock:androidsvg:1.3'
|
||||
implementation "com.android.support:support-annotations:${supportLibraryVersion}"
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
|
|
|
@ -91,7 +91,6 @@ public class OCFileUnitTest {
|
|||
mFile.setPublicLink(PUBLIC_LINK);
|
||||
mFile.setPermissions(PERMISSIONS);
|
||||
mFile.setRemoteId(REMOTE_ID);
|
||||
mFile.setNeedsUpdateThumbnail(true);
|
||||
mFile.setDownloading(true);
|
||||
mFile.setEtagInConflict(ETAG_IN_CONFLICT);
|
||||
|
||||
|
@ -121,12 +120,12 @@ public class OCFileUnitTest {
|
|||
assertThat(fileReadFromParcel.getLastSyncDateForData(), is(LAST_SYNC_DATE_FOR_DATA));
|
||||
assertThat(fileReadFromParcel.isAvailableOffline(), is(true));
|
||||
assertThat(fileReadFromParcel.getEtag(), is(ETAG));
|
||||
assertThat(fileReadFromParcel.getEtagOnServer(), is(ETAG));
|
||||
assertThat(fileReadFromParcel.isSharedViaLink(), is(true));
|
||||
assertThat(fileReadFromParcel.isSharedWithSharee(), is(true));
|
||||
assertThat(fileReadFromParcel.getPublicLink(), is(PUBLIC_LINK));
|
||||
assertThat(fileReadFromParcel.getPermissions(), is(PERMISSIONS));
|
||||
assertThat(fileReadFromParcel.getRemoteId(), is(REMOTE_ID));
|
||||
assertThat(fileReadFromParcel.needsUpdateThumbnail(), is(true));
|
||||
assertThat(fileReadFromParcel.isDownloading(), is(true));
|
||||
assertThat(fileReadFromParcel.getEtagInConflict(), is(ETAG_IN_CONFLICT));
|
||||
|
||||
|
|
|
@ -397,7 +397,7 @@ public final class PushUtils {
|
|||
if (oldPrivateKeyFile.exists()) {
|
||||
try {
|
||||
FileStorageUtils.moveFile(oldPrivateKeyFile, privateKeyFile);
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to move old private key to new location");
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ public final class PushUtils {
|
|||
if (oldPublicKeyFile.exists()) {
|
||||
try {
|
||||
FileStorageUtils.moveFile(oldPublicKeyFile, publicKeyFile);
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to move old public key to new location");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,12 +203,6 @@
|
|||
android:resource="@xml/exposed_filepaths" />
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name=".providers.DiskLruImageCacheFileProvider"
|
||||
android:authorities="@string/image_cache_provider_authority"
|
||||
android:exported="true">
|
||||
</provider>
|
||||
|
||||
<activity
|
||||
android:name=".authentication.AuthenticatorActivity"
|
||||
android:exported="true"
|
||||
|
|
|
@ -53,7 +53,6 @@ import com.owncloud.android.datamodel.MediaFolderType;
|
|||
import com.owncloud.android.datamodel.MediaProvider;
|
||||
import com.owncloud.android.datamodel.SyncedFolder;
|
||||
import com.owncloud.android.datamodel.SyncedFolderProvider;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.datastorage.DataStorageProvider;
|
||||
import com.owncloud.android.datastorage.StoragePoint;
|
||||
import com.owncloud.android.db.PreferenceManager;
|
||||
|
@ -143,10 +142,6 @@ public class MainApp extends MultiDexApplication {
|
|||
.setDefaultPolicy(Policy.SINGLE_SESSION_PER_ACCOUNT_IF_SERVER_SUPPORTS_SERVER_MONITORING);
|
||||
}
|
||||
|
||||
// initialise thumbnails cache on background thread
|
||||
new ThumbnailsCacheManager.InitDiskCacheTask().execute();
|
||||
|
||||
|
||||
if (BuildConfig.DEBUG || getApplicationContext().getResources().getBoolean(R.bool.logger_enabled) ||
|
||||
appPrefs.getBoolean(Preferences.PREFERENCE_EXPERT_MODE, false)) {
|
||||
// use app writable dir, no permissions needed
|
||||
|
|
|
@ -29,6 +29,9 @@ import android.support.annotation.Nullable;
|
|||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||
import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
import com.owncloud.android.ui.activity.ManageAccountsActivity;
|
||||
|
@ -196,4 +199,33 @@ public final class AccountUtils {
|
|||
public static boolean hasSearchSupport(Account account) {
|
||||
return getServerVersion(account).isSearchSupported();
|
||||
}
|
||||
|
||||
public static @Nullable
|
||||
OwnCloudClient getClientForCurrentAccount(Context context) {
|
||||
try {
|
||||
Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(context);
|
||||
|
||||
if (currentAccount == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
OwnCloudAccount ocAccount = new OwnCloudAccount(currentAccount, context);
|
||||
return OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, context);
|
||||
} catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
|
||||
throw new IllegalStateException("Account not found", e);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Client could not be instantiated", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static OwnCloudClient getClientForAccount(Account account, Context context) {
|
||||
try {
|
||||
OwnCloudAccount ocAccount = new OwnCloudAccount(account, context);
|
||||
return OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, context);
|
||||
} catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
|
||||
throw new IllegalStateException("Account not found");
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Client could not be instantiated");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,12 +210,12 @@ public class FileDataStorageManager {
|
|||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
|
||||
cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isAvailableOffline() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, file.getEtagOnServer());
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
|
||||
cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
|
||||
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
|
||||
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
|
||||
cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, file.getEtagInConflict());
|
||||
|
||||
|
@ -450,6 +450,7 @@ public class FileDataStorageManager {
|
|||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, folder.getLastSyncDateForData());
|
||||
cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, folder.isAvailableOffline() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_ETAG, folder.getEtag());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, folder.getEtagOnServer());
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, folder.isSharedViaLink() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, folder.isSharedWithSharee() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, folder.getPublicLink());
|
||||
|
@ -479,12 +480,12 @@ public class FileDataStorageManager {
|
|||
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
|
||||
cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isAvailableOffline() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, file.getEtagOnServer());
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
|
||||
cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
|
||||
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
|
||||
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
|
||||
cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, file.getEtagInConflict());
|
||||
cv.put(ProviderTableMeta.FILE_FAVORITE, file.isFavorite());
|
||||
|
@ -968,12 +969,12 @@ public class FileDataStorageManager {
|
|||
file.setLastSyncDateForData(c.getLong(c.getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA)));
|
||||
file.setAvailableOffline(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1);
|
||||
file.setEtag(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG)));
|
||||
file.setEtagOnServer(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG_ON_SERVER)));
|
||||
file.setShareViaLink(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_SHARED_VIA_LINK)) == 1);
|
||||
file.setShareWithSharee(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_SHARED_WITH_SHAREE)) == 1);
|
||||
file.setPublicLink(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PUBLIC_LINK)));
|
||||
file.setPermissions(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PERMISSIONS)));
|
||||
file.setRemoteId(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_REMOTE_ID)));
|
||||
file.setNeedsUpdateThumbnail(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1);
|
||||
file.setDownloading(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_IS_DOWNLOADING)) == 1);
|
||||
file.setEtagInConflict(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG_IN_CONFLICT)));
|
||||
file.setFavorite(c.getInt(c.getColumnIndex(ProviderTableMeta.FILE_FAVORITE)) == 1);
|
||||
|
@ -1394,16 +1395,13 @@ public class FileDataStorageManager {
|
|||
);
|
||||
cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isAvailableOffline() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
|
||||
cv.put(ProviderTableMeta.FILE_ETAG_ON_SERVER, file.getEtagOnServer());
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
|
||||
cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
|
||||
cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
|
||||
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
|
||||
cv.put(ProviderTableMeta.FILE_FAVORITE, file.isFavorite());
|
||||
cv.put(
|
||||
ProviderTableMeta.FILE_UPDATE_THUMBNAIL,
|
||||
file.needsUpdateThumbnail() ? 1 : 0
|
||||
);
|
||||
cv.put(
|
||||
ProviderTableMeta.FILE_IS_DOWNLOADING,
|
||||
file.isDownloading() ? 1 : 0
|
||||
|
|
|
@ -81,6 +81,7 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
private boolean mAvailableOffline;
|
||||
|
||||
private String mEtag;
|
||||
private String mEtagOnServer;
|
||||
|
||||
private boolean mShareByLink;
|
||||
private String mPublicLink;
|
||||
|
@ -154,6 +155,7 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
mLastSyncDateForProperties = source.readLong();
|
||||
mLastSyncDateForData = source.readLong();
|
||||
mEtag = source.readString();
|
||||
mEtagOnServer = source.readString();
|
||||
mShareByLink = source.readInt() == 1;
|
||||
mPublicLink = source.readString();
|
||||
mPermissions = source.readString();
|
||||
|
@ -184,6 +186,7 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
dest.writeLong(mLastSyncDateForProperties);
|
||||
dest.writeLong(mLastSyncDateForData);
|
||||
dest.writeString(mEtag);
|
||||
dest.writeString(mEtagOnServer);
|
||||
dest.writeInt(mShareByLink ? 1 : 0);
|
||||
dest.writeString(mPublicLink);
|
||||
dest.writeString(mPermissions);
|
||||
|
@ -513,6 +516,7 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
mAvailableOffline = false;
|
||||
mNeedsUpdating = false;
|
||||
mEtag = null;
|
||||
mEtagOnServer = null;
|
||||
mShareByLink = false;
|
||||
mPublicLink = null;
|
||||
mPermissions = null;
|
||||
|
@ -600,14 +604,6 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
return mNeedsUpdating;
|
||||
}
|
||||
|
||||
public boolean needsUpdateThumbnail() {
|
||||
return mNeedsUpdateThumbnail;
|
||||
}
|
||||
|
||||
public void setNeedsUpdateThumbnail(boolean needsUpdateThumbnail) {
|
||||
this.mNeedsUpdateThumbnail = needsUpdateThumbnail;
|
||||
}
|
||||
|
||||
public long getLastSyncDateForProperties() {
|
||||
return mLastSyncDateForProperties;
|
||||
}
|
||||
|
@ -685,6 +681,9 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
this.mEtag = (etag != null ? etag : "");
|
||||
}
|
||||
|
||||
public void setEtagOnServer(String eTag) {
|
||||
this.mEtagOnServer = eTag != null ? eTag : "";
|
||||
}
|
||||
|
||||
public boolean isSharedViaLink() {
|
||||
return mShareByLink;
|
||||
|
@ -797,4 +796,8 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
public void setMountType(WebdavEntry.MountType mountType) {
|
||||
mMountType = mountType;
|
||||
}
|
||||
|
||||
public String getEtagOnServer() {
|
||||
return mEtagOnServer;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,7 +32,7 @@ import com.owncloud.android.MainApp;
|
|||
public class ProviderMeta {
|
||||
|
||||
public static final String DB_NAME = "filelist";
|
||||
public static final int DB_VERSION = 34;
|
||||
public static final int DB_VERSION = 35;
|
||||
|
||||
private ProviderMeta() {
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ public class ProviderMeta {
|
|||
public static final String FILE_LAST_SYNC_DATE_FOR_DATA = "last_sync_date_for_data";
|
||||
public static final String FILE_KEEP_IN_SYNC = "keep_in_sync";
|
||||
public static final String FILE_ETAG = "etag";
|
||||
public static final String FILE_ETAG_ON_SERVER = "etag_on_server";
|
||||
public static final String FILE_SHARED_VIA_LINK = "share_by_link";
|
||||
public static final String FILE_SHARED_WITH_SHAREE = "shared_via_users";
|
||||
public static final String FILE_PUBLIC_LINK = "public_link";
|
||||
|
@ -104,12 +105,12 @@ public class ProviderMeta {
|
|||
public static final String FILE_IS_ENCRYPTED = "is_encrypted";
|
||||
public static final String FILE_MOUNT_TYPE = "mount_type";
|
||||
|
||||
public static final String [] FILE_ALL_COLUMNS = {_ID, FILE_PARENT, FILE_NAME
|
||||
, FILE_CREATION, FILE_MODIFIED,
|
||||
public static final String[] FILE_ALL_COLUMNS = {_ID, FILE_PARENT, FILE_NAME, FILE_CREATION, FILE_MODIFIED,
|
||||
FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, FILE_CONTENT_LENGTH, FILE_CONTENT_TYPE, FILE_STORAGE_PATH,
|
||||
FILE_PATH, FILE_ACCOUNT_OWNER, FILE_LAST_SYNC_DATE, FILE_LAST_SYNC_DATE_FOR_DATA, FILE_KEEP_IN_SYNC,
|
||||
FILE_ETAG, FILE_SHARED_VIA_LINK, FILE_SHARED_WITH_SHAREE, FILE_PUBLIC_LINK, FILE_PERMISSIONS,
|
||||
FILE_REMOTE_ID, FILE_UPDATE_THUMBNAIL, FILE_IS_DOWNLOADING, FILE_ETAG_IN_CONFLICT, FILE_FAVORITE};
|
||||
FILE_ETAG, FILE_ETAG_ON_SERVER, FILE_SHARED_VIA_LINK, FILE_SHARED_WITH_SHAREE, FILE_PUBLIC_LINK,
|
||||
FILE_PERMISSIONS, FILE_REMOTE_ID, FILE_IS_DOWNLOADING, FILE_ETAG_IN_CONFLICT,
|
||||
FILE_FAVORITE};
|
||||
|
||||
public static final String FILE_DEFAULT_SORT_ORDER = FILE_NAME + " collate nocase asc";
|
||||
|
||||
|
|
|
@ -492,7 +492,6 @@ public class FileDownloader extends Service
|
|||
long syncDate = System.currentTimeMillis();
|
||||
file.setLastSyncDateForProperties(syncDate);
|
||||
file.setLastSyncDateForData(syncDate);
|
||||
file.setNeedsUpdateThumbnail(true);
|
||||
file.setModificationTimestamp(mCurrentDownload.getModificationTimestamp());
|
||||
file.setModificationTimestampAtLastSyncForData(mCurrentDownload.getModificationTimestamp());
|
||||
file.setEtag(mCurrentDownload.getEtag());
|
||||
|
|
|
@ -53,7 +53,6 @@ import com.owncloud.android.authentication.AccountUtils;
|
|||
import com.owncloud.android.authentication.AuthenticatorActivity;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.datamodel.UploadsStorageManager;
|
||||
import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus;
|
||||
import com.owncloud.android.db.OCUpload;
|
||||
|
@ -71,6 +70,7 @@ import com.owncloud.android.ui.activity.FileActivity;
|
|||
import com.owncloud.android.ui.activity.UploadListActivity;
|
||||
import com.owncloud.android.ui.notifications.NotificationUtils;
|
||||
import com.owncloud.android.utils.ConnectivityUtils;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.ErrorMessageAdapter;
|
||||
import com.owncloud.android.utils.PowerUtils;
|
||||
import com.owncloud.android.utils.ThemeUtils;
|
||||
|
@ -1120,13 +1120,7 @@ public class FileUploader extends Service
|
|||
}
|
||||
|
||||
// generate new Thumbnail
|
||||
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
||||
new ThumbnailsCacheManager.ThumbnailGenerationTask(mStorageManager, mCurrentAccount);
|
||||
|
||||
File file = new File(mCurrentUpload.getOriginalStoragePath());
|
||||
String remoteId = mCurrentUpload.getFile().getRemoteId();
|
||||
|
||||
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, remoteId));
|
||||
DisplayUtils.generateThumbnail(mCurrentUpload.getFile(), mCurrentUpload.getOriginalStoragePath(), getBaseContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -477,7 +477,6 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
} else if (remoteFolderChanged && MimeTypeUtil.isImage(remoteFile) &&
|
||||
remoteFile.getModificationTimestamp() !=
|
||||
localFile.getModificationTimestamp()) {
|
||||
updatedFile.setNeedsUpdateThumbnail(true);
|
||||
Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
|
||||
}
|
||||
|
||||
|
@ -488,6 +487,9 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
// remote eTag will not be updated unless file CONTENTS are synchronized
|
||||
updatedFile.setEtag("");
|
||||
}
|
||||
|
||||
// eTag on Server is used for thumbnail validation
|
||||
updatedFile.setEtagOnServer(remoteFile.getEtag());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -26,19 +26,21 @@ import android.accounts.Account;
|
|||
import android.content.Context;
|
||||
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.files.RemoveRemoteFileOperation;
|
||||
import com.owncloud.android.operations.common.SyncOperation;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Remote operation performing the removal of a remote file or folder in the ownCloud server.
|
||||
*/
|
||||
public class RemoveFileOperation extends SyncOperation {
|
||||
private final static String TAG = RemoveFileOperation.class.getSimpleName();
|
||||
|
||||
private OCFile fileToRemove;
|
||||
private String remotePath;
|
||||
|
@ -92,7 +94,11 @@ public class RemoveFileOperation extends SyncOperation {
|
|||
fileToRemove = getStorageManager().getFileByPath(remotePath);
|
||||
|
||||
// store resized image
|
||||
ThumbnailsCacheManager.generateResizedImage(fileToRemove);
|
||||
try {
|
||||
DisplayUtils.generateResizedImage(fileToRemove, context);
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Thumbnail generation failed", e);
|
||||
}
|
||||
|
||||
boolean localRemovalFailed = false;
|
||||
if (!onlyLocalCopy) {
|
||||
|
|
|
@ -23,7 +23,6 @@ package com.owncloud.android.operations;
|
|||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
|
@ -39,7 +38,6 @@ import com.owncloud.android.lib.resources.files.RemoteFile;
|
|||
import com.owncloud.android.operations.common.SyncOperation;
|
||||
import com.owncloud.android.services.OperationsService;
|
||||
import com.owncloud.android.utils.FileStorageUtils;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
|
@ -332,11 +330,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
if (updatedFile.isFolder()) {
|
||||
updatedFile.setFileLength(localFile.getFileLength());
|
||||
// TODO move operations about size of folders to FileContentProvider
|
||||
} else if (mRemoteFolderChanged && MimeTypeUtil.isImage(remoteFile) &&
|
||||
remoteFile.getModificationTimestamp() !=
|
||||
localFile.getModificationTimestamp()) {
|
||||
updatedFile.setNeedsUpdateThumbnail(true);
|
||||
Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
|
||||
}
|
||||
updatedFile.setPublicLink(localFile.getPublicLink());
|
||||
updatedFile.setShareViaLink(localFile.isSharedViaLink());
|
||||
|
|
|
@ -35,7 +35,6 @@ import com.owncloud.android.datamodel.DecryptedFolderMetadata;
|
|||
import com.owncloud.android.datamodel.EncryptedFolderMetadata;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.datamodel.UploadsStorageManager;
|
||||
import com.owncloud.android.db.OCUpload;
|
||||
import com.owncloud.android.files.services.FileUploader;
|
||||
|
@ -59,6 +58,7 @@ import com.owncloud.android.lib.resources.files.UpdateMetadataOperation;
|
|||
import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
|
||||
import com.owncloud.android.operations.common.SyncOperation;
|
||||
import com.owncloud.android.utils.ConnectivityUtils;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.EncryptionUtils;
|
||||
import com.owncloud.android.utils.FileStorageUtils;
|
||||
import com.owncloud.android.utils.MimeType;
|
||||
|
@ -1332,16 +1332,13 @@ public class UploadFileOperation extends SyncOperation {
|
|||
// coincidence; nothing else is needed, the storagePath is right
|
||||
// in the instance returned by mCurrentUpload.getFile()
|
||||
}
|
||||
file.setNeedsUpdateThumbnail(true);
|
||||
getStorageManager().saveFile(file);
|
||||
getStorageManager().saveConflict(file, null);
|
||||
|
||||
FileDataStorageManager.triggerMediaScan(file.getStoragePath());
|
||||
|
||||
// generate new Thumbnail
|
||||
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
||||
new ThumbnailsCacheManager.ThumbnailGenerationTask(getStorageManager(), mAccount);
|
||||
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, file.getRemoteId()));
|
||||
DisplayUtils.generateThumbnail(file, mOriginalStoragePath, getContext());
|
||||
}
|
||||
|
||||
private void updateOCFile(OCFile file, RemoteFile remoteFile) {
|
||||
|
@ -1352,6 +1349,7 @@ public class UploadFileOperation extends SyncOperation {
|
|||
file.setModificationTimestampAtLastSyncForData(remoteFile.getModifiedTimestamp());
|
||||
file.setEtag(remoteFile.getEtag());
|
||||
file.setRemoteId(remoteFile.getRemoteId());
|
||||
file.setEtagOnServer(remoteFile.getEtag());
|
||||
}
|
||||
|
||||
public interface OnRenameListener {
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2017 Tobias Kaminsky
|
||||
* Copyright (C) 2017 Nextcloud GmbH.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.providers;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.MatrixCursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class DiskLruImageCacheFileProvider extends ContentProvider {
|
||||
public static final String TAG = DiskLruImageCacheFileProvider.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private OCFile getFile(Uri uri) {
|
||||
Account account = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
|
||||
FileDataStorageManager fileDataStorageManager = new FileDataStorageManager(account,
|
||||
MainApp.getAppContext().getContentResolver());
|
||||
|
||||
return fileDataStorageManager.getFileByPath(uri.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException {
|
||||
OCFile ocFile = getFile(uri);
|
||||
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
String.valueOf(ThumbnailsCacheManager.PREFIX_RESIZED_IMAGE + ocFile.getRemoteId()));
|
||||
|
||||
// fallback to thumbnail
|
||||
if (thumbnail == null) {
|
||||
thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
String.valueOf(ThumbnailsCacheManager.PREFIX_THUMBNAIL + ocFile.getRemoteId()));
|
||||
}
|
||||
|
||||
// fallback to default image
|
||||
if (thumbnail == null) {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultImg;
|
||||
}
|
||||
|
||||
// create a file to write bitmap data
|
||||
File f = new File(MainApp.getAppContext().getCacheDir(), ocFile.getFileName());
|
||||
try {
|
||||
f.createNewFile();
|
||||
|
||||
//Convert bitmap to byte array
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bos);
|
||||
byte[] bitmapData = bos.toByteArray();
|
||||
|
||||
//write the bytes in file
|
||||
try (FileOutputStream fos = new FileOutputStream(f)){
|
||||
fos.write(bitmapData);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log_OC.e(TAG, "File not found: " + e.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Error opening file: " + e.getMessage());
|
||||
}
|
||||
|
||||
return ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(@NonNull Uri uri) {
|
||||
OCFile ocFile = getFile(uri);
|
||||
return ocFile.getMimeType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(@NonNull Uri uri, String[] arg1, String arg2, String[] arg3, String arg4) {
|
||||
MatrixCursor cursor = null;
|
||||
|
||||
OCFile ocFile = getFile(uri);
|
||||
File file = new File(MainApp.getAppContext().getCacheDir(), ocFile.getFileName());
|
||||
if (file.exists()) {
|
||||
cursor = new MatrixCursor(new String[] {
|
||||
OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE });
|
||||
cursor.addRow(new Object[] { uri.getLastPathSegment(),
|
||||
file.length() });
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(@NonNull Uri uri, ContentValues values) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -84,7 +84,7 @@ public class FileContentProvider extends ContentProvider {
|
|||
private static final String TEXT = " TEXT, ";
|
||||
private static final String ALTER_TABLE = "ALTER TABLE ";
|
||||
private static final String ADD_COLUMN = " ADD COLUMN ";
|
||||
private static final String REMOVE_COLUMN = " REMOVE COLUMN ";
|
||||
private static final String REMOVE_COLUMN = " DROP COLUMN ";
|
||||
private static final String UPGRADE_VERSION_MSG = "OUT of the ADD in onUpgrade; oldVersion == %d, newVersion == %d";
|
||||
private static final int SINGLE_PATH_SEGMENT = 1;
|
||||
public static final int ARBITRARY_DATA_TABLE_INTRODUCTION_VERSION = 20;
|
||||
|
@ -738,11 +738,11 @@ public class FileContentProvider extends ContentProvider {
|
|||
+ ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA + INTEGER
|
||||
+ ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA + INTEGER
|
||||
+ ProviderTableMeta.FILE_ETAG + TEXT
|
||||
+ ProviderTableMeta.FILE_ETAG_ON_SERVER + TEXT
|
||||
+ ProviderTableMeta.FILE_SHARED_VIA_LINK + INTEGER
|
||||
+ ProviderTableMeta.FILE_PUBLIC_LINK + TEXT
|
||||
+ ProviderTableMeta.FILE_PERMISSIONS + " TEXT null,"
|
||||
+ ProviderTableMeta.FILE_REMOTE_ID + " TEXT null,"
|
||||
+ ProviderTableMeta.FILE_UPDATE_THUMBNAIL + INTEGER //boolean
|
||||
+ ProviderTableMeta.FILE_IS_DOWNLOADING + INTEGER //boolean
|
||||
+ ProviderTableMeta.FILE_FAVORITE + INTEGER // boolean
|
||||
+ ProviderTableMeta.FILE_IS_ENCRYPTED + INTEGER // boolean
|
||||
|
@ -1745,6 +1745,24 @@ public class FileContentProvider extends ContentProvider {
|
|||
if (!upgraded) {
|
||||
Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
|
||||
}
|
||||
|
||||
if (oldVersion < 35 && newVersion >= 35) {
|
||||
Log_OC.i(SQL, "Entering in the #35 add eTagOnServer");
|
||||
db.beginTransaction();
|
||||
try {
|
||||
db.execSQL(ALTER_TABLE + ProviderTableMeta.FILE_TABLE_NAME +
|
||||
ADD_COLUMN + ProviderTableMeta.FILE_ETAG_ON_SERVER + " TEXT ");
|
||||
|
||||
upgraded = true;
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
if (!upgraded) {
|
||||
Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,6 +32,8 @@ import android.view.ViewGroup.LayoutParams;
|
|||
import android.view.WindowManager;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
/**
|
||||
* Represents a custom PopupWindows
|
||||
*/
|
||||
|
@ -121,6 +123,7 @@ public class CustomPopup {
|
|||
showLikeQuickAction(0, 0);
|
||||
}
|
||||
|
||||
@SuppressFBWarnings("CLI")
|
||||
public void showLikeQuickAction(int x, int y) {
|
||||
preShow();
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.NavigationView;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
|
@ -56,9 +57,8 @@ import android.widget.LinearLayout;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
|
@ -94,6 +94,7 @@ import com.owncloud.android.utils.DisplayUtils;
|
|||
import com.owncloud.android.utils.DrawerMenuUtil;
|
||||
import com.owncloud.android.utils.FilesSyncHelper;
|
||||
import com.owncloud.android.utils.ThemeUtils;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
import com.owncloud.android.utils.svg.MenuSimpleTarget;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
@ -630,11 +631,8 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
|
||||
// activate second/end account avatar
|
||||
if (mAvatars[1] != null) {
|
||||
View accountEndView = findNavigationViewChildById(R.id.drawer_account_end);
|
||||
accountEndView.setTag(mAvatars[1].name);
|
||||
|
||||
DisplayUtils.setAvatar(mAvatars[1], this, mOtherAccountAvatarRadiusDimension, getResources(),
|
||||
accountEndView, this);
|
||||
ImageView accountEndView = (ImageView) findNavigationViewChildById(R.id.drawer_account_end);
|
||||
DisplayUtils.setAvatar(mAvatars[1], this, accountEndView, mOtherAccountAvatarRadiusDimension);
|
||||
mAccountEndAccountAvatar.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mAccountEndAccountAvatar.setVisibility(View.GONE);
|
||||
|
@ -642,11 +640,8 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
|
||||
// activate third/middle account avatar
|
||||
if (mAvatars[2] != null) {
|
||||
View accountMiddleView = findNavigationViewChildById(R.id.drawer_account_middle);
|
||||
accountMiddleView.setTag(mAvatars[2].name);
|
||||
|
||||
DisplayUtils.setAvatar(mAvatars[2], this, mOtherAccountAvatarRadiusDimension, getResources(),
|
||||
accountMiddleView, this);
|
||||
ImageView accountMiddleView = (ImageView) findNavigationViewChildById(R.id.drawer_account_middle);
|
||||
DisplayUtils.setAvatar(mAvatars[2], this, accountMiddleView, mOtherAccountAvatarRadiusDimension);
|
||||
mAccountMiddleAccountAvatar.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mAccountMiddleAccountAvatar.setVisibility(View.GONE);
|
||||
|
@ -666,12 +661,11 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
private void repopulateAccountList(List<Account> accounts) {
|
||||
// remove all accounts from list
|
||||
mNavigationView.getMenu().removeGroup(R.id.drawer_menu_accounts);
|
||||
|
||||
SimpleTarget<Drawable> menuTarget;
|
||||
// add all accounts to list
|
||||
for (Account account: accounts) {
|
||||
try {
|
||||
// show all accounts except the currently active one and those pending for removal
|
||||
|
||||
if (!getAccount().name.equals(account.name)) {
|
||||
MenuItem accountMenuItem = mNavigationView.getMenu().add(
|
||||
R.id.drawer_menu_accounts,
|
||||
|
@ -679,8 +673,16 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
MENU_ORDER_ACCOUNT,
|
||||
account.name)
|
||||
.setIcon(TextDrawable.createAvatar(account.name, mMenuAccountAvatarRadiusDimension));
|
||||
DisplayUtils.setAvatar(account, this, mMenuAccountAvatarRadiusDimension, getResources(),
|
||||
accountMenuItem, this);
|
||||
|
||||
menuTarget = new SimpleTarget<Drawable>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Drawable resource,
|
||||
@Nullable Transition<? super Drawable> transition) {
|
||||
accountMenuItem.setIcon(resource);
|
||||
}
|
||||
};
|
||||
|
||||
DisplayUtils.setAvatar(account, this, menuTarget, mMenuAccountAvatarRadiusDimension);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Error calculating RGB value for account menu item.", e);
|
||||
|
@ -748,11 +750,9 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
username.setText(AccountUtils.getAccountUsername(account.name));
|
||||
}
|
||||
|
||||
View currentAccountView = findNavigationViewChildById(R.id.drawer_current_account);
|
||||
currentAccountView.setTag(account.name);
|
||||
ImageView currentAccountView = (ImageView) findNavigationViewChildById(R.id.drawer_current_account);
|
||||
|
||||
DisplayUtils.setAvatar(account, this, mCurrentAccountAvatarRadiusDimension, getResources(),
|
||||
currentAccountView, this);
|
||||
DisplayUtils.setAvatar(account, this, currentAccountView, mCurrentAccountAvatarRadiusDimension);
|
||||
|
||||
// check and show quota info if available
|
||||
getAndDisplayUserQuota();
|
||||
|
@ -862,31 +862,26 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
mQuotaTextLink.setText(firstQuota.name);
|
||||
mQuotaTextLink.setClickable(true);
|
||||
mQuotaTextLink.setVisibility(View.VISIBLE);
|
||||
mQuotaTextLink.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent externalWebViewIntent = new Intent(getApplicationContext(), ExternalSiteWebView.class);
|
||||
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_TITLE, firstQuota.name);
|
||||
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_URL, firstQuota.url);
|
||||
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_SHOW_SIDEBAR, true);
|
||||
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_MENU_ITEM_ID, -1);
|
||||
startActivity(externalWebViewIntent);
|
||||
}
|
||||
mQuotaTextLink.setOnClickListener(v -> {
|
||||
Intent externalWebViewIntent = new Intent(getApplicationContext(), ExternalSiteWebView.class);
|
||||
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_TITLE, firstQuota.name);
|
||||
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_URL, firstQuota.url);
|
||||
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_SHOW_SIDEBAR, true);
|
||||
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_MENU_ITEM_ID, -1);
|
||||
startActivity(externalWebViewIntent);
|
||||
});
|
||||
|
||||
|
||||
SimpleTarget target = new SimpleTarget<Drawable>() {
|
||||
SimpleTarget<Drawable> target = new SimpleTarget<Drawable>() {
|
||||
@Override
|
||||
public void onResourceReady(Drawable resource, GlideAnimation glideAnimation) {
|
||||
public void onResourceReady(@NonNull Drawable resource,
|
||||
@Nullable Transition<? super Drawable> transition) {
|
||||
Drawable test = resource.getCurrent();
|
||||
test.setBounds(0, 0, size, size);
|
||||
mQuotaTextLink.setCompoundDrawablesWithIntrinsicBounds(test, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
super.onLoadFailed(e, errorDrawable);
|
||||
|
||||
public void onLoadFailed(@Nullable Drawable errorDrawable) {
|
||||
Drawable test = errorDrawable.getCurrent();
|
||||
test.setBounds(0, 0, size, size);
|
||||
|
||||
|
@ -894,8 +889,8 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
}
|
||||
};
|
||||
|
||||
DisplayUtils.downloadIcon(this, firstQuota.iconUrl, target, R.drawable.ic_link_grey, size, size);
|
||||
|
||||
DisplayUtils.downloadIcon(this, firstQuota.iconUrl, target, R.drawable.ic_link_grey,
|
||||
R.drawable.ic_link_grey);
|
||||
} else {
|
||||
mQuotaTextLink.setVisibility(View.GONE);
|
||||
}
|
||||
|
@ -1018,28 +1013,28 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
mNavigationView.getMenu().removeGroup(R.id.drawer_menu_external_links);
|
||||
|
||||
float density = getResources().getDisplayMetrics().density;
|
||||
final int size = Math.round(24 * density);
|
||||
int greyColor = getResources().getColor(R.color.standard_grey);
|
||||
MenuSimpleTarget<Drawable> target;
|
||||
|
||||
for (final ExternalLink link : externalLinksProvider.getExternalLink(ExternalLinkType.LINK)) {
|
||||
int id = mNavigationView.getMenu().add(R.id.drawer_menu_external_links,
|
||||
MENU_ITEM_EXTERNAL_LINK + link.id, MENU_ORDER_EXTERNAL_LINKS, link.name)
|
||||
.setCheckable(true).getItemId();
|
||||
|
||||
MenuSimpleTarget target = new MenuSimpleTarget<Drawable>(id) {
|
||||
target = new MenuSimpleTarget<Drawable>(id) {
|
||||
@Override
|
||||
public void onResourceReady(Drawable resource, GlideAnimation glideAnimation) {
|
||||
public void onResourceReady(@NonNull Drawable resource,
|
||||
@Nullable Transition<? super Drawable> transition) {
|
||||
setExternalLinkIcon(getIdMenuItem(), resource, greyColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
super.onLoadFailed(e, errorDrawable);
|
||||
public void onLoadFailed(@Nullable Drawable errorDrawable) {
|
||||
setExternalLinkIcon(getIdMenuItem(), errorDrawable, greyColor);
|
||||
}
|
||||
};
|
||||
|
||||
DisplayUtils.downloadIcon(this, link.iconUrl, target, R.drawable.ic_link_grey, size, size);
|
||||
DisplayUtils.downloadIcon(this, link.iconUrl, target, R.drawable.ic_link_grey, R.drawable.ic_link_grey);
|
||||
}
|
||||
|
||||
setDrawerMenuItemChecked(mCheckedMenuItem);
|
||||
|
@ -1083,16 +1078,17 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
// use url
|
||||
if (URLUtil.isValidUrl(background) || background.isEmpty()) {
|
||||
// background image
|
||||
SimpleTarget target = new SimpleTarget<Drawable>() {
|
||||
SimpleTarget<Drawable> target = new SimpleTarget<Drawable>() {
|
||||
@Override
|
||||
public void onResourceReady(Drawable resource, GlideAnimation glideAnimation) {
|
||||
public void onResourceReady(@NonNull Drawable resource,
|
||||
@Nullable Transition<? super Drawable> transition) {
|
||||
Drawable[] drawables = {new ColorDrawable(primaryColor), resource};
|
||||
LayerDrawable layerDrawable = new LayerDrawable(drawables);
|
||||
setNavigationHeaderBackground(layerDrawable, navigationHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
public void onLoadFailed(@Nullable Drawable errorDrawable) {
|
||||
Drawable[] drawables = {new ColorDrawable(primaryColor), errorDrawable};
|
||||
LayerDrawable layerDrawable = new LayerDrawable(drawables);
|
||||
setNavigationHeaderBackground(layerDrawable, navigationHeader);
|
||||
|
@ -1107,13 +1103,8 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
|
|||
backgroundResource = R.drawable.background;
|
||||
}
|
||||
|
||||
Glide.with(this)
|
||||
.load(background)
|
||||
.centerCrop()
|
||||
.placeholder(backgroundResource)
|
||||
.error(backgroundResource)
|
||||
.crossFade()
|
||||
.into(target);
|
||||
DisplayUtils.downloadImage(background, backgroundResource, backgroundResource, target,
|
||||
GlideKey.url(background), this);
|
||||
} else {
|
||||
// plain color
|
||||
setNavigationHeaderBackground(new ColorDrawable(primaryColor), navigationHeader);
|
||||
|
|
|
@ -441,7 +441,7 @@ public class FileDisplayActivity extends HookActivity
|
|||
setFile(file);
|
||||
|
||||
if (mAccountWasSet) {
|
||||
setAccountInDrawer(getAccount());
|
||||
// setAccountInDrawer(getAccount()); // no need to call this here, as updateAccountList will be used
|
||||
setupDrawer();
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ public class ManageSpaceActivity extends AppCompatActivity {
|
|||
clearDataButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ClearDataAsynTask clearDataTask = new ClearDataAsynTask();
|
||||
ClearDataAsyncTask clearDataTask = new ClearDataAsyncTask();
|
||||
clearDataTask.execute();
|
||||
}
|
||||
});
|
||||
|
@ -82,7 +82,7 @@ public class ManageSpaceActivity extends AppCompatActivity {
|
|||
/**
|
||||
* AsyncTask for Clear Data, saving the passcode
|
||||
*/
|
||||
private class ClearDataAsynTask extends AsyncTask<Void, Void, Boolean>{
|
||||
private class ClearDataAsyncTask extends AsyncTask<Void, Void, Boolean> {
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
|
|
|
@ -776,7 +776,7 @@ public class ReceiveExternalFilesActivity extends FileActivity
|
|||
R.layout.uploader_list_item_layout,
|
||||
new String[]{"dirname"},
|
||||
new int[]{R.id.filename},
|
||||
getStorageManager(), getAccount());
|
||||
getAccount());
|
||||
|
||||
mListView.setAdapter(sa);
|
||||
}
|
||||
|
|
|
@ -56,9 +56,8 @@ import android.widget.LinearLayout;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.google.gson.Gson;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
|
@ -68,11 +67,13 @@ import com.owncloud.android.lib.common.UserInfo;
|
|||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;
|
||||
import com.owncloud.android.ui.events.TokenPushEvent;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.PushUtils;
|
||||
import com.owncloud.android.utils.ThemeUtils;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
@ -221,34 +222,38 @@ public class UserInfoActivity extends FileActivity {
|
|||
ImageView backgroundImageView = appBar.findViewById(R.id.drawer_header_background);
|
||||
|
||||
String background = getStorageManager().getCapability(account.name).getServerBackground();
|
||||
int primaryColor = ThemeUtils.primaryColor(getAccount(), false, this);
|
||||
int primaryColor = ThemeUtils.primaryColor(account, false, this);
|
||||
|
||||
if (URLUtil.isValidUrl(background)) {
|
||||
Drawable backgroundResource;
|
||||
OwnCloudVersion ownCloudVersion = AccountUtils.getServerVersion(account);
|
||||
if (ownCloudVersion.compareTo(OwnCloudVersion.nextcloud_13) >= 0) {
|
||||
backgroundResource = getResources().getDrawable(R.drawable.background_nc13);
|
||||
} else {
|
||||
backgroundResource = getResources().getDrawable(R.drawable.background);
|
||||
}
|
||||
|
||||
// background image
|
||||
SimpleTarget target = new SimpleTarget<Drawable>() {
|
||||
SimpleTarget<Drawable> target = new SimpleTarget<Drawable>() {
|
||||
@Override
|
||||
public void onResourceReady(Drawable resource, GlideAnimation glideAnimation) {
|
||||
public void onResourceReady(@NonNull Drawable resource,
|
||||
@Nullable Transition<? super Drawable> transition) {
|
||||
Drawable[] drawables = {new ColorDrawable(primaryColor), resource};
|
||||
LayerDrawable layerDrawable = new LayerDrawable(drawables);
|
||||
backgroundImageView.setImageDrawable(layerDrawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
public void onLoadFailed(@Nullable Drawable errorDrawable) {
|
||||
Drawable[] drawables = {new ColorDrawable(primaryColor),
|
||||
getResources().getDrawable(R.drawable.background)};
|
||||
backgroundResource};
|
||||
LayerDrawable layerDrawable = new LayerDrawable(drawables);
|
||||
backgroundImageView.setImageDrawable(layerDrawable);
|
||||
}
|
||||
};
|
||||
|
||||
Glide.with(this)
|
||||
.load(background)
|
||||
.centerCrop()
|
||||
.placeholder(R.drawable.background)
|
||||
.error(R.drawable.background)
|
||||
.crossFade()
|
||||
.into(target);
|
||||
DisplayUtils.downloadImage(background, R.drawable.background, R.drawable.background, target,
|
||||
GlideKey.url(background), this);
|
||||
} else {
|
||||
// plain color
|
||||
backgroundImageView.setImageDrawable(new ColorDrawable(primaryColor));
|
||||
|
@ -259,8 +264,8 @@ public class UserInfoActivity extends FileActivity {
|
|||
|
||||
private void populateUserInfoUi(UserInfo userInfo) {
|
||||
userName.setText(account.name);
|
||||
avatar.setTag(account.name);
|
||||
DisplayUtils.setAvatar(account, this, mCurrentAccountAvatarRadiusDimension, getResources(), avatar, this);
|
||||
|
||||
DisplayUtils.setAvatar(account, this, avatar, mCurrentAccountAvatarRadiusDimension);
|
||||
|
||||
int tint = ThemeUtils.primaryColor(account, true, this);
|
||||
|
||||
|
@ -485,6 +490,7 @@ public class UserInfoActivity extends FileActivity {
|
|||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
View view = inflater.inflate(R.layout.user_info_details_table_item, parent, false);
|
||||
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
*
|
||||
* @author Andy Scherzinger
|
||||
* Copyright (C) 2016 ownCloud Inc.
|
||||
* <p/>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
* <p/>
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* <p/>
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -155,10 +155,7 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements
|
|||
|
||||
private void setAvatar(AccountViewHolderItem viewHolder, Account account) {
|
||||
try {
|
||||
View viewItem = viewHolder.imageViewItem;
|
||||
viewItem.setTag(account.name);
|
||||
DisplayUtils.setAvatar(account, this, mAccountAvatarRadiusDimension, mContext.getResources(), viewItem,
|
||||
mContext);
|
||||
DisplayUtils.setAvatar(account, mContext, viewHolder.imageViewItem, mAccountAvatarRadiusDimension);
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Error calculating RGB value for account list item.", e);
|
||||
// use user icon as a fallback
|
||||
|
|
|
@ -22,8 +22,6 @@ package com.owncloud.android.ui.adapter;
|
|||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.PictureDrawable;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Spannable;
|
||||
|
@ -44,12 +42,6 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.GenericRequestBuilder;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.model.StreamEncoder;
|
||||
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
|
||||
import com.caverock.androidsvg.SVG;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
|
@ -63,12 +55,7 @@ import com.owncloud.android.lib.resources.files.FileUtils;
|
|||
import com.owncloud.android.ui.interfaces.ActivityListInterface;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
import com.owncloud.android.utils.glide.CustomGlideStreamLoader;
|
||||
import com.owncloud.android.utils.svg.SvgDecoder;
|
||||
import com.owncloud.android.utils.svg.SvgDrawableTranscoder;
|
||||
import com.owncloud.android.utils.svg.SvgSoftwareLayerSetter;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -175,7 +162,8 @@ public class ActivityListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
}
|
||||
|
||||
if (!TextUtils.isEmpty(activity.getIcon())) {
|
||||
downloadIcon(activity.getIcon(), activityViewHolder.activityIcon);
|
||||
DisplayUtils.downloadSVG(activity.getIcon(), R.drawable.ic_activity_light_grey,
|
||||
R.drawable.ic_activity_light_grey, activityViewHolder.activityIcon, context);
|
||||
}
|
||||
|
||||
if (activity.getRichSubjectElement() != null &&
|
||||
|
@ -240,20 +228,11 @@ public class ActivityListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
// No Folder
|
||||
if (!file.isFolder()) {
|
||||
if (MimeTypeUtil.isImage(file) || MimeTypeUtil.isVideo(file)) {
|
||||
int placeholder;
|
||||
|
||||
if (MimeTypeUtil.isImage(file)) {
|
||||
placeholder = R.drawable.file_image;
|
||||
if (TextUtils.isEmpty(file.getEtag())) {
|
||||
DisplayUtils.downloadActivityThumbnail(file, fileIcon, client, context);
|
||||
} else {
|
||||
placeholder = R.drawable.file_movie;
|
||||
DisplayUtils.downloadThumbnail(file, fileIcon, client, context);
|
||||
}
|
||||
|
||||
String uri = client.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" + px + "/" + px +
|
||||
Uri.encode(file.getRemotePath(), "/");
|
||||
|
||||
Glide.with(context).using(new CustomGlideStreamLoader()).load(uri).placeholder(placeholder)
|
||||
.error(placeholder).into(fileIcon); // using custom fetcher
|
||||
|
||||
} else {
|
||||
if (isDetailView) {
|
||||
fileIcon.setVisibility(View.GONE);
|
||||
|
@ -274,27 +253,6 @@ public class ActivityListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
}
|
||||
}
|
||||
|
||||
private void downloadIcon(String icon, ImageView itemViewType) {
|
||||
GenericRequestBuilder<Uri, InputStream, SVG, PictureDrawable> requestBuilder = Glide.with(context)
|
||||
.using(Glide.buildStreamModelLoader(Uri.class, context), InputStream.class)
|
||||
.from(Uri.class)
|
||||
.as(SVG.class)
|
||||
.transcode(new SvgDrawableTranscoder(), PictureDrawable.class)
|
||||
.sourceEncoder(new StreamEncoder())
|
||||
.cacheDecoder(new FileToStreamDecoder<>(new SvgDecoder()))
|
||||
.decoder(new SvgDecoder())
|
||||
.placeholder(R.drawable.ic_activity)
|
||||
.error(R.drawable.ic_activity)
|
||||
.animate(android.R.anim.fade_in)
|
||||
.listener(new SvgSoftwareLayerSetter<>());
|
||||
|
||||
Uri uri = Uri.parse(icon);
|
||||
requestBuilder
|
||||
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
|
||||
.load(uri)
|
||||
.into(itemViewType);
|
||||
}
|
||||
|
||||
private SpannableStringBuilder addClickablePart(RichElement richElement) {
|
||||
String text = richElement.getRichSubject();
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder(text);
|
||||
|
|
|
@ -23,7 +23,6 @@ package com.owncloud.android.ui.adapter;
|
|||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.DataSetObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
@ -37,7 +36,6 @@ import android.widget.ListView;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.db.PreferenceManager;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.ui.interfaces.LocalFileListFragmentInterface;
|
||||
|
@ -45,6 +43,7 @@ import com.owncloud.android.utils.DisplayUtils;
|
|||
import com.owncloud.android.utils.FileSortOrder;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
import com.owncloud.android.utils.ThemeUtils;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
@ -192,9 +191,14 @@ public class LocalFileListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
gridViewHolder.checkbox.setImageResource(R.drawable.ic_checkbox_blank_outline);
|
||||
}
|
||||
|
||||
gridViewHolder.thumbnail.setTag(file.hashCode());
|
||||
setThumbnail(file, gridViewHolder.thumbnail);
|
||||
|
||||
if (MimeTypeUtil.isVideo(file)) {
|
||||
gridViewHolder.playIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
gridViewHolder.playIcon.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (file.isDirectory()) {
|
||||
gridViewHolder.checkbox.setVisibility(View.GONE);
|
||||
} else {
|
||||
|
@ -236,45 +240,10 @@ public class LocalFileListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
if (file.isDirectory()) {
|
||||
thumbnailView.setImageDrawable(MimeTypeUtil.getDefaultFolderIcon(mContext));
|
||||
} else {
|
||||
thumbnailView.setImageResource(R.drawable.file);
|
||||
|
||||
/* Cancellation needs do be checked and done before changing the drawable in fileIcon, or
|
||||
* {@link ThumbnailsCacheManager#cancelPotentialThumbnailWork} will NEVER cancel any task.
|
||||
*/
|
||||
boolean allowedToCreateNewThumbnail = ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailView);
|
||||
|
||||
|
||||
// get Thumbnail if file is image
|
||||
if (MimeTypeUtil.isImage(file)) {
|
||||
// Thumbnail in Cache?
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
ThumbnailsCacheManager.PREFIX_THUMBNAIL + file.hashCode()
|
||||
);
|
||||
if (thumbnail != null) {
|
||||
thumbnailView.setImageBitmap(thumbnail);
|
||||
} else {
|
||||
|
||||
// generate new Thumbnail
|
||||
if (allowedToCreateNewThumbnail) {
|
||||
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
||||
new ThumbnailsCacheManager.ThumbnailGenerationTask(thumbnailView);
|
||||
if (MimeTypeUtil.isVideo(file)) {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultVideo;
|
||||
} else {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultImg;
|
||||
}
|
||||
final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable =
|
||||
new ThumbnailsCacheManager.AsyncThumbnailDrawable(
|
||||
mContext.getResources(),
|
||||
thumbnail,
|
||||
task
|
||||
);
|
||||
thumbnailView.setImageDrawable(asyncDrawable);
|
||||
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, null));
|
||||
Log_OC.v(TAG, "Executing task to generate a new thumbnail");
|
||||
|
||||
} // else, already being generated, don't restart it
|
||||
}
|
||||
if (MimeTypeUtil.isImage(file) || MimeTypeUtil.isVideo(file)) {
|
||||
int placeholder = MimeTypeUtil.isImage(file) ? R.drawable.file_image : R.drawable.file_movie;
|
||||
DisplayUtils.localImage(file, placeholder, placeholder, thumbnailView, GlideKey.localFile(file),
|
||||
mContext);
|
||||
} else {
|
||||
thumbnailView.setImageDrawable(MimeTypeUtil.getFileTypeIcon(null, file.getName(), mContext));
|
||||
}
|
||||
|
@ -544,6 +513,7 @@ public class LocalFileListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
private final TextView fileName;
|
||||
private final ImageView checkbox;
|
||||
private final LinearLayout itemLayout;
|
||||
private final ImageView playIcon;
|
||||
|
||||
private LocalFileListGridViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
@ -552,6 +522,7 @@ public class LocalFileListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
fileName = itemView.findViewById(R.id.Filename);
|
||||
checkbox = itemView.findViewById(R.id.custom_checkbox);
|
||||
itemLayout = itemView.findViewById(R.id.ListItemLayout);
|
||||
playIcon = itemView.findViewById(R.id.play_icon);
|
||||
|
||||
itemView.findViewById(R.id.sharedIcon).setVisibility(View.GONE);
|
||||
itemView.findViewById(R.id.favorite_action).setVisibility(View.GONE);
|
||||
|
|
|
@ -23,7 +23,6 @@ import android.content.Intent;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.PictureDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
|
@ -41,12 +40,6 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.GenericRequestBuilder;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.model.StreamEncoder;
|
||||
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
|
||||
import com.caverock.androidsvg.SVG;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
|
@ -57,9 +50,6 @@ import com.owncloud.android.lib.resources.notifications.models.RichObject;
|
|||
import com.owncloud.android.ui.activity.NotificationsActivity;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.ThemeUtils;
|
||||
import com.owncloud.android.utils.svg.SvgDecoder;
|
||||
import com.owncloud.android.utils.svg.SvgDrawableTranscoder;
|
||||
import com.owncloud.android.utils.svg.SvgSoftwareLayerSetter;
|
||||
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
|
@ -68,7 +58,6 @@ import org.apache.commons.httpclient.methods.GetMethod;
|
|||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -130,7 +119,8 @@ public class NotificationListAdapter extends RecyclerView.Adapter<NotificationLi
|
|||
|
||||
// Todo set proper action icon (to be clarified how to pick)
|
||||
if (!TextUtils.isEmpty(notification.getIcon())) {
|
||||
downloadIcon(notification.getIcon(), holder.icon);
|
||||
DisplayUtils.downloadSVG(notification.getIcon(), R.drawable.ic_notification, R.drawable.ic_notification,
|
||||
holder.icon, notificationsActivity);
|
||||
}
|
||||
|
||||
// add action buttons
|
||||
|
@ -237,28 +227,6 @@ public class NotificationListAdapter extends RecyclerView.Adapter<NotificationLi
|
|||
}
|
||||
}
|
||||
|
||||
private void downloadIcon(String icon, ImageView itemViewType) {
|
||||
GenericRequestBuilder<Uri, InputStream, SVG, PictureDrawable> requestBuilder = Glide.with(notificationsActivity)
|
||||
.using(Glide.buildStreamModelLoader(Uri.class, notificationsActivity), InputStream.class)
|
||||
.from(Uri.class)
|
||||
.as(SVG.class)
|
||||
.transcode(new SvgDrawableTranscoder(), PictureDrawable.class)
|
||||
.sourceEncoder(new StreamEncoder())
|
||||
.cacheDecoder(new FileToStreamDecoder<>(new SvgDecoder()))
|
||||
.decoder(new SvgDecoder())
|
||||
.placeholder(R.drawable.ic_notification)
|
||||
.error(R.drawable.ic_notification)
|
||||
.animate(android.R.anim.fade_in)
|
||||
.listener(new SvgSoftwareLayerSetter<>());
|
||||
|
||||
|
||||
Uri uri = Uri.parse(icon);
|
||||
requestBuilder
|
||||
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
|
||||
.load(uri)
|
||||
.into(itemViewType);
|
||||
}
|
||||
|
||||
private void openLink(String link) {
|
||||
notificationsActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(link)));
|
||||
}
|
||||
|
|
|
@ -21,16 +21,16 @@
|
|||
|
||||
package com.owncloud.android.ui.adapter;
|
||||
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -41,16 +41,18 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.request.target.CustomViewTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.datamodel.VirtualFolderType;
|
||||
import com.owncloud.android.db.PreferenceManager;
|
||||
import com.owncloud.android.db.ProviderMeta;
|
||||
import com.owncloud.android.files.services.FileDownloader;
|
||||
import com.owncloud.android.files.services.FileUploader;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
@ -88,6 +90,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
private final FileUploader.FileUploaderBinder uploaderBinder;
|
||||
private final OperationsService.OperationsServiceBinder operationsServiceBinder;
|
||||
private Context mContext;
|
||||
private OwnCloudClient client;
|
||||
private List<OCFile> mFiles = new ArrayList<>();
|
||||
private List<OCFile> mFilesAll = new ArrayList<>();
|
||||
private boolean mHideItemOptions;
|
||||
|
@ -107,15 +110,15 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
private static final int VIEWTYPE_ITEM = 1;
|
||||
private static final int VIEWTYPE_IMAGE = 2;
|
||||
|
||||
private List<ThumbnailsCacheManager.ThumbnailGenerationTask> asyncTasks = new ArrayList<>();
|
||||
private boolean onlyOnDevice = false;
|
||||
|
||||
public OCFileListAdapter(Context context, ComponentsGetter transferServiceGetter,
|
||||
public OCFileListAdapter(Context context, OwnCloudClient client, ComponentsGetter transferServiceGetter,
|
||||
OCFileListFragmentInterface ocFileListFragmentInterface, boolean argHideItemOptions,
|
||||
boolean gridView) {
|
||||
|
||||
this.ocFileListFragmentInterface = ocFileListFragmentInterface;
|
||||
mContext = context;
|
||||
this.client = client;
|
||||
mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);
|
||||
mHideItemOptions = argHideItemOptions;
|
||||
this.gridView = gridView;
|
||||
|
@ -124,9 +127,6 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
downloaderBinder = transferServiceGetter.getFileDownloaderBinder();
|
||||
uploaderBinder = transferServiceGetter.getFileUploaderBinder();
|
||||
operationsServiceBinder = transferServiceGetter.getOperationsServiceBinder();
|
||||
|
||||
// initialise thumbnails cache on background thread
|
||||
new ThumbnailsCacheManager.InitDiskCacheTask().execute();
|
||||
}
|
||||
|
||||
public boolean isMultiSelect() {
|
||||
|
@ -263,8 +263,13 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
|
||||
boolean gridImage = MimeTypeUtil.isImage(file) || MimeTypeUtil.isVideo(file);
|
||||
|
||||
gridViewHolder.thumbnail.setTag(file.getFileId());
|
||||
setThumbnail(file, gridViewHolder.thumbnail);
|
||||
setThumbnail(file, gridViewHolder);
|
||||
|
||||
if (MimeTypeUtil.isVideo(file)) {
|
||||
gridViewHolder.playIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
gridViewHolder.playIcon.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (isCheckedFile(file)) {
|
||||
gridViewHolder.itemLayout.setBackgroundColor(mContext.getResources()
|
||||
|
@ -373,53 +378,43 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
}
|
||||
}
|
||||
|
||||
private void setThumbnail(OCFile file, ImageView thumbnailView) {
|
||||
private void setThumbnail(OCFile file, OCFileListGridImageViewHolder gridImageViewHolder) {
|
||||
ImageView thumbnailView = gridImageViewHolder.thumbnail;
|
||||
|
||||
if (file.isFolder()) {
|
||||
thumbnailView.setImageDrawable(MimeTypeUtil.getFolderTypeIcon(file.isSharedWithMe() ||
|
||||
file.isSharedWithSharee(), file.isSharedViaLink(), file.isEncrypted(), file.getMountType(),
|
||||
mContext));
|
||||
} else {
|
||||
if ((MimeTypeUtil.isImage(file) || MimeTypeUtil.isVideo(file)) && file.getRemoteId() != null) {
|
||||
// Thumbnail in cache?
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
ThumbnailsCacheManager.PREFIX_THUMBNAIL + file.getRemoteId()
|
||||
);
|
||||
|
||||
if (thumbnail != null && !file.needsUpdateThumbnail()) {
|
||||
if (MimeTypeUtil.isVideo(file)) {
|
||||
Bitmap withOverlay = ThumbnailsCacheManager.addVideoOverlay(thumbnail);
|
||||
thumbnailView.setImageBitmap(withOverlay);
|
||||
} else {
|
||||
thumbnailView.setImageBitmap(thumbnail);
|
||||
}
|
||||
} else {
|
||||
// generate new thumbnail
|
||||
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailView)) {
|
||||
try {
|
||||
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
||||
new ThumbnailsCacheManager.ThumbnailGenerationTask(thumbnailView, mStorageManager,
|
||||
mAccount, asyncTasks);
|
||||
|
||||
if (thumbnail == null) {
|
||||
if (MimeTypeUtil.isVideo(file)) {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultVideo;
|
||||
} else {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultImg;
|
||||
}
|
||||
}
|
||||
final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable =
|
||||
new ThumbnailsCacheManager.AsyncThumbnailDrawable(mContext.getResources(),
|
||||
thumbnail, task);
|
||||
thumbnailView.setImageDrawable(asyncDrawable);
|
||||
asyncTasks.add(task);
|
||||
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file,
|
||||
file.getRemoteId()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log_OC.d(TAG, "ThumbnailGenerationTask : " + e.getMessage());
|
||||
}
|
||||
}
|
||||
if (client == null) {
|
||||
client = AccountUtils.getClientForCurrentAccount(mContext);
|
||||
}
|
||||
|
||||
CustomViewTarget thumbnailTarget = new CustomViewTarget<ImageView, Drawable>(thumbnailView) {
|
||||
@Override
|
||||
protected void onResourceCleared(@Nullable Drawable placeholder) {
|
||||
thumbnailView.setImageDrawable(placeholder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(@Nullable Drawable errorDrawable) {
|
||||
int placeholder = MimeTypeUtil.isVideo(file) ? R.drawable.file_movie : R.drawable.file_image;
|
||||
thumbnailView.setImageResource(placeholder);
|
||||
gridImageViewHolder.playIcon.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Drawable resource,
|
||||
@Nullable Transition<? super Drawable> transition) {
|
||||
thumbnailView.setImageDrawable(resource);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
DisplayUtils.downloadThumbnail(file, thumbnailTarget, client, mContext);
|
||||
|
||||
if ("image/png".equalsIgnoreCase(file.getMimeType())) {
|
||||
thumbnailView.setBackgroundColor(mContext.getResources().getColor(R.color.background_color));
|
||||
}
|
||||
|
@ -789,20 +784,6 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
return ret;
|
||||
}
|
||||
|
||||
public void cancelAllPendingTasks() {
|
||||
for (ThumbnailsCacheManager.ThumbnailGenerationTask task : asyncTasks) {
|
||||
if (task != null) {
|
||||
task.cancel(true);
|
||||
if (task.getGetMethod() != null) {
|
||||
Log_OC.d(TAG, "cancel: abort get method directly");
|
||||
task.getGetMethod().abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asyncTasks.clear();
|
||||
}
|
||||
|
||||
public void setGridView(boolean bool) {
|
||||
gridView = bool;
|
||||
}
|
||||
|
@ -838,6 +819,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
private final ImageView localFileIndicator;
|
||||
private final ImageView shared;
|
||||
private final ImageView checkbox;
|
||||
private final ImageView playIcon;
|
||||
private final LinearLayout itemLayout;
|
||||
|
||||
private OCFileListGridImageViewHolder(View itemView) {
|
||||
|
@ -849,6 +831,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
localFileIndicator = itemView.findViewById(R.id.localFileIndicator);
|
||||
shared = itemView.findViewById(R.id.sharedIcon);
|
||||
checkbox = itemView.findViewById(R.id.custom_checkbox);
|
||||
playIcon = itemView.findViewById(R.id.play_icon);
|
||||
itemLayout = itemView.findViewById(R.id.ListItemLayout);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
package com.owncloud.android.ui.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -37,8 +38,10 @@ import com.afollestad.sectionedrecyclerview.SectionedViewHolder;
|
|||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.datamodel.MediaFolderType;
|
||||
import com.owncloud.android.datamodel.SyncedFolderDisplayItem;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
import com.owncloud.android.utils.ThemeUtils;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
@ -179,21 +182,8 @@ public class SyncedFolderAdapter extends SectionedRecyclerViewAdapter<SyncedFold
|
|||
if (mSyncFolderItems.get(section).getFilePaths() != null) {
|
||||
File file = new File(mSyncFolderItems.get(section).getFilePaths().get(relativePosition));
|
||||
|
||||
ThumbnailsCacheManager.MediaThumbnailGenerationTask task =
|
||||
new ThumbnailsCacheManager.MediaThumbnailGenerationTask(holder.image, mContext);
|
||||
|
||||
ThumbnailsCacheManager.AsyncMediaThumbnailDrawable asyncDrawable =
|
||||
new ThumbnailsCacheManager.AsyncMediaThumbnailDrawable(
|
||||
mContext.getResources(),
|
||||
ThumbnailsCacheManager.mDefaultImg,
|
||||
task
|
||||
);
|
||||
holder.image.setImageDrawable(asyncDrawable);
|
||||
|
||||
task.execute(file);
|
||||
|
||||
// set proper tag
|
||||
holder.image.setTag(file.hashCode());
|
||||
int placeholder = MimeTypeUtil.isImage(file) ? R.drawable.file_image : R.drawable.file_movie;
|
||||
DisplayUtils.localImage(file, placeholder, placeholder, holder.image, GlideKey.localFile(file), mContext);
|
||||
|
||||
holder.itemView.setTag(relativePosition % mGridWidth);
|
||||
|
||||
|
@ -208,8 +198,9 @@ public class SyncedFolderAdapter extends SectionedRecyclerViewAdapter<SyncedFold
|
|||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
public MainViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(
|
||||
viewType == VIEW_TYPE_HEADER ?
|
||||
R.layout.synced_folders_item_header : R.layout.grid_sync_item, parent, false);
|
||||
|
|
|
@ -23,7 +23,6 @@ package com.owncloud.android.ui.adapter;
|
|||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -35,15 +34,15 @@ import android.widget.TextView;
|
|||
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.db.PreferenceManager;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.files.TrashbinFile;
|
||||
import com.owncloud.android.ui.interfaces.TrashbinActivityInterface;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.FileSortOrder;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -64,17 +63,15 @@ public class TrashbinListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
private List<TrashbinFile> files;
|
||||
private Context context;
|
||||
private Account account;
|
||||
private FileDataStorageManager storageManager;
|
||||
private OwnCloudClient client;
|
||||
|
||||
private List<ThumbnailsCacheManager.ThumbnailGenerationTask> asyncTasks = new ArrayList<>();
|
||||
|
||||
public TrashbinListAdapter(TrashbinActivityInterface trashbinActivityInterface,
|
||||
FileDataStorageManager storageManager, Context context) {
|
||||
public TrashbinListAdapter(TrashbinActivityInterface trashbinActivityInterface, Context context) {
|
||||
this.files = new ArrayList<>();
|
||||
this.trashbinActivityInterface = trashbinActivityInterface;
|
||||
this.account = AccountUtils.getCurrentOwnCloudAccount(context);
|
||||
this.storageManager = storageManager;
|
||||
this.context = context;
|
||||
|
||||
client = AccountUtils.getClientForCurrentAccount(context);
|
||||
}
|
||||
|
||||
public void setTrashbinFiles(List<Object> trashbinFiles, boolean clear) {
|
||||
|
@ -113,7 +110,6 @@ public class TrashbinListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
trashbinFileViewHolder.itemLayout.setOnClickListener(v -> trashbinActivityInterface.onItemClicked(file));
|
||||
|
||||
// thumbnail
|
||||
trashbinFileViewHolder.thumbnail.setTag(file.getRemoteId());
|
||||
setThumbnail(file, trashbinFileViewHolder.thumbnail);
|
||||
|
||||
// fileName
|
||||
|
@ -208,42 +204,21 @@ public class TrashbinListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
if (file.isFolder()) {
|
||||
thumbnailView.setImageDrawable(MimeTypeUtil.getDefaultFolderIcon(context));
|
||||
} else {
|
||||
if ((MimeTypeUtil.isImage(file) || MimeTypeUtil.isVideo(file)) && file.getRemoteId() != null) {
|
||||
// Thumbnail in cache?
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
ThumbnailsCacheManager.PREFIX_THUMBNAIL + file.getRemoteId()
|
||||
);
|
||||
if (MimeTypeUtil.isImageOrVideo(file)) {
|
||||
try {
|
||||
int placeholder = MimeTypeUtil.isImage(file) ? R.drawable.file_image : R.drawable.file_movie;
|
||||
|
||||
if (thumbnail != null) {
|
||||
if (MimeTypeUtil.isVideo(file)) {
|
||||
Bitmap withOverlay = ThumbnailsCacheManager.addVideoOverlay(thumbnail);
|
||||
thumbnailView.setImageBitmap(withOverlay);
|
||||
} else {
|
||||
thumbnailView.setImageBitmap(thumbnail);
|
||||
int px = DisplayUtils.getThumbnailDimension();
|
||||
|
||||
String url = DisplayUtils.getThumbnailUri(client, file, px);
|
||||
DisplayUtils.downloadImage(url, placeholder, placeholder, thumbnailView, client,
|
||||
GlideKey.trashbinThumbnail(file), context);
|
||||
|
||||
if ("image/png".equalsIgnoreCase(file.getMimeType())) {
|
||||
thumbnailView.setBackgroundColor(context.getResources().getColor(R.color.background_color));
|
||||
}
|
||||
} else {
|
||||
// generate new thumbnail
|
||||
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailView)) {
|
||||
try {
|
||||
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
||||
new ThumbnailsCacheManager.ThumbnailGenerationTask(thumbnailView, storageManager,
|
||||
account, asyncTasks);
|
||||
|
||||
final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable =
|
||||
new ThumbnailsCacheManager.AsyncThumbnailDrawable(context.getResources(),
|
||||
thumbnail, task);
|
||||
thumbnailView.setImageDrawable(asyncDrawable);
|
||||
asyncTasks.add(task);
|
||||
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file,
|
||||
file.getRemoteId()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log_OC.d(TAG, "ThumbnailGenerationTask : " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("image/png".equalsIgnoreCase(file.getMimeType())) {
|
||||
thumbnailView.setBackgroundColor(context.getResources().getColor(R.color.background_color));
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, e.getMessage());
|
||||
}
|
||||
} else {
|
||||
thumbnailView.setImageDrawable(MimeTypeUtil.getFileTypeIcon(file.getMimeType(), file.getFileName(),
|
||||
|
@ -266,20 +241,6 @@ public class TrashbinListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
return files.size() + 1;
|
||||
}
|
||||
|
||||
public void cancelAllPendingTasks() {
|
||||
for (ThumbnailsCacheManager.ThumbnailGenerationTask task : asyncTasks) {
|
||||
if (task != null) {
|
||||
task.cancel(true);
|
||||
if (task.getGetMethod() != null) {
|
||||
Log_OC.d(TAG, "cancel: abort get method directly");
|
||||
task.getGetMethod().abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
asyncTasks.clear();
|
||||
}
|
||||
|
||||
public void setSortOrder(FileSortOrder sortOrder) {
|
||||
PreferenceManager.setSortOrder(context, null, sortOrder);
|
||||
files = sortOrder.sortTrashbinFiles(files);
|
||||
|
|
|
@ -24,7 +24,6 @@ package com.owncloud.android.ui.adapter;
|
|||
import android.accounts.Account;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.format.DateUtils;
|
||||
|
@ -42,17 +41,18 @@ import com.afollestad.sectionedrecyclerview.SectionedViewHolder;
|
|||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.datamodel.UploadsStorageManager;
|
||||
import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus;
|
||||
import com.owncloud.android.db.OCUpload;
|
||||
import com.owncloud.android.db.UploadResult;
|
||||
import com.owncloud.android.files.services.FileUploader;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.ui.activity.FileActivity;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
import com.owncloud.android.utils.ThemeUtils;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
|
@ -66,6 +66,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
|||
public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedViewHolder> {
|
||||
|
||||
private static final String TAG = UploadListAdapter.class.getSimpleName();
|
||||
private OwnCloudClient client;
|
||||
|
||||
private ProgressListener mProgressListener;
|
||||
|
||||
|
@ -130,6 +131,9 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
|
|||
fixAndSortItems(mUploadsStorageManager.getFinishedUploadsForCurrentAccount());
|
||||
}
|
||||
};
|
||||
|
||||
client = AccountUtils.getClientForCurrentAccount(mParentActivity);
|
||||
|
||||
loadUploadItemsFromDb();
|
||||
}
|
||||
|
||||
|
@ -285,100 +289,31 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
|
|||
});
|
||||
}
|
||||
} else {
|
||||
itemViewHolder.itemLayout.setOnClickListener(v ->
|
||||
onUploadItemClick(item));
|
||||
itemViewHolder.itemLayout.setOnClickListener(v -> onUploadItemClick(item));
|
||||
}
|
||||
|
||||
// Set icon or thumbnail
|
||||
itemViewHolder.thumbnail.setImageResource(R.drawable.file);
|
||||
if (MimeTypeUtil.isImageOrVideo(new File(item.getLocalPath()))) {
|
||||
if (item.getUploadStatus() == UploadStatus.UPLOAD_SUCCEEDED) {
|
||||
|
||||
/*
|
||||
* Cancellation needs do be checked and done before changing the drawable in fileIcon, or
|
||||
* {@link ThumbnailsCacheManager#cancelPotentialWork} will NEVER cancel any task.
|
||||
*/
|
||||
OCFile fakeFileToCheatThumbnailsCacheManagerInterface = new OCFile(item.getRemotePath());
|
||||
fakeFileToCheatThumbnailsCacheManagerInterface.setStoragePath(item.getLocalPath());
|
||||
fakeFileToCheatThumbnailsCacheManagerInterface.setMimetype(item.getMimeType());
|
||||
OCFile file = mParentActivity.getStorageManager().getFileByPath(item.getRemotePath());
|
||||
|
||||
boolean allowedToCreateNewThumbnail = ThumbnailsCacheManager.cancelPotentialThumbnailWork(
|
||||
fakeFileToCheatThumbnailsCacheManagerInterface, itemViewHolder.thumbnail
|
||||
);
|
||||
|
||||
// TODO this code is duplicated; refactor to a common place
|
||||
if (MimeTypeUtil.isImage(fakeFileToCheatThumbnailsCacheManagerInterface)
|
||||
&& fakeFileToCheatThumbnailsCacheManagerInterface.getRemoteId() != null &&
|
||||
item.getUploadStatus() == UploadStatus.UPLOAD_SUCCEEDED) {
|
||||
// Thumbnail in Cache?
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
String.valueOf(fakeFileToCheatThumbnailsCacheManagerInterface.getRemoteId())
|
||||
);
|
||||
if (thumbnail != null && !fakeFileToCheatThumbnailsCacheManagerInterface.needsUpdateThumbnail()) {
|
||||
itemViewHolder.thumbnail.setImageBitmap(thumbnail);
|
||||
} else {
|
||||
// generate new Thumbnail
|
||||
if (allowedToCreateNewThumbnail) {
|
||||
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
||||
new ThumbnailsCacheManager.ThumbnailGenerationTask(
|
||||
itemViewHolder.thumbnail, mParentActivity.getStorageManager(), mParentActivity.getAccount()
|
||||
);
|
||||
if (thumbnail == null) {
|
||||
if (MimeTypeUtil.isVideo(fakeFileToCheatThumbnailsCacheManagerInterface)) {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultVideo;
|
||||
} else {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultImg;
|
||||
}
|
||||
}
|
||||
final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable =
|
||||
new ThumbnailsCacheManager.AsyncThumbnailDrawable(
|
||||
mParentActivity.getResources(),
|
||||
thumbnail,
|
||||
task
|
||||
);
|
||||
itemViewHolder.thumbnail.setImageDrawable(asyncDrawable);
|
||||
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(
|
||||
fakeFileToCheatThumbnailsCacheManagerInterface, null));
|
||||
if (file != null) {
|
||||
DisplayUtils.downloadThumbnail(file, itemViewHolder.thumbnail, client, mParentActivity);
|
||||
}
|
||||
}
|
||||
|
||||
if ("image/png".equals(item.getMimeType())) {
|
||||
itemViewHolder.thumbnail.setBackgroundColor(mParentActivity.getResources()
|
||||
.getColor(R.color.background_color));
|
||||
}
|
||||
|
||||
|
||||
} else if (MimeTypeUtil.isImage(fakeFileToCheatThumbnailsCacheManagerInterface)) {
|
||||
File file = new File(item.getLocalPath());
|
||||
// Thumbnail in Cache?
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
String.valueOf(file.hashCode()));
|
||||
if (thumbnail != null) {
|
||||
itemViewHolder.thumbnail.setImageBitmap(thumbnail);
|
||||
} else {
|
||||
// generate new Thumbnail
|
||||
if (allowedToCreateNewThumbnail) {
|
||||
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
||||
new ThumbnailsCacheManager.ThumbnailGenerationTask(itemViewHolder.thumbnail);
|
||||
File file = new File(item.getLocalPath());
|
||||
|
||||
if (MimeTypeUtil.isVideo(file)) {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultVideo;
|
||||
} else {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultImg;
|
||||
}
|
||||
int placeholder = MimeTypeUtil.isImage(new File(item.getLocalPath())) ?
|
||||
R.drawable.file_image : R.drawable.file_movie;
|
||||
DisplayUtils.localImage(file, placeholder, placeholder, itemViewHolder.thumbnail,
|
||||
GlideKey.localFile(file), mParentActivity);
|
||||
|
||||
final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable =
|
||||
new ThumbnailsCacheManager.AsyncThumbnailDrawable(mParentActivity.getResources(), thumbnail,
|
||||
task);
|
||||
|
||||
itemViewHolder.thumbnail.setImageDrawable(asyncDrawable);
|
||||
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, null));
|
||||
Log_OC.v(TAG, "Executing task to generate a new thumbnail");
|
||||
if ("image/png".equalsIgnoreCase(item.getMimeType())) {
|
||||
itemViewHolder.thumbnail.setBackgroundColor(mParentActivity.getResources()
|
||||
.getColor(R.color.background_color));
|
||||
}
|
||||
}
|
||||
|
||||
if ("image/png".equalsIgnoreCase(item.getMimeType())) {
|
||||
itemViewHolder.thumbnail.setBackgroundColor(mParentActivity.getResources()
|
||||
.getColor(R.color.background_color));
|
||||
}
|
||||
} else {
|
||||
itemViewHolder.thumbnail.setImageDrawable(MimeTypeUtil.getFileTypeIcon(item.getMimeType(), fileName,
|
||||
account, mParentActivity));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*
|
||||
* ownCloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
|
@ -22,7 +22,6 @@ package com.owncloud.android.ui.adapter;
|
|||
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -31,10 +30,9 @@ import android.widget.SimpleAdapter;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncThumbnailDrawable;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
|
||||
|
@ -43,21 +41,19 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
public class UploaderAdapter extends SimpleAdapter {
|
||||
|
||||
private Context mContext;
|
||||
private Account mAccount;
|
||||
private FileDataStorageManager mStorageManager;
|
||||
private LayoutInflater inflater;
|
||||
private OwnCloudClient client;
|
||||
|
||||
public UploaderAdapter(Context context,
|
||||
List<? extends Map<String, ?>> data, int resource, String[] from,
|
||||
int[] to, FileDataStorageManager storageManager, Account account) {
|
||||
int[] to, Account account) {
|
||||
super(context, data, resource, from, to);
|
||||
mAccount = account;
|
||||
mStorageManager = storageManager;
|
||||
mContext = context;
|
||||
inflater = (LayoutInflater) mContext
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
client = AccountUtils.getClientForCurrentAccount(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,7 +70,6 @@ public class UploaderAdapter extends SimpleAdapter {
|
|||
filename.setText(file.getFileName());
|
||||
|
||||
ImageView fileIcon = vi.findViewById(R.id.thumbnail);
|
||||
fileIcon.setTag(file.getFileId());
|
||||
|
||||
TextView lastModV = vi.findViewById(R.id.last_mod);
|
||||
lastModV.setText(DisplayUtils.getRelativeTimestamp(mContext, file.getModificationTimestamp()));
|
||||
|
@ -97,35 +92,8 @@ public class UploaderAdapter extends SimpleAdapter {
|
|||
file.getMountType(), mContext));
|
||||
} else {
|
||||
// get Thumbnail if file is image
|
||||
if (MimeTypeUtil.isImage(file) && file.getRemoteId() != null) {
|
||||
// Thumbnail in Cache?
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
String.valueOf(file.getRemoteId())
|
||||
);
|
||||
if (thumbnail != null && !file.needsUpdateThumbnail()) {
|
||||
fileIcon.setImageBitmap(thumbnail);
|
||||
} else {
|
||||
// generate new Thumbnail
|
||||
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, fileIcon)) {
|
||||
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
|
||||
new ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon, mStorageManager,
|
||||
mAccount);
|
||||
if (thumbnail == null) {
|
||||
if (MimeTypeUtil.isVideo(file)) {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultVideo;
|
||||
} else {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultImg;
|
||||
}
|
||||
}
|
||||
final AsyncThumbnailDrawable asyncDrawable = new AsyncThumbnailDrawable(
|
||||
mContext.getResources(),
|
||||
thumbnail,
|
||||
task
|
||||
);
|
||||
fileIcon.setImageDrawable(asyncDrawable);
|
||||
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, file.getRemoteId()));
|
||||
}
|
||||
}
|
||||
if (MimeTypeUtil.isImageOrVideo(file)) {
|
||||
DisplayUtils.downloadThumbnail(file, fileIcon, client, mContext);
|
||||
} else {
|
||||
fileIcon.setImageDrawable(
|
||||
MimeTypeUtil.getFileTypeIcon(file.getMimeType(), file.getFileName(), mAccount, mContext)
|
||||
|
@ -135,6 +103,4 @@ public class UploaderAdapter extends SimpleAdapter {
|
|||
|
||||
return vi;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@ package com.owncloud.android.ui.fragment;
|
|||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -42,14 +45,20 @@ import android.widget.PopupMenu;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.files.FileMenuFilter;
|
||||
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
|
||||
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
|
||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.ui.activity.FileActivity;
|
||||
|
@ -61,8 +70,12 @@ import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
|
|||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
import com.owncloud.android.utils.ThemeUtils;
|
||||
import com.owncloud.android.utils.glide.GlideApp;
|
||||
import com.owncloud.android.utils.glide.GlideContainer;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
@ -552,56 +565,86 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
|
|||
* @param file a {@link OCFile} to be previewed
|
||||
*/
|
||||
private void setFilePreview(OCFile file) {
|
||||
Bitmap resizedImage;
|
||||
|
||||
if (MimeTypeUtil.isImage(file) && activity != null) {
|
||||
String tagId = String.valueOf(ThumbnailsCacheManager.PREFIX_RESIZED_IMAGE + getFile().getRemoteId());
|
||||
resizedImage = ThumbnailsCacheManager.getBitmapFromDiskCache(tagId);
|
||||
if (MimeTypeUtil.isImage(file) && activity != null && activity.getPreviewImageView() != null) {
|
||||
try {
|
||||
Account account = AccountUtils.getCurrentOwnCloudAccount(getContext());
|
||||
OwnCloudAccount ocAccount = new OwnCloudAccount(account, MainApp.getAppContext());
|
||||
|
||||
OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
||||
getClientFor(ocAccount, MainApp.getAppContext());
|
||||
|
||||
int thumbnailW = DisplayUtils.getThumbnailDimension();
|
||||
int thumbnailH = DisplayUtils.getThumbnailDimension();
|
||||
|
||||
if (resizedImage != null && !file.needsUpdateThumbnail()) {
|
||||
activity.setPreviewImageBitmap(resizedImage);
|
||||
activatePreviewImage();
|
||||
previewLoaded = true;
|
||||
} else {
|
||||
// show thumbnail while loading resized image
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
String.valueOf(ThumbnailsCacheManager.PREFIX_THUMBNAIL + getFile().getRemoteId()));
|
||||
|
||||
if (thumbnail != null) {
|
||||
activity.setPreviewImageBitmap(thumbnail);
|
||||
} else {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultImg;
|
||||
}
|
||||
// Thumbnail
|
||||
GlideContainer container = new GlideContainer();
|
||||
int placeholder = MimeTypeUtil.isVideo(getFile()) ? R.drawable.file_movie : R.drawable.file_image;
|
||||
|
||||
// generate new resized image
|
||||
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(getFile(), activity.getPreviewImageView()) &&
|
||||
mContainerActivity.getStorageManager() != null) {
|
||||
final ThumbnailsCacheManager.ResizedImageGenerationTask task =
|
||||
new ThumbnailsCacheManager.ResizedImageGenerationTask(this,
|
||||
activity.getPreviewImageView(),
|
||||
mContainerActivity.getStorageManager(),
|
||||
mContainerActivity.getStorageManager().getAccount());
|
||||
container.url = mClient.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" +
|
||||
thumbnailW + "/" + thumbnailH + Uri.encode(getFile().getRemotePath(), "/");
|
||||
container.client = mClient;
|
||||
container.key = GlideKey.serverThumbnail(getFile());
|
||||
|
||||
if (resizedImage == null) {
|
||||
resizedImage = thumbnail;
|
||||
}
|
||||
// resized image
|
||||
GlideContainer containerResizedImage = new GlideContainer();
|
||||
|
||||
final ThumbnailsCacheManager.AsyncResizedImageDrawable asyncDrawable =
|
||||
new ThumbnailsCacheManager.AsyncResizedImageDrawable(
|
||||
MainApp.getAppContext().getResources(),
|
||||
resizedImage,
|
||||
task
|
||||
);
|
||||
Point p = DisplayUtils.getScreenDimension();
|
||||
int pxW = p.x;
|
||||
int pxH = p.y;
|
||||
|
||||
activity.setPreviewImageDrawable(asyncDrawable);
|
||||
activatePreviewImage();
|
||||
previewLoaded = true;
|
||||
task.execute(getFile());
|
||||
}
|
||||
containerResizedImage.url = mClient.getBaseUri() + "/index.php/core/preview.png?file="
|
||||
+ URLEncoder.encode(getFile().getRemotePath())
|
||||
+ "&x=" + pxW + "&y=" + pxH + "&a=1&mode=cover&forceIcon=0";
|
||||
containerResizedImage.key = GlideKey.resizedImage(getFile());
|
||||
containerResizedImage.client = mClient;
|
||||
|
||||
GlideApp.with(requireContext())
|
||||
.asBitmap()
|
||||
.load(container)
|
||||
.placeholder(placeholder)
|
||||
.priority(Priority.IMMEDIATE)
|
||||
.onlyRetrieveFromCache(true)
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onLoadFailed(@Nullable Drawable errorDrawable) {
|
||||
activity.setPreviewImageDrawable(activity.getResources()
|
||||
.getDrawable(placeholder));
|
||||
loadResizedImage(containerResizedImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource,
|
||||
@Nullable Transition<? super Bitmap> transition) {
|
||||
activity.setPreviewImageBitmap(resource);
|
||||
loadResizedImage(containerResizedImage);
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadResizedImage(GlideContainer containerResizedImage) {
|
||||
GlideApp.with(requireContext())
|
||||
.asBitmap()
|
||||
.load(containerResizedImage)
|
||||
.priority(Priority.IMMEDIATE)
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource,
|
||||
@Nullable Transition<? super Bitmap> transition) {
|
||||
activity.setPreviewImageBitmap(resource);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables buttons for a file being downloaded
|
||||
*/
|
||||
|
|
|
@ -25,8 +25,6 @@ package com.owncloud.android.ui.fragment;
|
|||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -68,9 +66,7 @@ import com.owncloud.android.datamodel.OCFile;
|
|||
import com.owncloud.android.datamodel.VirtualFolderType;
|
||||
import com.owncloud.android.db.PreferenceManager;
|
||||
import com.owncloud.android.files.FileMenuFilter;
|
||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
@ -113,7 +109,6 @@ import org.greenrobot.eventbus.ThreadMode;
|
|||
import org.parceler.Parcels;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
@ -175,6 +170,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
private boolean searchFragment;
|
||||
private SearchEvent searchEvent;
|
||||
private AsyncTask remoteOperationAsyncTask;
|
||||
private OwnCloudClient client;
|
||||
|
||||
private enum MenuItemAddRemove {
|
||||
DO_NOTHING, REMOVE_SORT, REMOVE_GRID_AND_SORT, ADD_SORT, ADD_GRID_AND_SORT, ADD_GRID_AND_SORT_WITH_SEARCH,
|
||||
|
@ -288,13 +284,6 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
super.onDetach();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mAdapter.cancelAllPendingTasks();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -312,7 +301,9 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
mOnlyFoldersClickable = args != null && args.getBoolean(ARG_ONLY_FOLDERS_CLICKABLE, false);
|
||||
boolean hideItemOptions = args != null && args.getBoolean(ARG_HIDE_ITEM_OPTIONS, false);
|
||||
|
||||
mAdapter = new OCFileListAdapter(getActivity(), mContainerActivity, this, hideItemOptions,
|
||||
client = AccountUtils.getClientForCurrentAccount(getContext());
|
||||
|
||||
mAdapter = new OCFileListAdapter(getActivity(), client, mContainerActivity, this, hideItemOptions,
|
||||
isGridViewPreferred(mFile));
|
||||
setRecyclerViewAdapter(mAdapter);
|
||||
|
||||
|
@ -1317,36 +1308,21 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
public void onMessageEvent(FavoriteEvent event) {
|
||||
Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
|
||||
|
||||
OwnCloudAccount ocAccount = null;
|
||||
AccountManager mAccountMgr = AccountManager.get(getActivity());
|
||||
|
||||
try {
|
||||
ocAccount = new OwnCloudAccount(
|
||||
currentAccount,
|
||||
MainApp.getAppContext()
|
||||
);
|
||||
String userId = mAccountMgr.getUserData(currentAccount,
|
||||
com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
|
||||
|
||||
OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
||||
getClientFor(ocAccount, MainApp.getAppContext());
|
||||
if (TextUtils.isEmpty(userId)) {
|
||||
userId = client.getCredentials().getUsername();
|
||||
}
|
||||
|
||||
String userId = mAccountMgr.getUserData(currentAccount,
|
||||
com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
|
||||
ToggleFavoriteOperation toggleFavoriteOperation = new ToggleFavoriteOperation(event.shouldFavorite,
|
||||
event.remotePath, userId);
|
||||
RemoteOperationResult remoteOperationResult = toggleFavoriteOperation.execute(client);
|
||||
|
||||
if (TextUtils.isEmpty(userId)) {
|
||||
userId = mClient.getCredentials().getUsername();
|
||||
}
|
||||
|
||||
ToggleFavoriteOperation toggleFavoriteOperation = new ToggleFavoriteOperation(event.shouldFavorite,
|
||||
event.remotePath, userId);
|
||||
RemoteOperationResult remoteOperationResult = toggleFavoriteOperation.execute(mClient);
|
||||
|
||||
if (remoteOperationResult.isSuccess()) {
|
||||
mAdapter.setFavoriteAttributeForItemID(event.remoteId, event.shouldFavorite);
|
||||
}
|
||||
|
||||
} catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException | AuthenticatorException
|
||||
| IOException | OperationCanceledException e) {
|
||||
Log_OC.e(TAG, "Error processing event", e);
|
||||
if (remoteOperationResult.isSuccess()) {
|
||||
mAdapter.setFavoriteAttributeForItemID(event.remoteId, event.shouldFavorite);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1475,35 +1451,16 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
|
||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||
public void onMessageEvent(EncryptionEvent event) {
|
||||
Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
|
||||
ToggleEncryptionOperation toggleEncryptionOperation = new ToggleEncryptionOperation(event.localId,
|
||||
event.remotePath, event.shouldBeEncrypted);
|
||||
RemoteOperationResult remoteOperationResult = toggleEncryptionOperation.execute(client, true);
|
||||
|
||||
OwnCloudAccount ocAccount = null;
|
||||
try {
|
||||
ocAccount = new OwnCloudAccount(currentAccount, MainApp.getAppContext());
|
||||
|
||||
OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
||||
getClientFor(ocAccount, MainApp.getAppContext());
|
||||
|
||||
ToggleEncryptionOperation toggleEncryptionOperation = new ToggleEncryptionOperation(event.localId,
|
||||
event.remotePath, event.shouldBeEncrypted);
|
||||
RemoteOperationResult remoteOperationResult = toggleEncryptionOperation.execute(mClient, true);
|
||||
|
||||
if (remoteOperationResult.isSuccess()) {
|
||||
mAdapter.setEncryptionAttributeForItemID(event.remoteId, event.shouldBeEncrypted);
|
||||
} else if (remoteOperationResult.getHttpCode() == HttpStatus.SC_FORBIDDEN) {
|
||||
Snackbar.make(getRecyclerView(), R.string.end_to_end_encryption_folder_not_empty, Snackbar.LENGTH_LONG).show();
|
||||
} else {
|
||||
Snackbar.make(getRecyclerView(), R.string.common_error_unknown, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
} catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
|
||||
Log_OC.e(TAG, "Account not found", e);
|
||||
} catch (AuthenticatorException e) {
|
||||
Log_OC.e(TAG, "Authentication failed", e);
|
||||
} catch (IOException e) {
|
||||
Log_OC.e(TAG, "IO error", e);
|
||||
} catch (OperationCanceledException e) {
|
||||
Log_OC.e(TAG, "Operation has been canceled", e);
|
||||
if (remoteOperationResult.isSuccess()) {
|
||||
mAdapter.setEncryptionAttributeForItemID(event.remoteId, event.shouldBeEncrypted);
|
||||
} else if (remoteOperationResult.getHttpCode() == HttpStatus.SC_FORBIDDEN) {
|
||||
Snackbar.make(getRecyclerView(), R.string.end_to_end_encryption_folder_not_empty, Snackbar.LENGTH_LONG).show();
|
||||
} else {
|
||||
Snackbar.make(getRecyclerView(), R.string.common_error_unknown, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ package com.owncloud.android.ui.fragment;
|
|||
|
||||
import android.accounts.Account;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
@ -47,8 +47,9 @@ import android.widget.ScrollView;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.shares.OCShare;
|
||||
import com.owncloud.android.lib.resources.shares.ShareType;
|
||||
|
@ -62,8 +63,8 @@ import com.owncloud.android.utils.MimeTypeUtil;
|
|||
import com.owncloud.android.utils.ThemeUtils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Fragment for Sharing a file with sharees (users or groups) or creating
|
||||
|
@ -189,17 +190,20 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
|
|||
// Setup layout
|
||||
// Image
|
||||
ImageView icon = view.findViewById(R.id.shareFileIcon);
|
||||
icon.setImageDrawable(
|
||||
MimeTypeUtil.getFileTypeIcon(mFile.getMimeType(), mFile.getFileName(), mAccount, getContext())
|
||||
);
|
||||
if (MimeTypeUtil.isImage(mFile)) {
|
||||
String remoteId = String.valueOf(mFile.getRemoteId());
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(remoteId);
|
||||
if (thumbnail != null) {
|
||||
icon.setImageBitmap(thumbnail);
|
||||
}
|
||||
}
|
||||
Context context = getContext();
|
||||
|
||||
if ((MimeTypeUtil.isImage(mFile) || MimeTypeUtil.isVideo(mFile)) && mFile.getRemoteId() != null) {
|
||||
OwnCloudClient client = AccountUtils.getClientForCurrentAccount(context);
|
||||
DisplayUtils.downloadThumbnail(mFile, icon, client, context);
|
||||
|
||||
if ("image/png".equalsIgnoreCase(mFile.getMimeType())) {
|
||||
icon.setBackgroundColor(container.getResources().getColor(R.color.background_color));
|
||||
}
|
||||
} else {
|
||||
icon.setImageDrawable(MimeTypeUtil.getFileTypeIcon(mFile.getMimeType(), mFile.getFileName(),
|
||||
mAccount, getContext()));
|
||||
}
|
||||
|
||||
// Title
|
||||
TextView title = view.findViewById(R.id.shareWithUsersSectionTitle);
|
||||
title.setTextColor(accentColor);
|
||||
|
|
|
@ -32,7 +32,6 @@ import android.database.Cursor;
|
|||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
@ -61,15 +60,15 @@ import android.widget.RelativeLayout;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
import com.evernote.android.job.util.support.PersistableBundleCompat;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.files.services.FileDownloader;
|
||||
import com.owncloud.android.jobs.ContactsImportJob;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.ui.TextDrawable;
|
||||
import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
|
||||
|
@ -79,6 +78,7 @@ import com.owncloud.android.utils.BitmapUtils;
|
|||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.PermissionUtil;
|
||||
import com.owncloud.android.utils.ThemeUtils;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
@ -168,6 +168,8 @@ public class ContactListFragment extends FileFragment {
|
|||
View view = inflater.inflate(R.layout.contactlist_fragment, container, false);
|
||||
ButterKnife.bind(this, view);
|
||||
|
||||
OwnCloudClient client = AccountUtils.getClientForCurrentAccount(requireContext());
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
ContactsPreferenceActivity contactsPreferenceActivity = (ContactsPreferenceActivity) getActivity();
|
||||
|
@ -184,7 +186,7 @@ public class ContactListFragment extends FileFragment {
|
|||
recyclerView = view.findViewById(R.id.contactlist_recyclerview);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
contactListAdapter = new ContactListAdapter(getContext(), vCards);
|
||||
contactListAdapter = new ContactListAdapter(getContext(), client, vCards);
|
||||
} else {
|
||||
Set<Integer> checkedItems = new HashSet<>();
|
||||
int[] itemsArray = savedInstanceState.getIntArray(CHECKED_ITEMS_ARRAY_KEY);
|
||||
|
@ -196,7 +198,7 @@ public class ContactListFragment extends FileFragment {
|
|||
if (checkedItems.size() > 0) {
|
||||
onMessageEvent(new VCardToggleEvent(true));
|
||||
}
|
||||
contactListAdapter = new ContactListAdapter(getContext(), vCards, checkedItems);
|
||||
contactListAdapter = new ContactListAdapter(getContext(), client, vCards, checkedItems);
|
||||
}
|
||||
recyclerView.setAdapter(contactListAdapter);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
|
@ -572,20 +574,22 @@ class ContactListAdapter extends RecyclerView.Adapter<ContactListFragment.Contac
|
|||
|
||||
private List<VCard> vCards;
|
||||
private Set<Integer> checkedVCards;
|
||||
|
||||
private OwnCloudClient client;
|
||||
|
||||
private Context context;
|
||||
|
||||
ContactListAdapter(Context context, List<VCard> vCards) {
|
||||
ContactListAdapter(Context context, OwnCloudClient client, List<VCard> vCards) {
|
||||
this.vCards = vCards;
|
||||
this.context = context;
|
||||
this.checkedVCards = new HashSet<>();
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
ContactListAdapter(Context context, List<VCard> vCards,
|
||||
Set<Integer> checkedVCards) {
|
||||
ContactListAdapter(Context context, OwnCloudClient client, List<VCard> vCards, Set<Integer> checkedVCards) {
|
||||
this.vCards = vCards;
|
||||
this.context = context;
|
||||
this.checkedVCards = checkedVCards;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public int getCheckedCount() {
|
||||
|
@ -667,20 +671,8 @@ class ContactListAdapter extends RecyclerView.Adapter<ContactListFragment.Contac
|
|||
|
||||
imageView.setImageDrawable(drawable);
|
||||
} else if (url != null) {
|
||||
SimpleTarget target = new SimpleTarget<Drawable>() {
|
||||
@Override
|
||||
public void onResourceReady(Drawable resource, GlideAnimation glideAnimation) {
|
||||
imageView.setImageDrawable(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
super.onLoadFailed(e, errorDrawable);
|
||||
imageView.setImageDrawable(errorDrawable);
|
||||
}
|
||||
};
|
||||
DisplayUtils.downloadIcon(context, url, target, R.drawable.ic_user, imageView.getWidth(),
|
||||
imageView.getHeight());
|
||||
DisplayUtils.downloadImage(url, R.drawable.ic_user, R.drawable.ic_user, imageView, client,
|
||||
GlideKey.url(url), context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.Point;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -71,6 +73,9 @@ import com.owncloud.android.utils.ConnectivityUtils;
|
|||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.FileStorageUtils;
|
||||
import com.owncloud.android.utils.UriUtils;
|
||||
import com.owncloud.android.utils.glide.GlideApp;
|
||||
import com.owncloud.android.utils.glide.GlideContainer;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
|
@ -83,6 +88,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -699,23 +705,81 @@ public class FileOperationsHelper {
|
|||
|
||||
public void sendCachedImage(OCFile file, String packageName, String activityName) {
|
||||
if (file != null) {
|
||||
Context context = MainApp.getAppContext();
|
||||
Intent sendIntent = new Intent(Intent.ACTION_SEND);
|
||||
// set MimeType
|
||||
sendIntent.setType(file.getMimeType());
|
||||
sendIntent.setComponent(new ComponentName(packageName, activityName));
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" +
|
||||
context.getResources().getString(R.string.image_cache_provider_authority) +
|
||||
file.getRemotePath()));
|
||||
sendIntent.putExtra(Intent.ACTION_SEND, true); // Send Action
|
||||
|
||||
mFileActivity.startActivity(Intent.createChooser(sendIntent,
|
||||
context.getString(R.string.actionbar_send_file)));
|
||||
|
||||
LoadCachedImageAsyncTask loadTask = new LoadCachedImageAsyncTask(packageName, activityName, mFileActivity);
|
||||
loadTask.execute(file);
|
||||
|
||||
|
||||
} else {
|
||||
Log_OC.wtf(TAG, "Trying to send a NULL OCFile");
|
||||
}
|
||||
}
|
||||
|
||||
private static class LoadCachedImageAsyncTask extends AsyncTask<OCFile, Void, Uri> {
|
||||
private OCFile file;
|
||||
private String packageName;
|
||||
private String activityName;
|
||||
private FileActivity fileActivity;
|
||||
|
||||
LoadCachedImageAsyncTask(String packageName, String activityName, FileActivity fileActivity) {
|
||||
this.packageName = packageName;
|
||||
this.activityName = activityName;
|
||||
this.fileActivity = fileActivity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri doInBackground(OCFile... ocFiles) {
|
||||
File cachedImage = null;
|
||||
file = ocFiles[0];
|
||||
|
||||
try {
|
||||
GlideContainer container = new GlideContainer();
|
||||
container.key = GlideKey.resizedImage(file);
|
||||
|
||||
Point p = DisplayUtils.getScreenDimension();
|
||||
int pxW = p.x;
|
||||
int pxH = p.y;
|
||||
|
||||
cachedImage = GlideApp
|
||||
.with(fileActivity)
|
||||
.downloadOnly()
|
||||
.load(container)
|
||||
.submit(pxW, pxH)
|
||||
.get(); // needs to be called on background thread
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Log_OC.e(TAG, "Error generating image", e);
|
||||
}
|
||||
|
||||
Context context = MainApp.getAppContext();
|
||||
|
||||
return FileProvider.getUriForFile(context,
|
||||
context.getResources().getString(R.string.file_provider_authority), cachedImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Uri uri) {
|
||||
super.onPostExecute(uri);
|
||||
|
||||
if (uri != null) {
|
||||
Context context = MainApp.getAppContext();
|
||||
Intent sendIntent = new Intent(Intent.ACTION_SEND);
|
||||
|
||||
// set MimeType
|
||||
sendIntent.setType(file.getMimeType());
|
||||
sendIntent.setComponent(new ComponentName(packageName, activityName));
|
||||
// sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" +
|
||||
// context.getResources().getString(R.string.image_cache_provider_authority) +
|
||||
// file.getRemotePath()));
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
|
||||
sendIntent.putExtra(Intent.ACTION_SEND, true); // Send Action
|
||||
|
||||
fileActivity.startActivity(Intent.createChooser(sendIntent,
|
||||
context.getString(R.string.actionbar_send_file)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPictureAs(OCFile file, View view) {
|
||||
if (file != null) {
|
||||
Context context = MainApp.getAppContext();
|
||||
|
|
|
@ -29,12 +29,14 @@ import android.graphics.drawable.BitmapDrawable;
|
|||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.graphics.drawable.PictureDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Process;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
|
@ -51,14 +53,20 @@ import android.widget.ProgressBar;
|
|||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.caverock.androidsvg.SVG;
|
||||
import com.caverock.androidsvg.SVGParseException;
|
||||
import com.github.chrisbanes.photoview.PhotoView;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.files.FileMenuFilter;
|
||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
|
||||
|
@ -67,11 +75,15 @@ import com.owncloud.android.utils.BitmapUtils;
|
|||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.MimeType;
|
||||
import com.owncloud.android.utils.MimeTypeUtil;
|
||||
import com.owncloud.android.utils.glide.GlideApp;
|
||||
import com.owncloud.android.utils.glide.GlideContainer;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import pl.droidsonroids.gif.GifDrawable;
|
||||
|
@ -221,54 +233,66 @@ public class PreviewImageFragment extends FileFragment {
|
|||
public void onStart() {
|
||||
super.onStart();
|
||||
if (getFile() != null) {
|
||||
mImageView.setTag(getFile().getFileId());
|
||||
|
||||
if (mShowResizedImage) {
|
||||
Bitmap resizedImage = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
String.valueOf(ThumbnailsCacheManager.PREFIX_RESIZED_IMAGE + getFile().getRemoteId()));
|
||||
try {
|
||||
Account account = AccountUtils.getCurrentOwnCloudAccount(getContext());
|
||||
OwnCloudAccount ocAccount = new OwnCloudAccount(account, MainApp.getAppContext());
|
||||
|
||||
if (resizedImage != null && !getFile().needsUpdateThumbnail()) {
|
||||
mImageView.setImageBitmap(resizedImage);
|
||||
mImageView.setVisibility(View.VISIBLE);
|
||||
mBitmap = resizedImage;
|
||||
} else {
|
||||
// show thumbnail while loading resized image
|
||||
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
|
||||
String.valueOf(ThumbnailsCacheManager.PREFIX_THUMBNAIL + getFile().getRemoteId()));
|
||||
OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
||||
getClientFor(ocAccount, MainApp.getAppContext());
|
||||
|
||||
if (thumbnail != null) {
|
||||
mImageView.setImageBitmap(thumbnail);
|
||||
mImageView.setVisibility(View.VISIBLE);
|
||||
mBitmap = thumbnail;
|
||||
} else {
|
||||
thumbnail = ThumbnailsCacheManager.mDefaultImg;
|
||||
}
|
||||
int thumbnailW = DisplayUtils.getThumbnailDimension();
|
||||
int thumbnailH = DisplayUtils.getThumbnailDimension();
|
||||
|
||||
// generate new resized image
|
||||
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(getFile(), mImageView) &&
|
||||
mContainerActivity.getStorageManager() != null) {
|
||||
final ThumbnailsCacheManager.ResizedImageGenerationTask task =
|
||||
new ThumbnailsCacheManager.ResizedImageGenerationTask(this,
|
||||
mImageView,
|
||||
mContainerActivity.getStorageManager(),
|
||||
mContainerActivity.getStorageManager().getAccount());
|
||||
if (resizedImage == null) {
|
||||
resizedImage = thumbnail;
|
||||
}
|
||||
final ThumbnailsCacheManager.AsyncResizedImageDrawable asyncDrawable =
|
||||
new ThumbnailsCacheManager.AsyncResizedImageDrawable(
|
||||
MainApp.getAppContext().getResources(),
|
||||
resizedImage,
|
||||
task
|
||||
);
|
||||
mImageView.setImageDrawable(asyncDrawable);
|
||||
task.execute(getFile());
|
||||
}
|
||||
// Thumbnail
|
||||
GlideContainer container = new GlideContainer();
|
||||
int placeholder = MimeTypeUtil.isVideo(getFile()) ? R.drawable.file_movie : R.drawable.file_image;
|
||||
|
||||
container.url = mClient.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" +
|
||||
thumbnailW + "/" + thumbnailH + Uri.encode(getFile().getRemotePath(), "/");
|
||||
container.client = mClient;
|
||||
container.key = GlideKey.serverThumbnail(getFile());
|
||||
|
||||
// resized image
|
||||
GlideContainer containerResizedImage = new GlideContainer();
|
||||
|
||||
Point p = DisplayUtils.getScreenDimension();
|
||||
int pxW = p.x;
|
||||
int pxH = p.y;
|
||||
|
||||
containerResizedImage.url = mClient.getBaseUri() + "/index.php/core/preview.png?file="
|
||||
+ URLEncoder.encode(getFile().getRemotePath())
|
||||
+ "&x=" + pxW + "&y=" + pxH + "&a=1&mode=cover&forceIcon=0";
|
||||
containerResizedImage.key = GlideKey.resizedImage(getFile());
|
||||
containerResizedImage.client = mClient;
|
||||
|
||||
GlideApp.with(getContext())
|
||||
.asBitmap()
|
||||
.load(container)
|
||||
.placeholder(placeholder)
|
||||
.priority(Priority.IMMEDIATE)
|
||||
.onlyRetrieveFromCache(true)
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onLoadFailed(@Nullable Drawable errorDrawable) {
|
||||
mImageView.setImageResource(placeholder);
|
||||
loadResizedImage(containerResizedImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource,
|
||||
@Nullable Transition<? super Bitmap> transition) {
|
||||
mImageView.setImageBitmap(resource);
|
||||
loadResizedImage(containerResizedImage);
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, e.getMessage());
|
||||
}
|
||||
|
||||
mMultiView.setVisibility(View.GONE);
|
||||
if (getResources() != null) {
|
||||
mImageView.setBackgroundColor(getResources().getColor(R.color.black));
|
||||
}
|
||||
mImageView.setBackgroundColor(getResources().getColor(R.color.black));
|
||||
mImageView.setVisibility(View.VISIBLE);
|
||||
|
||||
} else {
|
||||
|
@ -280,6 +304,21 @@ public class PreviewImageFragment extends FileFragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void loadResizedImage(GlideContainer containerResizedImage) {
|
||||
GlideApp.with(requireContext())
|
||||
.asBitmap()
|
||||
.load(containerResizedImage)
|
||||
.priority(Priority.IMMEDIATE)
|
||||
.into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource,
|
||||
@Nullable Transition<? super Bitmap> transition) {
|
||||
mImageView.setImageBitmap(resource);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
Log_OC.d(TAG, "onStop starts");
|
||||
|
@ -482,8 +521,7 @@ public class PreviewImageFragment extends FileFragment {
|
|||
}
|
||||
|
||||
try {
|
||||
bitmapResult = BitmapUtils.decodeSampledBitmapFromFile(storagePath, minWidth,
|
||||
minHeight);
|
||||
bitmapResult = BitmapUtils.decodeSampledBitmapFromFile(storagePath, minWidth, minHeight);
|
||||
|
||||
if (isCancelled()) {
|
||||
return new LoadImage(bitmapResult, null, ocFile);
|
||||
|
|
|
@ -22,6 +22,7 @@ package com.owncloud.android.ui.preview;
|
|||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
|
@ -217,6 +218,7 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
|
|||
return super.getItemPosition(object);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
Object fragment = super.instantiateItem(container, position);
|
||||
|
|
|
@ -121,7 +121,7 @@ public class TrashbinActivity extends FileActivity implements TrashbinActivityIn
|
|||
emptyContentMessage.setText(noResultsMessage);
|
||||
emptyContentMessage.setVisibility(View.VISIBLE);
|
||||
|
||||
trashbinListAdapter = new TrashbinListAdapter(this, getStorageManager(), this);
|
||||
trashbinListAdapter = new TrashbinListAdapter(this, this);
|
||||
recyclerView.setAdapter(trashbinListAdapter);
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.setHasFooter(true);
|
||||
|
@ -226,12 +226,6 @@ public class TrashbinActivity extends FileActivity implements TrashbinActivityIn
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
trashbinListAdapter.cancelAllPendingTasks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
trashbinPresenter.navigateUp();
|
||||
|
@ -286,4 +280,4 @@ public class TrashbinActivity extends FileActivity implements TrashbinActivityIn
|
|||
emptyContentIcon.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import android.graphics.Point;
|
|||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.PictureDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -50,39 +51,50 @@ import android.text.format.DateUtils;
|
|||
import android.text.style.StyleSpan;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.GenericRequestBuilder;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.Key;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.model.StreamEncoder;
|
||||
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.CustomViewTarget;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.caverock.androidsvg.SVG;
|
||||
import com.bumptech.glide.signature.ObjectKey;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.files.SearchOperation;
|
||||
import com.owncloud.android.lib.resources.files.ServerFileInterface;
|
||||
import com.owncloud.android.ui.TextDrawable;
|
||||
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
||||
import com.owncloud.android.ui.events.MenuItemClickEvent;
|
||||
import com.owncloud.android.ui.events.SearchEvent;
|
||||
import com.owncloud.android.ui.fragment.OCFileListFragment;
|
||||
import com.owncloud.android.utils.svg.SvgDecoder;
|
||||
import com.owncloud.android.utils.svg.SvgDrawableTranscoder;
|
||||
import com.owncloud.android.utils.glide.GlideApp;
|
||||
import com.owncloud.android.utils.glide.GlideAvatar;
|
||||
import com.owncloud.android.utils.glide.GlideContainer;
|
||||
import com.owncloud.android.utils.glide.GlideKey;
|
||||
import com.owncloud.android.utils.glide.GlideOCFileType;
|
||||
import com.owncloud.android.utils.glide.GlideOcFile;
|
||||
import com.owncloud.android.utils.svg.SvgSoftwareLayerSetter;
|
||||
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
@ -90,6 +102,7 @@ import java.lang.reflect.Constructor;
|
|||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.IDN;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
@ -98,6 +111,7 @@ import java.util.HashSet;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* A helper class for UI/display related operations.
|
||||
|
@ -117,6 +131,7 @@ public final class DisplayUtils {
|
|||
private static final int BYTE_SIZE_DIVIDER = 1024;
|
||||
private static final double BYTE_SIZE_DIVIDER_DOUBLE = 1024.0;
|
||||
private static final int DATE_TIME_PARTS_SIZE = 2;
|
||||
private static final String ETAG = "ETag";
|
||||
|
||||
private static Map<String, String> mimeType2HumanReadable;
|
||||
|
||||
|
@ -433,18 +448,28 @@ public final class DisplayUtils {
|
|||
* fetches and sets the avatar of the given account in the passed callContext
|
||||
*
|
||||
* @param account the account to be used to connect to server
|
||||
* @param avatarRadius the avatar radius
|
||||
* @param resources reference for density information
|
||||
* @param callContext which context is called to set the generated avatar
|
||||
*/
|
||||
public static void setAvatar(@NonNull Account account, AvatarGenerationListener listener,
|
||||
float avatarRadius, Resources resources, Object callContext, Context context) {
|
||||
// public static void setAvatar(@NonNull Account account, Context context, SimpleTarget<Drawable> target) {
|
||||
//
|
||||
// AccountManager accountManager = AccountManager.get(context);
|
||||
// String userId = accountManager.getUserData(account,
|
||||
// com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
|
||||
//
|
||||
// setAvatar(account, userId, context, target);
|
||||
// }
|
||||
|
||||
/**
|
||||
* fetches and sets the avatar of the given account in the passed callContext
|
||||
*
|
||||
* @param account the account to be used to connect to server
|
||||
*/
|
||||
public static void setAvatar(@NonNull Account account, Context context, Object view, float radius) {
|
||||
|
||||
AccountManager accountManager = AccountManager.get(context);
|
||||
String userId = accountManager.getUserData(account,
|
||||
com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
|
||||
|
||||
setAvatar(account, userId, listener, avatarRadius, resources, callContext, context);
|
||||
setAvatar(account, userId, context, view, radius);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -452,54 +477,158 @@ public final class DisplayUtils {
|
|||
*
|
||||
* @param account the account to be used to connect to server
|
||||
* @param userId the userId which avatar should be set
|
||||
* @param avatarRadius the avatar radius
|
||||
* @param resources reference for density information
|
||||
* @param callContext which context is called to set the generated avatar
|
||||
* @param view where the image is shown in
|
||||
*/
|
||||
public static void setAvatar(@NonNull Account account, @NonNull String userId, AvatarGenerationListener listener,
|
||||
float avatarRadius, Resources resources, Object callContext, Context context) {
|
||||
if (callContext instanceof View) {
|
||||
((View) callContext).setContentDescription(account.name);
|
||||
public static void setAvatar(@NonNull Account account, @NonNull String userId, Context context, Object view,
|
||||
float radius) {
|
||||
Drawable placeholder = context.getResources().getDrawable(R.drawable.ic_user);
|
||||
|
||||
Drawable fallback;
|
||||
try {
|
||||
fallback = TextDrawable.createAvatar(account.name, radius);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
fallback = placeholder;
|
||||
}
|
||||
|
||||
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
|
||||
// show avatar immediately, might be outdated
|
||||
if (view instanceof ImageView) {
|
||||
ImageView imageView = (ImageView) view;
|
||||
imageView.setContentDescription(account.name);
|
||||
|
||||
String serverName = account.name.substring(account.name.lastIndexOf('@') + 1, account.name.length());
|
||||
String eTag = arbitraryDataProvider.getValue(userId + "@" + serverName, ThumbnailsCacheManager.AVATAR);
|
||||
String avatarKey = "a_" + userId + "_" + serverName + "_" + eTag;
|
||||
GlideApp.with(context)
|
||||
.asBitmap()
|
||||
.load(new GlideAvatar(GlideKey.avatar(account, userId, context), null))
|
||||
.apply(RequestOptions.circleCropTransform())
|
||||
.placeholder(placeholder)
|
||||
.error(fallback)
|
||||
.onlyRetrieveFromCache(true)
|
||||
.into(imageView);
|
||||
} else {
|
||||
GlideApp.with(context)
|
||||
.load(new GlideAvatar(GlideKey.avatar(account, userId, context), null))
|
||||
.apply(RequestOptions.circleCropTransform())
|
||||
.placeholder(placeholder)
|
||||
.error(fallback)
|
||||
.onlyRetrieveFromCache(true)
|
||||
.into((SimpleTarget<Drawable>) view);
|
||||
}
|
||||
|
||||
AsyncTask task = new AsyncTask<Object, Void, InputStream>() {
|
||||
|
||||
// first show old one
|
||||
Drawable avatar = BitmapUtils.bitmapToCircularBitmapDrawable(resources,
|
||||
ThumbnailsCacheManager.getBitmapFromDiskCache(avatarKey));
|
||||
GetMethod get;
|
||||
ArbitraryDataProvider arbitraryDataProvider;
|
||||
String accountName;
|
||||
|
||||
// if no one exists, show colored icon with initial char
|
||||
if (avatar == null) {
|
||||
try {
|
||||
avatar = TextDrawable.createAvatarByUserId(userId, avatarRadius);
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Error calculating RGB value for active account icon.", e);
|
||||
avatar = resources.getDrawable(R.drawable.account_circle_white);
|
||||
@Override
|
||||
protected InputStream doInBackground(Object[] objects) {
|
||||
InputStream inputStream = null;
|
||||
|
||||
// we need to create client here, as different servers can be used
|
||||
OwnCloudClient client = AccountUtils.getClientForAccount(account, context);
|
||||
|
||||
int px = getAvatarDimension(context);
|
||||
|
||||
arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
|
||||
String serverName = account.name.substring(account.name.lastIndexOf('@') + 1, account.name.length());
|
||||
accountName = userId + "@" + serverName;
|
||||
String eTag = arbitraryDataProvider.getValue(accountName, GlideKey.AVATAR_KEY);
|
||||
Log_OC.d(TAG, "glide: old etag: " + eTag);
|
||||
|
||||
try {
|
||||
String uri = client.getBaseUri() + "/index.php/avatar/" + Uri.encode(userId) + "/" + px;
|
||||
Log_OC.d("Avatar", "URI: " + uri);
|
||||
get = new GetMethod(uri);
|
||||
|
||||
// only use eTag if available
|
||||
if (!eTag.isEmpty()) {
|
||||
get.setRequestHeader("If-None-Match", eTag);
|
||||
}
|
||||
|
||||
int status = client.executeMethod(get);
|
||||
|
||||
Log_OC.d(TAG, "glide: status: " + status);
|
||||
|
||||
// we are using eTag to download a new avatar only if it changed
|
||||
switch (status) {
|
||||
case HttpStatus.SC_OK:
|
||||
case HttpStatus.SC_CREATED:
|
||||
// new avatar
|
||||
inputStream = get.getResponseBodyAsStream();
|
||||
|
||||
if (get.getResponseHeader(ETAG) != null) {
|
||||
String newETag = get.getResponseHeader(ETAG).getValue().replace("\"", "");
|
||||
Log_OC.d(TAG, "glide: new etag: " + newETag);
|
||||
arbitraryDataProvider.storeOrUpdateKeyValue(accountName, GlideKey.AVATAR_KEY, newETag);
|
||||
}
|
||||
break;
|
||||
|
||||
case HttpStatus.SC_NOT_MODIFIED:
|
||||
default:
|
||||
client.exhaustResponse(get.getResponseBodyAsStream());
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// do nothing, fallback in glide
|
||||
if (get != null) {
|
||||
get.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
return inputStream;
|
||||
}
|
||||
}
|
||||
|
||||
// check for new avatar, eTag is compared, so only new one is downloaded
|
||||
if (ThumbnailsCacheManager.cancelPotentialAvatarWork(userId, callContext)) {
|
||||
final ThumbnailsCacheManager.AvatarGenerationTask task =
|
||||
new ThumbnailsCacheManager.AvatarGenerationTask(listener, callContext, account, resources,
|
||||
avatarRadius, userId, serverName, context);
|
||||
@Override
|
||||
protected void onPostExecute(InputStream inputStream) {
|
||||
Drawable placeholder = context.getResources().getDrawable(R.drawable.ic_user);
|
||||
|
||||
final ThumbnailsCacheManager.AsyncAvatarDrawable asyncDrawable =
|
||||
new ThumbnailsCacheManager.AsyncAvatarDrawable(resources, avatar, task);
|
||||
listener.avatarGenerated(asyncDrawable, callContext);
|
||||
task.execute(userId);
|
||||
}
|
||||
Drawable fallback;
|
||||
try {
|
||||
fallback = TextDrawable.createAvatar(account.name, radius);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
fallback = placeholder;
|
||||
}
|
||||
|
||||
try {
|
||||
if (view instanceof ImageView) {
|
||||
ImageView imageView = (ImageView) view;
|
||||
imageView.setContentDescription(account.name);
|
||||
|
||||
GlideApp.with(context)
|
||||
.asBitmap()
|
||||
.load(new GlideAvatar(GlideKey.avatar(account, userId, context), inputStream))
|
||||
.apply(RequestOptions.circleCropTransform())
|
||||
.placeholder(placeholder)
|
||||
.error(fallback)
|
||||
.onlyRetrieveFromCache(inputStream == null)
|
||||
.into(imageView);
|
||||
} else {
|
||||
GlideApp.with(context)
|
||||
.load(new GlideAvatar(GlideKey.avatar(account, userId, context), inputStream))
|
||||
.apply(RequestOptions.circleCropTransform())
|
||||
.placeholder(placeholder)
|
||||
.error(fallback)
|
||||
.onlyRetrieveFromCache(inputStream == null)
|
||||
.into((SimpleTarget<Drawable>) view);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Avatar generation failed", e);
|
||||
// reset eTag
|
||||
arbitraryDataProvider.storeOrUpdateKeyValue(accountName, GlideKey.AVATAR_KEY, "");
|
||||
// context may be null
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
task.execute();
|
||||
}
|
||||
|
||||
public static void downloadIcon(Context context, String iconUrl, SimpleTarget imageView, int placeholder,
|
||||
int width, int height) {
|
||||
public static void downloadIcon(Context context, String iconUrl, SimpleTarget<Drawable> imageView, int placeholder,
|
||||
int error) {
|
||||
try {
|
||||
if (iconUrl.endsWith(".svg")) {
|
||||
downloadSVGIcon(context, iconUrl, imageView, placeholder, width, height);
|
||||
downloadSVG(iconUrl, placeholder, error, imageView, context);
|
||||
} else {
|
||||
downloadPNGIcon(context, iconUrl, imageView, placeholder);
|
||||
}
|
||||
|
@ -508,44 +637,43 @@ public final class DisplayUtils {
|
|||
}
|
||||
}
|
||||
|
||||
private static void downloadPNGIcon(Context context, String iconUrl, SimpleTarget imageView, int placeholder) {
|
||||
Glide
|
||||
.with(context)
|
||||
private static void downloadPNGIcon(Context context, String iconUrl, SimpleTarget<Drawable> imageView,
|
||||
int placeholder) {
|
||||
GlideApp.with(context)
|
||||
.load(iconUrl)
|
||||
.centerCrop()
|
||||
.placeholder(placeholder)
|
||||
.error(placeholder)
|
||||
.crossFade()
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
private static void downloadSVGIcon(Context context, String iconUrl, SimpleTarget imageView, int placeholder,
|
||||
int width, int height) {
|
||||
GenericRequestBuilder<Uri, InputStream, SVG, PictureDrawable> requestBuilder = Glide.with(context)
|
||||
.using(Glide.buildStreamModelLoader(Uri.class, context), InputStream.class)
|
||||
.from(Uri.class)
|
||||
.as(SVG.class)
|
||||
.transcode(new SvgDrawableTranscoder(), PictureDrawable.class)
|
||||
.sourceEncoder(new StreamEncoder())
|
||||
.cacheDecoder(new FileToStreamDecoder<>(new SvgDecoder(height, width)))
|
||||
.decoder(new SvgDecoder(height, width))
|
||||
public static void downloadSVG(String url, int placeholder, int error, ImageView imageView, Context context) {
|
||||
GlideApp.with(context)
|
||||
.as(PictureDrawable.class)
|
||||
.placeholder(placeholder)
|
||||
.error(placeholder)
|
||||
.animate(android.R.anim.fade_in);
|
||||
|
||||
|
||||
Uri uri = Uri.parse(iconUrl);
|
||||
requestBuilder
|
||||
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
|
||||
.load(uri)
|
||||
.fitCenter()
|
||||
.error(error)
|
||||
.listener(new SvgSoftwareLayerSetter())
|
||||
.load(url)
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
private static void downloadSVG(String url, int placeholder, int error, SimpleTarget<Drawable> imageView,
|
||||
Context context) {
|
||||
GlideApp.with(context)
|
||||
.as(PictureDrawable.class)
|
||||
.load(url)
|
||||
.placeholder(placeholder)
|
||||
.error(error)
|
||||
.listener(new SvgSoftwareLayerSetter())
|
||||
.into((SimpleTarget) imageView);
|
||||
}
|
||||
|
||||
public static Bitmap downloadImageSynchronous(Context context, String imageUrl) {
|
||||
try {
|
||||
return Glide.with(context)
|
||||
.load(imageUrl)
|
||||
return GlideApp.with(context)
|
||||
.asBitmap()
|
||||
.load(imageUrl)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
|
@ -556,6 +684,139 @@ public final class DisplayUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void localImage(File file, int placeholder, int error, ImageView view, Key key, Context context) {
|
||||
GlideApp.with(context)
|
||||
.load(file)
|
||||
.placeholder(placeholder)
|
||||
.error(error)
|
||||
.into(view);
|
||||
}
|
||||
|
||||
public static void downloadThumbnail(OCFile file, Object view, OwnCloudClient client, Context context) {
|
||||
GlideContainer container = new GlideContainer();
|
||||
|
||||
int placeholder = MimeTypeUtil.isVideo(file) ? R.drawable.file_movie : R.drawable.file_image;
|
||||
int pxW = DisplayUtils.getThumbnailDimension();
|
||||
int pxH = DisplayUtils.getThumbnailDimension();
|
||||
|
||||
container.url = client.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" + pxW + "/" + pxH +
|
||||
Uri.encode(file.getRemotePath(), "/");
|
||||
container.client = client;
|
||||
container.key = GlideKey.serverThumbnail(file);
|
||||
|
||||
if (view instanceof ImageView) {
|
||||
GlideApp.with(context)
|
||||
.load(container)
|
||||
.placeholder(placeholder)
|
||||
.error(placeholder)
|
||||
.into((ImageView) view);
|
||||
} else {
|
||||
GlideApp.with(context)
|
||||
.load(container)
|
||||
.placeholder(placeholder)
|
||||
.error(placeholder)
|
||||
.into((CustomViewTarget<ImageView, Drawable>) view);
|
||||
}
|
||||
}
|
||||
|
||||
public static void downloadActivityThumbnail(OCFile file, ImageView view, OwnCloudClient client, Context context) {
|
||||
GlideContainer container = new GlideContainer();
|
||||
|
||||
int placeholder = MimeTypeUtil.isVideo(file) ? R.drawable.file_movie : R.drawable.file_image;
|
||||
int pxW = DisplayUtils.getThumbnailDimension();
|
||||
int pxH = DisplayUtils.getThumbnailDimension();
|
||||
|
||||
container.url = client.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" + pxW + "/" + pxH +
|
||||
Uri.encode(file.getRemotePath(), "/");
|
||||
container.client = client;
|
||||
container.key = GlideKey.activityThumbnail(file);
|
||||
|
||||
GlideApp.with(context)
|
||||
.load(container)
|
||||
.placeholder(placeholder)
|
||||
.into(view);
|
||||
}
|
||||
|
||||
public static Drawable getThumbnail(OCFile file, ImageView view, OwnCloudClient client, Context context) {
|
||||
GlideContainer container = new GlideContainer();
|
||||
|
||||
int placeholder = MimeTypeUtil.isVideo(file) ? R.drawable.file_movie : R.drawable.file_image;
|
||||
int pxW = DisplayUtils.getThumbnailDimension();
|
||||
int pxH = DisplayUtils.getThumbnailDimension();
|
||||
|
||||
container.url = client.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" + pxW + "/" + pxH +
|
||||
Uri.encode(file.getRemotePath(), "/");
|
||||
container.client = client;
|
||||
container.key = GlideKey.serverThumbnail(file);
|
||||
|
||||
try {
|
||||
return GlideApp.with(context)
|
||||
.load(container)
|
||||
.placeholder(placeholder)
|
||||
.into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Log_OC.e(TAG, "Could not download image " + container.url);
|
||||
return context.getResources().getDrawable(placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
public static void downloadImage(String uri, int placeholder, int error, ImageView view, OwnCloudClient client,
|
||||
ObjectKey key, Context context) {
|
||||
GlideContainer container = new GlideContainer();
|
||||
|
||||
container.url = uri;
|
||||
container.key = key;
|
||||
container.client = client;
|
||||
|
||||
GlideApp.with(context)
|
||||
.load(container)
|
||||
.placeholder(placeholder)
|
||||
.error(error)
|
||||
.into(view);
|
||||
}
|
||||
|
||||
public static String getThumbnailUri(OwnCloudClient client, ServerFileInterface file, int size) {
|
||||
return client.getBaseUri() + "/index.php/apps/files_trashbin/preview?fileId=" +
|
||||
file.getLocalId() + "&x=" + size + "&y=" + size;
|
||||
}
|
||||
|
||||
public static void downloadImage(String uri, int placeholder, int error, SimpleTarget<Drawable> target, Key key,
|
||||
Context context) {
|
||||
GlideApp.with(context)
|
||||
.load(uri)
|
||||
.placeholder(placeholder)
|
||||
.error(error)
|
||||
.into(target);
|
||||
}
|
||||
|
||||
public static void generateResizedImage(OCFile file, Context context) {
|
||||
Point p = DisplayUtils.getScreenDimension();
|
||||
int pxW = p.x;
|
||||
int pxH = p.y;
|
||||
|
||||
try {
|
||||
GlideApp.with(context)
|
||||
.load(new GlideOcFile(file, GlideOCFileType.resizedImage))
|
||||
.downloadOnly(pxW, pxH).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Log_OC.e(TAG, "Thumbnail generation failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateThumbnail(OCFile file, String path, Context context) {
|
||||
int pxW = DisplayUtils.getThumbnailDimension();
|
||||
int pxH = DisplayUtils.getThumbnailDimension();
|
||||
|
||||
try {
|
||||
GlideApp.with(context)
|
||||
.load(new GlideOcFile(file, GlideOCFileType.thumbnail, path))
|
||||
.downloadOnly(pxW, pxH).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Log_OC.e(TAG, "Thumbnail generation failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupBottomBar(BottomNavigationView view, Resources resources, final Activity activity,
|
||||
int checkedMenuItem) {
|
||||
|
||||
|
@ -773,4 +1034,40 @@ public final class DisplayUtils {
|
|||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts size of file icon from dp to pixel
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static int getThumbnailDimension() {
|
||||
// Converts dp to pixel
|
||||
Resources r = MainApp.getAppContext().getResources();
|
||||
return Math.round(r.getDimension(R.dimen.file_icon_size_grid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts dimension of screen as point
|
||||
*
|
||||
* @return Point
|
||||
*/
|
||||
public static Point getScreenDimension() {
|
||||
WindowManager wm = (WindowManager) MainApp.getAppContext().getSystemService(Context.WINDOW_SERVICE);
|
||||
|
||||
if (wm == null) {
|
||||
// fallback to reasonable size for resized images
|
||||
return new Point(1024, 868);
|
||||
} else {
|
||||
Display display = wm.getDefaultDisplay();
|
||||
Point point = new Point();
|
||||
display.getSize(point);
|
||||
return point;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getAvatarDimension(Context context) {
|
||||
// Converts dp to pixel
|
||||
Resources r = context.getResources();
|
||||
return Math.round(r.getDimension(R.dimen.file_avatar_size));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -318,7 +318,7 @@ public final class FileStorageUtils {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static boolean moveFile(File sourceFile, File targetFile) throws IOException {
|
||||
public static boolean moveFile(File sourceFile, File targetFile) {
|
||||
if (copyFile(sourceFile, targetFile)) {
|
||||
return sourceFile.delete();
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils;
|
||||
|
||||
public class GlideUtils {
|
||||
}
|
|
@ -281,6 +281,14 @@ public final class MimeTypeUtil {
|
|||
|| MimeTypeUtil.isImage(getMimeTypeFromPath(file.getRemotePath()));
|
||||
}
|
||||
|
||||
public static boolean isImageOrVideo(ServerFileInterface file) {
|
||||
return isImage(file) || isVideo(file);
|
||||
}
|
||||
|
||||
public static boolean isImageOrVideo(File file) {
|
||||
return isImage(file) || isVideo(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file the file to be analyzed
|
||||
* @return 'True' if the file is simple text (e.g. not application-dependent, like .doc or .docx)
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class AvatarFetcher implements DataFetcher<InputStream> {
|
||||
private GlideAvatar avatar;
|
||||
|
||||
public AvatarFetcher(GlideAvatar avatar) {
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
|
||||
callback.onDataReady(avatar.getInputStream());
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
// not needed
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
// not needed
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Class<InputStream> getDataClass() {
|
||||
return InputStream.class;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DataSource getDataSource() {
|
||||
return DataSource.REMOTE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Alejandro Bautista
|
||||
* Copyright (C) 2017 Alejandro Bautista
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Custom Model for OwnCloudClient
|
||||
*/
|
||||
|
||||
public class AvatarLoader implements ModelLoader<GlideAvatar, InputStream> {
|
||||
@Nullable
|
||||
@Override
|
||||
public LoadData<InputStream> buildLoadData(@NonNull GlideAvatar avatar, int width, int height, @NonNull Options options) {
|
||||
return new LoadData<>(avatar.getKey(), new AvatarFetcher(avatar));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(@NonNull GlideAvatar a) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
||||
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class AvatarModelLoaderFactory implements ModelLoaderFactory<GlideAvatar, InputStream> {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelLoader<GlideAvatar, InputStream> build(@NonNull MultiModelLoaderFactory unused) {
|
||||
return new AvatarLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class FileFetcher implements DataFetcher<InputStream> {
|
||||
private final static String TAG = FileFetcher.class.getSimpleName();
|
||||
private String storagePath;
|
||||
private InputStream data;
|
||||
|
||||
public FileFetcher(String storagePath) {
|
||||
this.storagePath = storagePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
|
||||
try {
|
||||
data = new FileInputStream(storagePath);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log_OC.d(TAG, "Failed to open file", e);
|
||||
callback.onLoadFailed(e);
|
||||
return;
|
||||
}
|
||||
callback.onDataReady(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
if (data != null) {
|
||||
try {
|
||||
data.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
// unused
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Class<InputStream> getDataClass() {
|
||||
return InputStream.class;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DataSource getDataSource() {
|
||||
return DataSource.LOCAL;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
/**
|
||||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Alejandro Bautista
|
||||
* Copyright (C) 2017 Alejandro Bautista
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
|
@ -17,20 +18,27 @@
|
|||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
import com.bumptech.glide.load.model.stream.StreamModelLoader;
|
||||
import com.bumptech.glide.signature.ObjectKey;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Custom Model for OwnCloudClient
|
||||
*/
|
||||
public class GlideAvatar {
|
||||
private ObjectKey key;
|
||||
private InputStream inputStream;
|
||||
|
||||
public class CustomGlideStreamLoader implements StreamModelLoader<String> {
|
||||
@Override
|
||||
public DataFetcher<InputStream> getResourceFetcher(String url, int width, int height) {
|
||||
return new HttpStreamFetcher(url);
|
||||
public GlideAvatar(ObjectKey key, InputStream avatar) {
|
||||
this.key = key;
|
||||
this.inputStream = avatar;
|
||||
}
|
||||
|
||||
public ObjectKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return inputStream;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import com.bumptech.glide.signature.ObjectKey;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
|
||||
public class GlideContainer {
|
||||
public OwnCloudClient client;
|
||||
public ObjectKey key;
|
||||
public String url;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
||||
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class GlideContainerModelLoaderFactory implements ModelLoaderFactory<GlideContainer, InputStream> {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelLoader<GlideContainer, InputStream> build(@NonNull MultiModelLoaderFactory unused) {
|
||||
return new GlideContainerStreamLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Alejandro Bautista
|
||||
* Copyright (C) 2017 Alejandro Bautista
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.signature.ObjectKey;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import static com.owncloud.android.utils.glide.GlideKey.RESIZED_IMAGE_KEY;
|
||||
import static com.owncloud.android.utils.glide.GlideKey.THUMBNAIL_KEY;
|
||||
|
||||
/**
|
||||
* Custom model for Nextcloud Client
|
||||
*/
|
||||
public class GlideContainerStreamLoader implements ModelLoader<GlideContainer, InputStream> {
|
||||
@Nullable
|
||||
@Override
|
||||
public LoadData<InputStream> buildLoadData(@NonNull GlideContainer container, int width, int height,
|
||||
@NonNull Options options) {
|
||||
return new LoadData<>(container.key, new HttpStreamGlideContainerFetcher(container));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(@NonNull GlideContainer s) {
|
||||
return !s.key.equals(new ObjectKey(THUMBNAIL_KEY)) && !s.key.equals(new ObjectKey(RESIZED_IMAGE_KEY));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
|
||||
import com.bumptech.glide.signature.ObjectKey;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.lib.resources.files.TrashbinFile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public final class GlideKey {
|
||||
public static final String AVATAR_KEY = "AVATAR";
|
||||
static final String THUMBNAIL_KEY = "THUMBNAIL_";
|
||||
static final String RESIZED_IMAGE_KEY = "RESIZED_IMAGE_";
|
||||
|
||||
private GlideKey() {
|
||||
// Required empty constructor
|
||||
}
|
||||
|
||||
public static ObjectKey serverThumbnail(OCFile file) {
|
||||
return new ObjectKey(THUMBNAIL_KEY + file.getEtagOnServer());
|
||||
}
|
||||
|
||||
public static ObjectKey resizedImage(OCFile file) {
|
||||
return new ObjectKey(RESIZED_IMAGE_KEY + file.getEtagOnServer());
|
||||
}
|
||||
|
||||
public static ObjectKey localFile(File file) {
|
||||
return new ObjectKey(file.hashCode());
|
||||
}
|
||||
|
||||
public static ObjectKey url(String url) {
|
||||
return new ObjectKey(url);
|
||||
}
|
||||
|
||||
public static ObjectKey trashbinThumbnail(TrashbinFile file) {
|
||||
return new ObjectKey(THUMBNAIL_KEY + file.getRemoteId());
|
||||
}
|
||||
|
||||
public static ObjectKey activityThumbnail(OCFile file) {
|
||||
return new ObjectKey(THUMBNAIL_KEY + file.getRemoteId());
|
||||
}
|
||||
|
||||
public static ObjectKey avatar(Account account, String userId, Context context) {
|
||||
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
|
||||
|
||||
String serverName = account.name.substring(account.name.lastIndexOf('@') + 1, account.name.length());
|
||||
String eTag = arbitraryDataProvider.getValue(userId + "@" + serverName, GlideKey.AVATAR_KEY);
|
||||
|
||||
return new ObjectKey("a_" + userId + "_" + serverName + "_" + eTag);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
public enum GlideOCFileType {
|
||||
resizedImage, thumbnail
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
|
||||
public class GlideOcFile {
|
||||
private OCFile file;
|
||||
private GlideOCFileType type;
|
||||
private String path = "";
|
||||
|
||||
public GlideOcFile(OCFile file, GlideOCFileType type) {
|
||||
this.file = file;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public GlideOcFile(OCFile file, GlideOCFileType type, String path) {
|
||||
this.file = file;
|
||||
this.type = type;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public OCFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public GlideOCFileType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Alejandro Bautista
|
||||
* Copyright (C) 2017 Alejandro Bautista
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Fetcher with Nextcloud client
|
||||
*/
|
||||
public class GlideStringStreamFetcher implements DataFetcher<InputStream> {
|
||||
|
||||
private static final String TAG = GlideStringStreamFetcher.class.getName();
|
||||
private final String url;
|
||||
|
||||
public GlideStringStreamFetcher(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
|
||||
OwnCloudClient client = AccountUtils.getClientForCurrentAccount(MainApp.getAppContext());
|
||||
|
||||
GetMethod get = null;
|
||||
try {
|
||||
get = new GetMethod(url);
|
||||
get.setRequestHeader("Cookie", "nc_sameSiteCookielax=true;nc_sameSiteCookiestrict=true");
|
||||
get.setRequestHeader(RemoteOperation.OCS_API_HEADER, RemoteOperation.OCS_API_HEADER_VALUE);
|
||||
int status = client.executeMethod(get);
|
||||
if (status == HttpStatus.SC_OK) {
|
||||
callback.onDataReady(get.getResponseBodyAsStream());
|
||||
} else {
|
||||
client.exhaustResponse(get.getResponseBodyAsStream());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, e.getMessage(), e);
|
||||
} finally {
|
||||
if (get != null) {
|
||||
get.releaseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
Log_OC.i(TAG, "Cleanup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
Log_OC.i(TAG, "Cancel");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Class<InputStream> getDataClass() {
|
||||
return InputStream.class;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DataSource getDataSource() {
|
||||
return DataSource.REMOTE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Alejandro Bautista
|
||||
* Copyright (C) 2017 Alejandro Bautista
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.signature.ObjectKey;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Custom model for Nextcloud client
|
||||
*/
|
||||
public class GlideStringStreamLoader implements ModelLoader<String, InputStream> {
|
||||
@Nullable
|
||||
@Override
|
||||
public LoadData<InputStream> buildLoadData(@NonNull String url, int width, int height, @NonNull Options options) {
|
||||
// TODO replace key with etag? and type? (avatar, thumbnail, resized image)
|
||||
// TODO pass client to stream fetcher?
|
||||
return new LoadData<>(new ObjectKey(url), new GlideStringStreamFetcher(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(@NonNull String s) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/**
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Alejandro Bautista
|
||||
* Copyright (C) 2017 Alejandro Bautista
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.accounts.Account;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.lib.common.OwnCloudAccount;
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Fetcher with OwnCloudClient
|
||||
*/
|
||||
|
||||
public class HttpStreamFetcher implements DataFetcher<InputStream> {
|
||||
|
||||
private static final String TAG = HttpStreamFetcher.class.getName();
|
||||
private final String mURL;
|
||||
|
||||
public HttpStreamFetcher(String url) {
|
||||
this.mURL = url;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream loadData(Priority priority) throws Exception {
|
||||
|
||||
Account mAccount = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
|
||||
OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, MainApp.getAppContext());
|
||||
OwnCloudClient mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
||||
getClientFor(ocAccount, MainApp.getAppContext());
|
||||
|
||||
if (mClient != null) {
|
||||
GetMethod get;
|
||||
try {
|
||||
get = new GetMethod(mURL);
|
||||
get.setRequestHeader("Cookie", "nc_sameSiteCookielax=true;nc_sameSiteCookiestrict=true");
|
||||
get.setRequestHeader(RemoteOperation.OCS_API_HEADER, RemoteOperation.OCS_API_HEADER_VALUE);
|
||||
int status = mClient.executeMethod(get);
|
||||
if (status == HttpStatus.SC_OK) {
|
||||
return get.getResponseBodyAsStream();
|
||||
} else {
|
||||
mClient.exhaustResponse(get.getResponseBodyAsStream());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
Log_OC.i(TAG,"Cleanup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return mURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
Log_OC.i(TAG,"Cancel");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Alejandro Bautista
|
||||
* Copyright (C) 2017 Alejandro Bautista
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Fetcher with Nextcloud client
|
||||
*/
|
||||
public class HttpStreamGlideContainerFetcher implements DataFetcher<InputStream> {
|
||||
|
||||
private static final String TAG = HttpStreamGlideContainerFetcher.class.getName();
|
||||
private final GlideContainer container;
|
||||
|
||||
public HttpStreamGlideContainerFetcher(GlideContainer container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
|
||||
Log_OC.d(TAG, "load thumbnail for: " + container.url);
|
||||
|
||||
GetMethod get;
|
||||
try {
|
||||
get = new GetMethod(container.url);
|
||||
get.setRequestHeader("Cookie", "nc_sameSiteCookielax=true;nc_sameSiteCookiestrict=true");
|
||||
get.setRequestHeader(RemoteOperation.OCS_API_HEADER, RemoteOperation.OCS_API_HEADER_VALUE);
|
||||
|
||||
int status = container.client.executeMethod(get);
|
||||
if (status == HttpStatus.SC_OK) {
|
||||
callback.onDataReady(get.getResponseBodyAsStream());
|
||||
} else {
|
||||
container.client.exhaustResponse(get.getResponseBodyAsStream());
|
||||
callback.onLoadFailed(new Exception("Thumbnail failed"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
Log_OC.i(TAG, "Cleanup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
Log_OC.i(TAG, "Cancel");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Class<InputStream> getDataClass() {
|
||||
return InputStream.class;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DataSource getDataSource() {
|
||||
return DataSource.REMOTE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.PictureDrawable;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.Registry;
|
||||
import com.bumptech.glide.annotation.GlideModule;
|
||||
import com.bumptech.glide.module.AppGlideModule;
|
||||
import com.caverock.androidsvg.SVG;
|
||||
import com.owncloud.android.utils.svg.SvgDecoder;
|
||||
import com.owncloud.android.utils.svg.SvgDrawableTranscoder;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Module for generating api.
|
||||
*/
|
||||
@GlideModule
|
||||
public class NextcloudGlideModule extends AppGlideModule {
|
||||
@Override
|
||||
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
|
||||
registry.prepend(GlideContainer.class, InputStream.class, new GlideContainerModelLoaderFactory());
|
||||
registry.prepend(GlideOcFile.class, InputStream.class, new OCFileModelLoaderFactory());
|
||||
registry.prepend(String.class, InputStream.class, new StringModelLoaderFactory());
|
||||
registry.prepend(GlideAvatar.class, InputStream.class, new AvatarModelLoaderFactory());
|
||||
registry.register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder())
|
||||
.append(InputStream.class, SVG.class, new SvgDecoder());
|
||||
}
|
||||
|
||||
// Disable manifest parsing to avoid adding similar modules twice.
|
||||
@Override
|
||||
public boolean isManifestParsingEnabled() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class OCFileModelLoader implements ModelLoader<GlideOcFile, InputStream> {
|
||||
@Override
|
||||
public boolean handles(@NonNull GlideOcFile model) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadData<InputStream> buildLoadData(@NonNull GlideOcFile model, int width, int height, @NonNull Options options) {
|
||||
OCFile file = model.getFile();
|
||||
|
||||
if (GlideOCFileType.thumbnail.equals(model.getType())) {
|
||||
String path;
|
||||
if (model.getFile().getStoragePath().isEmpty()) {
|
||||
path = model.getPath();
|
||||
} else {
|
||||
path = model.getFile().getStoragePath();
|
||||
}
|
||||
|
||||
return new LoadData<>(GlideKey.serverThumbnail(file), new FileFetcher(path));
|
||||
} else {
|
||||
return new LoadData<>(GlideKey.resizedImage(file), new FileFetcher(file.getStoragePath()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
||||
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class OCFileModelLoaderFactory implements ModelLoaderFactory<GlideOcFile, InputStream> {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelLoader<GlideOcFile, InputStream> build(@NonNull MultiModelLoaderFactory unused) {
|
||||
return new OCFileModelLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Nextcloud Android client application
|
||||
*
|
||||
* @author Tobias Kaminsky
|
||||
* Copyright (C) 2018 Tobias Kaminsky
|
||||
* Copyright (C) 2018 Nextcloud
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.glide;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
||||
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class StringModelLoaderFactory implements ModelLoaderFactory<String, InputStream> {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ModelLoader<String, InputStream> build(@NonNull MultiModelLoaderFactory unused) {
|
||||
return new GlideStringStreamLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
|
@ -11,6 +11,9 @@
|
|||
|
||||
package com.owncloud.android.utils.svg;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.ResourceDecoder;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
import com.bumptech.glide.load.resource.SimpleResource;
|
||||
|
@ -25,19 +28,13 @@ import java.io.InputStream;
|
|||
* Decodes an SVG internal representation from an {@link InputStream}.
|
||||
*/
|
||||
public class SvgDecoder implements ResourceDecoder<InputStream, SVG> {
|
||||
private int height = -1;
|
||||
private int width = -1;
|
||||
|
||||
public SvgDecoder(){
|
||||
|
||||
@Override
|
||||
public boolean handles(@NonNull InputStream source, @NonNull Options options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public SvgDecoder(int height, int width) {
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public Resource<SVG> decode(InputStream source, int w, int h) throws IOException {
|
||||
public Resource<SVG> decode(@NonNull InputStream source, int width, int height, @NonNull Options options)
|
||||
throws IOException {
|
||||
try {
|
||||
SVG svg = SVG.getFromInputStream(source);
|
||||
|
||||
|
@ -54,9 +51,4 @@ public class SvgDecoder implements ResourceDecoder<InputStream, SVG> {
|
|||
throw new IOException("Cannot load SVG from stream", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "SvgDecoder.com.owncloud.android";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,10 @@ package com.owncloud.android.utils.svg;
|
|||
|
||||
import android.graphics.Picture;
|
||||
import android.graphics.drawable.PictureDrawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
import com.bumptech.glide.load.resource.SimpleResource;
|
||||
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
|
||||
|
@ -22,16 +25,12 @@ import com.caverock.androidsvg.SVG;
|
|||
* Convert the {@link SVG}'s internal representation to an Android-compatible one ({@link Picture}).
|
||||
*/
|
||||
public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, PictureDrawable> {
|
||||
@Nullable
|
||||
@Override
|
||||
public Resource<PictureDrawable> transcode(Resource<SVG> toTranscode) {
|
||||
public Resource<PictureDrawable> transcode(@NonNull Resource<SVG> toTranscode, @NonNull Options options) {
|
||||
SVG svg = toTranscode.get();
|
||||
Picture picture = svg.renderToPicture();
|
||||
PictureDrawable drawable = new PictureDrawable(picture);
|
||||
return new SimpleResource<PictureDrawable>(drawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "";
|
||||
return new SimpleResource<>(drawable);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,34 +10,45 @@
|
|||
*/
|
||||
package com.owncloud.android.utils.svg;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.drawable.PictureDrawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.ImageViewTarget;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public class SvgSoftwareLayerSetter<T> implements RequestListener<T, PictureDrawable> {
|
||||
|
||||
/**
|
||||
* Listener which updates the {@link ImageView} to be software rendered, because
|
||||
* {@link com.caverock.androidsvg.SVG SVG}/{@link android.graphics.Picture Picture} can't render on
|
||||
* a hardware backed {@link android.graphics.Canvas Canvas}.
|
||||
*/
|
||||
public class SvgSoftwareLayerSetter implements RequestListener<PictureDrawable> {
|
||||
@Override
|
||||
public boolean onException(Exception e, T model, Target<PictureDrawable> target, boolean isFirstResource) {
|
||||
ImageView view = ((ImageViewTarget<?>) target).getView();
|
||||
if (Build.VERSION_CODES.HONEYCOMB <= Build.VERSION.SDK_INT) {
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<PictureDrawable> target,
|
||||
boolean isFirstResource) {
|
||||
try {
|
||||
ImageView view = ((ImageViewTarget<?>) target).getView();
|
||||
view.setLayerType(ImageView.LAYER_TYPE_NONE, null);
|
||||
} catch (Exception e1) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(PictureDrawable resource, T model, Target<PictureDrawable> target,
|
||||
boolean isFromMemoryCache, boolean isFirstResource) {
|
||||
ImageView view = ((ImageViewTarget<?>) target).getView();
|
||||
if (Build.VERSION_CODES.HONEYCOMB <= Build.VERSION.SDK_INT) {
|
||||
public boolean onResourceReady(PictureDrawable resource, Object model, Target<PictureDrawable> target,
|
||||
DataSource dataSource, boolean isFirstResource) {
|
||||
try {
|
||||
ImageView view = ((ImageViewTarget<?>) target).getView();
|
||||
view.setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,14 @@
|
|||
android:src="@drawable/folder"
|
||||
android:contentDescription="@null"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/play_icon"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@string/thumbnail"
|
||||
android:src="@drawable/ic_play_arrow"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/favorite_action"
|
||||
|
|
|
@ -37,6 +37,15 @@
|
|||
android:src="@drawable/folder"
|
||||
android:contentDescription="@null"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/play_icon"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@string/thumbnail"
|
||||
android:src="@drawable/ic_play_arrow"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/favorite_action"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -105,4 +114,4 @@
|
|||
android:textColor="@color/textColor"
|
||||
android:textSize="@dimen/grid_item_text_size" />
|
||||
|
||||
</com.owncloud.android.ui.SquareLinearLayout>
|
||||
</com.owncloud.android.ui.SquareLinearLayout>
|
||||
|
|
|
@ -1,203 +1,212 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><!--
|
||||
ownCloud Android client application
|
||||
|
||||
Copyright (C) 2012 Bartek Przybylski
|
||||
Copyright (C) 2015 ownCloud Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2,
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/ListItemLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/standard_list_item_size"
|
||||
android:background="@drawable/list_selector"
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="@dimen/standard_list_item_size"
|
||||
android:layout_height="@dimen/standard_list_item_size"
|
||||
android:paddingBottom="@dimen/standard_padding"
|
||||
android:paddingEnd="@dimen/standard_quarter_padding"
|
||||
android:paddingLeft="@dimen/zero"
|
||||
android:paddingRight="@dimen/standard_quarter_padding"
|
||||
android:paddingStart="@dimen/zero"
|
||||
android:paddingTop="@dimen/standard_padding">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="@dimen/file_icon_size"
|
||||
android:layout_height="@dimen/file_icon_size"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginLeft="@dimen/standard_half_margin"
|
||||
android:layout_marginStart="@dimen/standard_half_margin"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/folder" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/favorite_action"
|
||||
android:layout_width="@dimen/list_item_favorite_action_layout_width"
|
||||
android:layout_height="@dimen/list_item_favorite_action_layout_height"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginEnd="@dimen/standard_quarter_margin"
|
||||
android:layout_marginRight="@dimen/standard_quarter_margin"
|
||||
android:contentDescription="@string/favorite"
|
||||
android:src="@drawable/badge_favorite" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/keptOfflineIcon"
|
||||
android:layout_width="@dimen/list_item_kept_offline_icon_layout_width"
|
||||
android:layout_height="@dimen/list_item_kept_offline_icon_layout_height"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginEnd="@dimen/list_item_kept_offline_icon_layout_right_end_margin"
|
||||
android:layout_marginRight="@dimen/list_item_kept_offline_icon_layout_right_end_margin"
|
||||
android:contentDescription="@string/available_offline_icon"
|
||||
android:src="@drawable/ic_available_offline" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/localFileIndicator"
|
||||
android:layout_width="@dimen/list_item_local_file_indicator_layout_width"
|
||||
android:layout_height="@dimen/list_item_local_file_indicator_layout_height"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginEnd="@dimen/standard_quarter_margin"
|
||||
android:layout_marginRight="@dimen/standard_quarter_margin"
|
||||
android:contentDescription="@string/downloader_download_succeeded_ticker"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_synced" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="top"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/standard_padding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/Filename"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="middle"
|
||||
android:singleLine="true"
|
||||
android:text="@string/placeholder_filename"
|
||||
android:textColor="@color/textColor"
|
||||
android:textSize="@dimen/two_line_primary_text_size" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_size"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/placeholder_fileSize"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_separator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:paddingEnd="@dimen/standard_quarter_padding"
|
||||
android:paddingLeft="@dimen/zero"
|
||||
android:paddingRight="@dimen/standard_quarter_padding"
|
||||
android:paddingStart="@dimen/zero"
|
||||
android:text="@string/info_separator"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_mod"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:text="@string/placeholder_media_time"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingEnd="@dimen/zero"
|
||||
android:paddingLeft="@dimen/standard_half_padding"
|
||||
android:paddingRight="@dimen/zero"
|
||||
android:paddingStart="@dimen/standard_half_padding">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sharedIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/shared_icon_share"
|
||||
android:focusable="true"
|
||||
android:paddingEnd="@dimen/list_item_share_right_margin"
|
||||
android:paddingLeft="@dimen/standard_half_padding"
|
||||
android:paddingRight="@dimen/list_item_share_right_margin"
|
||||
android:paddingStart="@dimen/standard_half_padding"
|
||||
android:src="@drawable/ic_unshared" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/custom_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@id/sharedIcon"
|
||||
android:layout_toRightOf="@id/sharedIcon"
|
||||
android:clickable="false"
|
||||
android:contentDescription="@string/checkbox"
|
||||
android:focusable="false"
|
||||
android:paddingEnd="@dimen/alternate_padding"
|
||||
android:paddingLeft="@dimen/standard_half_padding"
|
||||
android:paddingRight="@dimen/alternate_padding"
|
||||
android:paddingStart="@dimen/standard_half_padding"
|
||||
android:src="@drawable/ic_checkbox_blank_outline" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/overflow_menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@id/custom_checkbox"
|
||||
android:layout_toRightOf="@id/custom_checkbox"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/overflow_menu"
|
||||
android:focusable="true"
|
||||
android:paddingEnd="@dimen/alternate_padding"
|
||||
android:paddingLeft="@dimen/standard_half_padding"
|
||||
android:paddingRight="@dimen/alternate_padding"
|
||||
android:paddingStart="@dimen/standard_half_padding"
|
||||
android:src="@drawable/ic_dots_vertical" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
<?xml version="1.0" encoding="UTF-8"?><!--
|
||||
ownCloud Android client application
|
||||
|
||||
Copyright (C) 2012 Bartek Przybylski
|
||||
Copyright (C) 2015 ownCloud Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2,
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/ListItemLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/standard_list_item_size"
|
||||
android:background="@drawable/list_selector"
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="@dimen/standard_list_item_size"
|
||||
android:layout_height="@dimen/standard_list_item_size"
|
||||
android:paddingBottom="@dimen/standard_padding"
|
||||
android:paddingEnd="@dimen/standard_quarter_padding"
|
||||
android:paddingLeft="@dimen/zero"
|
||||
android:paddingRight="@dimen/standard_quarter_padding"
|
||||
android:paddingStart="@dimen/zero"
|
||||
android:paddingTop="@dimen/standard_padding">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="@dimen/file_icon_size"
|
||||
android:layout_height="@dimen/file_icon_size"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginLeft="@dimen/standard_half_margin"
|
||||
android:layout_marginStart="@dimen/standard_half_margin"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/file_image"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/play_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@string/thumbnail"
|
||||
android:src="@drawable/ic_play_arrow"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/favorite_action"
|
||||
android:layout_width="@dimen/list_item_favorite_action_layout_width"
|
||||
android:layout_height="@dimen/list_item_favorite_action_layout_height"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginEnd="@dimen/standard_quarter_margin"
|
||||
android:layout_marginRight="@dimen/standard_quarter_margin"
|
||||
android:contentDescription="@string/favorite"
|
||||
android:src="@drawable/badge_favorite" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/keptOfflineIcon"
|
||||
android:layout_width="@dimen/list_item_kept_offline_icon_layout_width"
|
||||
android:layout_height="@dimen/list_item_kept_offline_icon_layout_height"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginEnd="@dimen/list_item_kept_offline_icon_layout_right_end_margin"
|
||||
android:layout_marginRight="@dimen/list_item_kept_offline_icon_layout_right_end_margin"
|
||||
android:contentDescription="@string/available_offline_icon"
|
||||
android:src="@drawable/ic_available_offline" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/localFileIndicator"
|
||||
android:layout_width="@dimen/list_item_local_file_indicator_layout_width"
|
||||
android:layout_height="@dimen/list_item_local_file_indicator_layout_height"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginEnd="@dimen/standard_quarter_margin"
|
||||
android:layout_marginRight="@dimen/standard_quarter_margin"
|
||||
android:contentDescription="@string/downloader_download_succeeded_ticker"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_synced" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="top"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/standard_padding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/Filename"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="middle"
|
||||
android:singleLine="true"
|
||||
android:text="@string/placeholder_filename"
|
||||
android:textColor="@color/textColor"
|
||||
android:textSize="@dimen/two_line_primary_text_size" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_size"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/placeholder_fileSize"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_separator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:paddingEnd="@dimen/standard_quarter_padding"
|
||||
android:paddingLeft="@dimen/zero"
|
||||
android:paddingRight="@dimen/standard_quarter_padding"
|
||||
android:paddingStart="@dimen/zero"
|
||||
android:text="@string/info_separator"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/last_mod"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:text="@string/placeholder_media_time"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingEnd="@dimen/zero"
|
||||
android:paddingLeft="@dimen/standard_half_padding"
|
||||
android:paddingRight="@dimen/zero"
|
||||
android:paddingStart="@dimen/standard_half_padding">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sharedIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/shared_icon_share"
|
||||
android:focusable="true"
|
||||
android:paddingEnd="@dimen/list_item_share_right_margin"
|
||||
android:paddingLeft="@dimen/standard_half_padding"
|
||||
android:paddingRight="@dimen/list_item_share_right_margin"
|
||||
android:paddingStart="@dimen/standard_half_padding"
|
||||
android:src="@drawable/ic_unshared" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/custom_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@id/sharedIcon"
|
||||
android:layout_toRightOf="@id/sharedIcon"
|
||||
android:clickable="false"
|
||||
android:contentDescription="@string/checkbox"
|
||||
android:focusable="false"
|
||||
android:paddingEnd="@dimen/alternate_padding"
|
||||
android:paddingLeft="@dimen/standard_half_padding"
|
||||
android:paddingRight="@dimen/alternate_padding"
|
||||
android:paddingStart="@dimen/standard_half_padding"
|
||||
android:src="@drawable/ic_checkbox_blank_outline" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/overflow_menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@id/custom_checkbox"
|
||||
android:layout_toRightOf="@id/custom_checkbox"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/overflow_menu"
|
||||
android:focusable="true"
|
||||
android:paddingEnd="@dimen/alternate_padding"
|
||||
android:paddingLeft="@dimen/standard_half_padding"
|
||||
android:paddingRight="@dimen/alternate_padding"
|
||||
android:paddingStart="@dimen/standard_half_padding"
|
||||
android:src="@drawable/ic_dots_vertical" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -818,9 +818,8 @@
|
|||
<string name="file_rename">Rename</string>
|
||||
<string name="fab_label">Add or upload</string>
|
||||
<string name="account_creation_failed">Account creation failed</string>
|
||||
|
||||
<string name="single_sign_on_request_token" formatted="true">Allow %1$s to access your Nextcloud account %2$s?</string>
|
||||
<string name="permission_deny">Deny</string>
|
||||
<string name="permission_allow">Allow</string>
|
||||
|
||||
<string name="thumbnail">Thumbnail</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<paths xmlns:tools="http://schemas.android.com/tools">
|
||||
<cache-path
|
||||
name="share"
|
||||
path="image_manager_disk_cache"
|
||||
tools:path="DiskCache.Factory.DEFAULT_DISK_CACHE_DIR"/>
|
||||
<files-path name="user_files_internal" path="nextcloud/"/>
|
||||
<files-path
|
||||
path="log/"
|
||||
name="log"/>
|
||||
<external-path name="external_files" path="."/>
|
||||
<root-path name="external_files" path="/storage/" />
|
||||
|
||||
<!-- yes, valid for ALL external storage and not only our app folder, since we can't use @string/data_folder
|
||||
as a value for 'path' attribute; in practice, we will only generate URIs in our folders, of course -->
|
||||
</paths>
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Nextcloud Android client application
|
||||
|
||||
Copyright (C) 2018 Tobias Kaminsky
|
||||
Copyright (C) 2018 Nextcloud
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public
|
||||
License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<paths xmlns:tools="http://schemas.android.com/tools">
|
||||
<cache-path
|
||||
name="share"
|
||||
path="image_manager_disk_cache"
|
||||
tools:path="DiskCache.Factory.DEFAULT_DISK_CACHE_DIR"/>
|
||||
</paths>
|
Loading…
Reference in New Issue