diff --git a/src/main/java/com/owncloud/android/operations/CommentFileOperation.java b/src/main/java/com/owncloud/android/operations/CommentFileOperation.java new file mode 100644 index 0000000000..314106d3fb --- /dev/null +++ b/src/main/java/com/owncloud/android/operations/CommentFileOperation.java @@ -0,0 +1,112 @@ +/* + * Nextcloud Android client application + * + * @author Tobias Kaminsky + * Copyright (C) 2018 Tobias Kaminsky + * Copyright (C) 2018 Nextcloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 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 . + */ + +package com.owncloud.android.operations; + +import android.util.Log; + +import com.google.gson.GsonBuilder; +import com.owncloud.android.lib.common.OwnCloudClient; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.operations.common.SyncOperation; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + + +/** + * Restore a {@link com.owncloud.android.lib.resources.files.FileVersion}. + */ +public class CommentFileOperation extends SyncOperation { + + private static final String TAG = CommentFileOperation.class.getSimpleName(); + private static final int POST_READ_TIMEOUT = 30000; + private static final int POST_CONNECTION_TIMEOUT = 5000; + + private static final String ACTOR_ID = "actorId"; + private static final String ACTOR_TYPE = "actorType"; + private static final String ACTOR_TYPE_VALUE = "users"; + private static final String VERB = "verb"; + private static final String VERB_VALUE = "comment"; + private static final String MESSAGE = "message"; + + private String message; + private String fileId; + private String userId; + + /** + * Constructor + * + * @param message Comment to store + * @param userId userId to access correct dav endpoint + */ + public CommentFileOperation(String message, String fileId, String userId) { + this.message = message; + this.fileId = fileId; + this.userId = userId; + } + + /** + * Performs the operation. + * + * @param client Client object to communicate with the remote ownCloud server. + */ + @Override + protected RemoteOperationResult run(OwnCloudClient client) { + + RemoteOperationResult result; + try { + String url = client.getNewWebdavUri(false) + "/comments/files/" + fileId; + PostMethod postMethod = new PostMethod(url); + postMethod.addRequestHeader("Content-type", "application/json"); + + Map values = new HashMap<>(); + values.put(ACTOR_ID, userId); + values.put(ACTOR_TYPE, ACTOR_TYPE_VALUE); + values.put(VERB, VERB_VALUE); + values.put(MESSAGE, message); + + String json = new GsonBuilder().create().toJson(values, Map.class); + + postMethod.setRequestEntity(new StringRequestEntity(json)); + + int status = client.executeMethod(postMethod, POST_READ_TIMEOUT, POST_CONNECTION_TIMEOUT); + + result = new RemoteOperationResult(isSuccess(status), postMethod); + + client.exhaustResponse(postMethod.getResponseBodyAsStream()); + } catch (IOException e) { + result = new RemoteOperationResult(e); + Log.e(TAG, "Post comment to file with id " + fileId + " failed: " + result.getLogMessage(), e); + } + + return result; + } + + private boolean isSuccess(int status) { + return status == HttpStatus.SC_CREATED; + } +} \ No newline at end of file diff --git a/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java b/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java index 452e8b83fd..894a9599f9 100644 --- a/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java @@ -36,7 +36,6 @@ import android.widget.ProgressBar; import com.owncloud.android.R; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.datamodel.ThumbnailsCacheManager; import com.owncloud.android.utils.ThemeUtils; /** diff --git a/src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java index 68fdb508bf..2d34cd0def 100644 --- a/src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java +++ b/src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java @@ -50,7 +50,6 @@ import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment; import com.owncloud.android.ui.fragment.util.SharingMenuHelper; import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.ThemeUtils; -import com.owncloud.android.utils.DisplayUtils; import java.security.NoSuchAlgorithmException; import java.util.List; @@ -378,23 +377,6 @@ public class UserListAdapter extends RecyclerView.Adapter submitComment(new VersionListInterface.CommentCallback() { + + @Override + public void onSuccess() { + commentInput.getText().clear(); + fetchAndSetData(null); + } + + @Override + public void onError(int error) { + Snackbar.make(recyclerView, error, Snackbar.LENGTH_LONG).show(); + } + })); return view; } + private void submitComment(VersionListInterface.CommentCallback callback) { + String message = commentInput.getText().toString(); + new RestoreFileVersionTask.SubmitCommentTask(message, userId, file.getLocalId(), callback, ownCloudClient) + .execute(); + + } + private void onRefreshListLayout(SwipeRefreshLayout refreshLayout) { setLoadingMessage(); if (refreshLayout != null && refreshLayout.isRefreshing()) { @@ -379,6 +408,17 @@ public class FileDetailActivitiesFragment extends Fragment implements ActivityLi // TODO implement activity click } + @Override + public void onSuccess(String message) { + Snackbar.make(recyclerView, message, Snackbar.LENGTH_LONG).show(); + fetchAndSetData(null); + } + + @Override + public void onSuccess() { + fetchAndSetData(null); + } + @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); @@ -391,4 +431,43 @@ public class FileDetailActivitiesFragment extends Fragment implements ActivityLi public void onRestoreClicked(FileVersion fileVersion) { operationsHelper.restoreFileVersion(fileVersion, userId); } + + private static class SubmitCommentTask extends AsyncTask { + + private String message; + private String userId; + private String fileId; + private VersionListInterface.CommentCallback callback; + private OwnCloudClient client; + + private SubmitCommentTask(String message, String userId, String fileId, + VersionListInterface.CommentCallback callback, OwnCloudClient client) { + this.message = message; + this.userId = userId; + this.fileId = fileId; + this.callback = callback; + this.client = client; + } + + @Override + protected Boolean doInBackground(Void... voids) { + CommentFileOperation commentFileOperation = new CommentFileOperation(message, fileId, userId); + + RemoteOperationResult result = commentFileOperation.execute(client); + + return result.isSuccess(); + } + + @Override + protected void onPostExecute(Boolean success) { + super.onPostExecute(success); + + if (success) { + callback.onSuccess(); + } else { + callback.onError(R.string.error_comment_file); + + } + } + } } \ No newline at end of file diff --git a/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java index 1126312857..d9c99b6ddd 100644 --- a/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -28,7 +28,6 @@ import android.graphics.Bitmap; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; @@ -39,7 +38,6 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.PopupMenu; import android.widget.ProgressBar; import android.widget.TextView; @@ -68,7 +66,6 @@ import java.lang.ref.WeakReference; import butterknife.BindView; import butterknife.ButterKnife; -import butterknife.Optional; import butterknife.Unbinder; /** @@ -126,60 +123,6 @@ public class FileDetailFragment extends FileFragment implements OnClickListener private ToolbarActivity activity; private int activeTab; - @Nullable @BindView(R.id.fdProgressBlock) - View downloadProgressContainer; - - @Nullable @BindView(R.id.fdCancelBtn) - ImageButton cancelButton; - - @Nullable @BindView(R.id.fdProgressBar) - ProgressBar progressBar; - - @Nullable @BindView(R.id.fdProgressText) - TextView progressText; - - @Nullable @BindView(R.id.fdFilename) - TextView fileName; - - @Nullable @BindView(R.id.fdSize) - TextView fileSize; - - @Nullable @BindView(R.id.fdModified) - TextView fileModifiedTimestamp; - - @Nullable @BindView(R.id.fdFavorite) - ImageView favoriteIcon; - - @Nullable @BindView(R.id.overflow_menu) - ImageView overflowMenu; - - @Nullable @BindView(R.id.tab_layout) - TabLayout tabLayout; - - @Nullable @BindView(R.id.pager) - ViewPager viewPager; - - @Nullable @BindView(R.id.empty_list_view_text) - protected TextView emptyContentMessage; - - @Nullable @BindView(R.id.empty_list_view_headline) - protected TextView emptyContentHeadline; - - @Nullable @BindView(R.id.empty_list_icon) - protected ImageView emptyContentIcon; - - @Nullable @BindView(R.id.empty_list_progress) - protected ProgressBar emptyProgressBar; - - private int layout; - private View view; - private boolean previewLoaded; - private Account account; - private Unbinder unbinder; - - public ProgressListener progressListener; - private ToolbarActivity activity; - /** * Public factory method to create new FileDetailFragment instances. * @@ -306,72 +249,10 @@ public class FileDetailFragment extends FileFragment implements OnClickListener cancelButton.setOnClickListener(this); favoriteIcon.setOnClickListener(this); overflowMenu.setOnClickListener(this); - cancelButton.setOnClickListener(this); - favoriteIcon.setOnClickListener(this); - overflowMenu.setOnClickListener(this); - // TODO use whenever we switch to use glide for preview images - /* - if (MimeTypeUtil.isImage(getFile())) { - setHeaderImage(); - } - */ + updateFileDetails(false, false); - } else { - emptyContentMessage.setText(R.string.filedetails_select_file); - emptyContentMessage.setVisibility(View.VISIBLE); - emptyContentHeadline.setText(R.string.common_error); - emptyContentIcon.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_alert_octagon)); - emptyContentIcon.setVisibility(View.VISIBLE); - emptyProgressBar.setVisibility(View.GONE); } } - // TODO use whenever we switch to use glide for preview images - /* - private void setHeaderImage() { - if (mContainerActivity.getStorageManager().getCapability(account.name) - .getServerBackground() != null && previewImage != null) { - - String background = mContainerActivity.getStorageManager().getCapability(account.name).getServerBackground(); - - int primaryColor = ThemeUtils.primaryColor(account, getContext()); - - if (URLUtil.isValidUrl(background)) { - // background image - SimpleTarget target = new SimpleTarget() { - @Override - public void onResourceReady(Drawable resource, GlideAnimation glideAnimation) { - Drawable[] drawables = {new ColorDrawable(primaryColor), resource}; - LayerDrawable layerDrawable = new LayerDrawable(drawables); - previewImage.setImageDrawable(layerDrawable); - previewImage.setVisibility(View.VISIBLE); - ((ToolbarActivity) getActivity()).getSupportActionBar().setTitle(null); - ((ToolbarActivity) getActivity()).getSupportActionBar().setBackgroundDrawable(null); - toolbarProgressBar.setVisibility(View.GONE); - previewLoaded = true; - } - - @Override - public void onLoadFailed(Exception e, Drawable errorDrawable) { - previewImage.setVisibility(View.GONE); - toolbarProgressBar.setVisibility(View.VISIBLE); - } - }; - - Glide.with(this) - .load(background) - .centerCrop() - .placeholder(R.drawable.background) - .error(R.drawable.background) - .crossFade() - .into(target); - } else { - // hide image - previewImage.setVisibility(View.GONE); - toolbarProgressBar.setVisibility(View.VISIBLE); - } - } - } - */ public void onOverflowIconClicked(View view) { PopupMenu popup = new PopupMenu(getActivity(), view); diff --git a/src/main/java/com/owncloud/android/ui/fragment/FileFragment.java b/src/main/java/com/owncloud/android/ui/fragment/FileFragment.java index 4eeb0d9b2d..f0d00ea460 100644 --- a/src/main/java/com/owncloud/android/ui/fragment/FileFragment.java +++ b/src/main/java/com/owncloud/android/ui/fragment/FileFragment.java @@ -60,7 +60,7 @@ public class FileFragment extends Fragment { super.onCreate(savedInstanceState); Bundle bundle = getArguments(); - setFile((OCFile) bundle.getParcelable(EXTRA_FILE)); + setFile(bundle.getParcelable(EXTRA_FILE)); } /** diff --git a/src/main/java/com/owncloud/android/ui/interfaces/VersionListInterface.java b/src/main/java/com/owncloud/android/ui/interfaces/VersionListInterface.java index 878b482714..8236314c7f 100644 --- a/src/main/java/com/owncloud/android/ui/interfaces/VersionListInterface.java +++ b/src/main/java/com/owncloud/android/ui/interfaces/VersionListInterface.java @@ -28,4 +28,10 @@ public interface VersionListInterface { interface View { void onRestoreClicked(FileVersion fileVersion); } + + interface CommentCallback { + void onSuccess(); + + void onError(int error); + } } diff --git a/src/main/java/com/owncloud/android/utils/BitmapUtils.java b/src/main/java/com/owncloud/android/utils/BitmapUtils.java index 009c48c7ec..cc622b746a 100644 --- a/src/main/java/com/owncloud/android/utils/BitmapUtils.java +++ b/src/main/java/com/owncloud/android/utils/BitmapUtils.java @@ -34,7 +34,9 @@ import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.codec.binary.Hex; +import java.io.UnsupportedEncodingException; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Locale; /** diff --git a/src/main/res/layout/file_details_activities_fragment.xml b/src/main/res/layout/file_details_activities_fragment.xml index ca619eecbf..442731d06e 100644 --- a/src/main/res/layout/file_details_activities_fragment.xml +++ b/src/main/res/layout/file_details_activities_fragment.xml @@ -18,36 +18,56 @@ License along with this program. If not, see . --> - + + + + + + +