mirror of
https://github.com/lacerta-doc/Lacerta.git
synced 2024-11-26 17:53:14 +00:00
Merge pull request #115 from lacerta-doc/custom_dialog
ダイアログのデザインを修正, ディレクトリピッカー実装, フォルダの移動に対応
This commit is contained in:
commit
3f84b1a3e2
|
@ -1,5 +1,6 @@
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.com.android.library)
|
alias(libs.plugins.com.android.library)
|
||||||
|
id 'com.google.dagger.hilt.android'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
@ -33,5 +34,12 @@ dependencies {
|
||||||
androidTestImplementation libs.androidx.test.ext.junit
|
androidTestImplementation libs.androidx.test.ext.junit
|
||||||
androidTestImplementation libs.androidx.test.espresso.core
|
androidTestImplementation libs.androidx.test.espresso.core
|
||||||
|
|
||||||
|
// Hilt (DI)
|
||||||
|
implementation libs.com.google.dagger.hilt.android
|
||||||
|
annotationProcessor libs.com.google.dagger.hilt.compiler
|
||||||
|
|
||||||
implementation project(':shared:ui')
|
implementation project(':shared:ui')
|
||||||
|
implementation project(':utils')
|
||||||
|
implementation project(':model')
|
||||||
|
implementation project(':data')
|
||||||
}
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
package one.nem.lacerta.component.common;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
import one.nem.lacerta.data.LacertaLibrary;
|
||||||
|
import one.nem.lacerta.model.ListItemType;
|
||||||
|
import one.nem.lacerta.utils.LacertaLogger;
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
public class LacertaSelectDirDialog extends DialogFragment {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
LacertaLibrary lacertaLibrary;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
LacertaLogger logger;
|
||||||
|
|
||||||
|
private LacertaSelectDirDialogListener listener;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private String positiveButtonText;
|
||||||
|
|
||||||
|
private String negativeButtonText;
|
||||||
|
|
||||||
|
private SelectDirDialogItemAdapter adapter;
|
||||||
|
|
||||||
|
private RecyclerView recyclerView;
|
||||||
|
|
||||||
|
private TextView current_dir_text_view;
|
||||||
|
|
||||||
|
// Setter
|
||||||
|
|
||||||
|
public LacertaSelectDirDialog setListener(LacertaSelectDirDialogListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LacertaSelectDirDialog setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LacertaSelectDirDialog setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LacertaSelectDirDialog setPositiveButtonText(String positiveButtonText) {
|
||||||
|
this.positiveButtonText = positiveButtonText;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LacertaSelectDirDialog setNegativeButtonText(String negativeButtonText) {
|
||||||
|
this.negativeButtonText = negativeButtonText;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
super.onCreateDialog(savedInstanceState);
|
||||||
|
|
||||||
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
|
||||||
|
LayoutInflater inflater = requireActivity().getLayoutInflater();
|
||||||
|
View view = inflater.inflate(R.layout.lacerta_dialog_select_dir, null);
|
||||||
|
|
||||||
|
// 高さを画面の60%にする
|
||||||
|
int height = (int) (getResources().getDisplayMetrics().heightPixels * 0.6);
|
||||||
|
view.setMinimumHeight(height);
|
||||||
|
|
||||||
|
this.recyclerView = view.findViewById(R.id.select_dir_recycler_view);
|
||||||
|
this.current_dir_text_view = view.findViewById(R.id.current_dir_text_view);
|
||||||
|
|
||||||
|
this.adapter = new SelectDirDialogItemAdapter(new LacertaSelectDirDialogInternalEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onDirSelected(String name, String itemId) {
|
||||||
|
showRecyclerViewItem(itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackSelected(String parentId) {
|
||||||
|
showRecyclerViewItem(parentId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.recyclerView.setAdapter(this.adapter);
|
||||||
|
builder.setView(view);
|
||||||
|
|
||||||
|
showRecyclerViewItem(null); // get root folder
|
||||||
|
|
||||||
|
builder.setTitle(this.title == null ? "Select a directory" : this.title);
|
||||||
|
builder.setMessage(this.message == null ? "Select a directory" : this.message);
|
||||||
|
builder.setPositiveButton(this.positiveButtonText == null ? "OK" : this.positiveButtonText, (dialog, which) -> {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onDirSelected(
|
||||||
|
adapter.getCurrentPageTitle() == null ? null : adapter.getCurrentPageTitle(),
|
||||||
|
adapter.getCurrentId() == null ? null : adapter.getCurrentId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(this.negativeButtonText == null ? "Cancel" : this.negativeButtonText, (dialog, which) -> {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onCanceled();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showRecyclerViewItem(String targetDirId) {
|
||||||
|
lacertaLibrary.getPublicPath(targetDirId, ListItemType.ITEM_TYPE_FOLDER).thenAccept(publicPath -> {
|
||||||
|
getActivity().runOnUiThread(() -> {
|
||||||
|
if (publicPath != null) {
|
||||||
|
current_dir_text_view.setText("/" + publicPath.getStringPath()); // TODO-rca: PublicPathの実装を修正する
|
||||||
|
} else {
|
||||||
|
current_dir_text_view.setText("/");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
lacertaLibrary.getFolderList(targetDirId).thenAccept(libraryItemPage -> {
|
||||||
|
getActivity().runOnUiThread(() -> {
|
||||||
|
int currentCount = adapter.getItemCount();
|
||||||
|
String currentDirId = adapter.getCurrentId();
|
||||||
|
if (currentDirId == null) {
|
||||||
|
// Rootが関わる推移 (Rootからの推移)
|
||||||
|
adapter.setListItems(libraryItemPage);
|
||||||
|
adapter.notifyItemRangeRemoved(0, currentCount);
|
||||||
|
adapter.notifyItemRangeInserted(0, libraryItemPage.getListItems().size());
|
||||||
|
} else if (libraryItemPage.getPageId() == null) {
|
||||||
|
// Rootが関わる推移 (Rootへの推移)
|
||||||
|
adapter.setListItems(libraryItemPage);
|
||||||
|
adapter.notifyItemRangeRemoved(0, currentCount);
|
||||||
|
adapter.notifyItemRangeInserted(0, libraryItemPage.getListItems().size());
|
||||||
|
} else if (libraryItemPage.getPageId() != null) {
|
||||||
|
// Rootが関わらない推移
|
||||||
|
adapter.setListItems(libraryItemPage);
|
||||||
|
adapter.notifyItemRangeRemoved(1, currentCount);
|
||||||
|
adapter.notifyItemRangeInserted(1, libraryItemPage.getListItems().size());
|
||||||
|
} else {
|
||||||
|
// その他の遷移(安全側に倒すため全アイテム更新)
|
||||||
|
logger.warn("LacertaSelectDirDialog", "Unknown transition.");
|
||||||
|
logger.warn("LacertaSelectDirDialog", "currentDirId: " + currentDirId + ", libraryItemPage.getPageId(): " + libraryItemPage.getPageId());
|
||||||
|
adapter.setListItems(libraryItemPage);
|
||||||
|
adapter.notifyItemRangeRemoved(0, currentCount);
|
||||||
|
adapter.notifyItemRangeInserted(0, libraryItemPage.getListItems().size());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package one.nem.lacerta.component.common;
|
||||||
|
|
||||||
|
public interface LacertaSelectDirDialogInternalEventListener {
|
||||||
|
void onDirSelected(String name, String itemId);
|
||||||
|
void onBackSelected(String parentId);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package one.nem.lacerta.component.common;
|
||||||
|
|
||||||
|
public interface LacertaSelectDirDialogListener {
|
||||||
|
|
||||||
|
void onDirSelected(String name, String itemId);
|
||||||
|
void onCanceled();
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package one.nem.lacerta.component.common;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import one.nem.lacerta.model.LibraryItemPage;
|
||||||
|
import one.nem.lacerta.model.ListItem;
|
||||||
|
import one.nem.lacerta.model.ListItemType;
|
||||||
|
|
||||||
|
public class SelectDirDialogItemAdapter extends RecyclerView.Adapter<SelectDirDialogItemAdapter.SelectDirDialogItemViewHolder> {
|
||||||
|
|
||||||
|
|
||||||
|
private LibraryItemPage libraryItemPage;
|
||||||
|
LacertaSelectDirDialogInternalEventListener listener;
|
||||||
|
|
||||||
|
public SelectDirDialogItemAdapter(LacertaSelectDirDialogInternalEventListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListItems(LibraryItemPage libraryItemPage) {
|
||||||
|
this.libraryItemPage = libraryItemPage;
|
||||||
|
if (this.libraryItemPage.getPageId() != null) { // ルートディレクトリの場合は戻るボタンを表示しない
|
||||||
|
this.libraryItemPage.getListItems().add(0, new ListItem("戻る", " ", ListItemType.ITEM_TYPE_ACTION_BACK, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public SelectDirDialogItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(one.nem.lacerta.shared.ui.R.layout.common_list_item, parent, false);
|
||||||
|
return new SelectDirDialogItemViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(SelectDirDialogItemViewHolder holder, int position) {
|
||||||
|
ListItem listItem = libraryItemPage.getListItems().get(position);
|
||||||
|
holder.title.setText(listItem.getTitle());
|
||||||
|
holder.description.setText(listItem.getDescription());
|
||||||
|
holder.icon.setImageResource(listItem.getItemType().getIconId());
|
||||||
|
if(listItem.getItemType() == ListItemType.ITEM_TYPE_ACTION_BACK) {
|
||||||
|
holder.itemView.setOnClickListener(v -> listener.onBackSelected(this.libraryItemPage.getParentId()));
|
||||||
|
} else {
|
||||||
|
holder.itemView.setOnClickListener(v -> listener.onDirSelected(listItem.getTitle(), listItem.getItemId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return this.libraryItemPage == null ? 0 : this.libraryItemPage.getListItems().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentId() {
|
||||||
|
if (this.libraryItemPage == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
if (this.libraryItemPage.getPageId() == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return this.libraryItemPage.getPageId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentPageTitle() {
|
||||||
|
if (this.libraryItemPage == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
if (this.libraryItemPage.getPageId() == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return this.libraryItemPage.getPageTitle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SelectDirDialogItemViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
TextView title;
|
||||||
|
TextView description;
|
||||||
|
|
||||||
|
ImageView icon;
|
||||||
|
|
||||||
|
|
||||||
|
public SelectDirDialogItemViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
|
||||||
|
title = itemView.findViewById(one.nem.lacerta.shared.ui.R.id.item_title);
|
||||||
|
description = itemView.findViewById(one.nem.lacerta.shared.ui.R.id.item_description);
|
||||||
|
icon = itemView.findViewById(one.nem.lacerta.shared.ui.R.id.item_icon);
|
||||||
|
description.setVisibility(View.GONE); // 暫定
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/current_dir_text_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/select_dir_recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -56,4 +56,6 @@ dependencies {
|
||||||
|
|
||||||
implementation project(':vcs')
|
implementation project(':vcs')
|
||||||
|
|
||||||
|
implementation project(':component:common')
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package one.nem.lacerta.component.viewer;
|
package one.nem.lacerta.component.viewer;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
@ -13,11 +12,15 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
import one.nem.lacerta.component.common.LacertaSelectDirDialog;
|
||||||
|
import one.nem.lacerta.component.common.LacertaSelectDirDialogListener;
|
||||||
import one.nem.lacerta.data.Document;
|
import one.nem.lacerta.data.Document;
|
||||||
import one.nem.lacerta.model.document.page.Page;
|
import one.nem.lacerta.model.document.page.Page;
|
||||||
import one.nem.lacerta.utils.FeatureSwitch;
|
import one.nem.lacerta.utils.FeatureSwitch;
|
||||||
|
@ -158,14 +161,18 @@ public class ViewerListFragment extends Fragment {
|
||||||
.commit();
|
.commit();
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.action_rename) {
|
} else if (item.getItemId() == R.id.action_rename) {
|
||||||
// TODO-rca: デザインをMaterial Design 3に合わせたカスタムダイアログにする
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
|
||||||
builder.setTitle("ファイル名の変更");
|
builder.setTitle("ファイル名の変更");
|
||||||
builder.setMessage("ファイル名を入力してください");
|
|
||||||
final android.widget.EditText input = new android.widget.EditText(getContext());
|
View view = LayoutInflater.from(requireContext()).inflate(one.nem.lacerta.shared.ui.R.layout.lacerta_dialog_edit_text_layout, null);
|
||||||
input.setText(documentName);
|
final com.google.android.material.textfield.TextInputEditText input = view.findViewById(one.nem.lacerta.shared.ui.R.id.custom_edit_text);
|
||||||
builder.setView(input);
|
final com.google.android.material.textfield.TextInputLayout inputLayout = view.findViewById(one.nem.lacerta.shared.ui.R.id.custom_text_input_layout);
|
||||||
builder.setPositiveButton("作成", (dialog, which) -> {
|
inputLayout.setHint("ファイル名");
|
||||||
|
|
||||||
|
builder.setView(view);
|
||||||
|
|
||||||
|
builder.setPositiveButton("変更", (dialog, which) -> {
|
||||||
document.renameDocument(documentId, input.getText().toString()).thenAccept(aVoid -> {
|
document.renameDocument(documentId, input.getText().toString()).thenAccept(aVoid -> {
|
||||||
getActivity().runOnUiThread(() -> {
|
getActivity().runOnUiThread(() -> {
|
||||||
toolbar.setTitle(input.getText().toString());
|
toolbar.setTitle(input.getText().toString());
|
||||||
|
@ -176,12 +183,12 @@ public class ViewerListFragment extends Fragment {
|
||||||
builder.setNegativeButton("キャンセル", (dialog, which) -> {
|
builder.setNegativeButton("キャンセル", (dialog, which) -> {
|
||||||
dialog.cancel();
|
dialog.cancel();
|
||||||
});
|
});
|
||||||
builder.show();
|
|
||||||
|
|
||||||
|
builder.show();
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.action_delete) {
|
} else if (item.getItemId() == R.id.action_delete) {
|
||||||
// TODO-rca: デザインをMaterial Design 3に合わせたカスタムダイアログにする
|
// TODO-rca: デザインをMaterial Design 3に合わせたカスタムダイアログにする
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
|
||||||
builder.setTitle("ファイルの削除");
|
builder.setTitle("ファイルの削除");
|
||||||
builder.setMessage("ファイルを削除しますか?");
|
builder.setMessage("ファイルを削除しますか?");
|
||||||
builder.setPositiveButton("削除", (dialog, which) -> {
|
builder.setPositiveButton("削除", (dialog, which) -> {
|
||||||
|
@ -198,7 +205,30 @@ public class ViewerListFragment extends Fragment {
|
||||||
builder.show();
|
builder.show();
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.action_move) {
|
} else if (item.getItemId() == R.id.action_move) {
|
||||||
Toast.makeText(getContext(), "Work in progress", Toast.LENGTH_SHORT).show();
|
// Toast.makeText(getContext(), "Work in progress", Toast.LENGTH_SHORT).show();
|
||||||
|
LacertaSelectDirDialog lacertaSelectDirDialog = new LacertaSelectDirDialog();
|
||||||
|
lacertaSelectDirDialog.setListener(new LacertaSelectDirDialogListener() {
|
||||||
|
@Override
|
||||||
|
public void onDirSelected(String name, String itemId) {
|
||||||
|
logger.debug(TAG, "Selected dir: " + name + ", " + itemId);
|
||||||
|
document.moveDocument(documentId, itemId).thenAccept(aVoid -> {
|
||||||
|
getActivity().runOnUiThread(() -> {
|
||||||
|
// Stop Activity
|
||||||
|
getActivity().finish(); // TODO-rca: ファイル移動後に終了するべきかは検討
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCanceled() {
|
||||||
|
logger.debug(TAG, "Canceled");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lacertaSelectDirDialog.setTitle("ファイルの移動")
|
||||||
|
.setMessage("ファイルを移動するフォルダを選択してください。")
|
||||||
|
.setPositiveButtonText("移動")
|
||||||
|
.setNegativeButtonText("キャンセル");
|
||||||
|
lacertaSelectDirDialog.show(getParentFragmentManager(), "select_dir_dialog");
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -23,6 +23,8 @@ public interface Document {
|
||||||
|
|
||||||
CompletableFuture<Void> deleteDocument(String documentId);
|
CompletableFuture<Void> deleteDocument(String documentId);
|
||||||
|
|
||||||
|
CompletableFuture<Void> moveDocument(String documentId, String parentId);
|
||||||
|
|
||||||
CompletableFuture<Void> updateDocument(DocumentDetail detail);
|
CompletableFuture<Void> updateDocument(DocumentDetail detail);
|
||||||
|
|
||||||
CompletableFuture<DocumentDetail> getDocument(String documentId);
|
CompletableFuture<DocumentDetail> getDocument(String documentId);
|
||||||
|
|
|
@ -20,6 +20,9 @@ public interface LacertaLibrary {
|
||||||
CompletableFuture<LibraryItemPage> getLibraryPage(String pageId, int limit);
|
CompletableFuture<LibraryItemPage> getLibraryPage(String pageId, int limit);
|
||||||
CompletableFuture<LibraryItemPage> getLibraryPage(String pageId, int limit, int offset);
|
CompletableFuture<LibraryItemPage> getLibraryPage(String pageId, int limit, int offset);
|
||||||
|
|
||||||
|
// Get Folder List
|
||||||
|
CompletableFuture<LibraryItemPage> getFolderList(String parentId);
|
||||||
|
|
||||||
// Create Folder
|
// Create Folder
|
||||||
CompletableFuture<String> createFolder(String parentId, String name);
|
CompletableFuture<String> createFolder(String parentId, String name);
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,19 @@ public class DocumentImpl implements Document {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> moveDocument(String documentId, String parentId) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
DocumentEntity documentEntity = database.documentDao().findById(documentId);
|
||||||
|
if (documentEntity == null) {
|
||||||
|
throw new IllegalArgumentException("documentId is not found");
|
||||||
|
}
|
||||||
|
documentEntity.parentId = parentId;
|
||||||
|
database.documentDao().update(documentEntity);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> updateDocument(DocumentDetail detail) {
|
public CompletableFuture<Void> updateDocument(DocumentDetail detail) {
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
|
|
@ -127,6 +127,47 @@ public class LacertaLibraryImpl implements LacertaLibrary {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<LibraryItemPage> getFolderList(String targetDirId) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
LibraryItemPage libraryItemPage = new LibraryItemPage();
|
||||||
|
|
||||||
|
List<FolderEntity> folderEntities;
|
||||||
|
if (targetDirId == null) { // When root folder
|
||||||
|
folderEntities = database.folderDao().findRootFolders();
|
||||||
|
libraryItemPage.setParentId(null);
|
||||||
|
libraryItemPage.setPageId(null);
|
||||||
|
libraryItemPage.setPageTitle("ライブラリ");
|
||||||
|
} else {
|
||||||
|
folderEntities = database.folderDao().findByParentId(targetDirId);
|
||||||
|
FolderEntity folderEntity = database.folderDao().findById(targetDirId);
|
||||||
|
if (folderEntity == null) {
|
||||||
|
logger.warn("LacertaLibraryImpl", targetDirId + " is not found.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
libraryItemPage.setParentId(folderEntity.parentId);
|
||||||
|
libraryItemPage.setPageId(folderEntity.id);
|
||||||
|
libraryItemPage.setPageTitle(folderEntity.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<ListItem> listItems = new ArrayList<>();
|
||||||
|
for (FolderEntity childFolderEntity : folderEntities) {
|
||||||
|
logger.debug("LacertaLibraryImpl", "childFolderEntity.name: " + childFolderEntity.name);
|
||||||
|
ListItem listItem = new ListItem();
|
||||||
|
listItem.setItemType(ListItemType.ITEM_TYPE_FOLDER);
|
||||||
|
listItem.setTitle(childFolderEntity.name);
|
||||||
|
listItem.setDescription("フォルダ"); // TODO-rca: ハードコーディングやめる
|
||||||
|
listItem.setItemId(childFolderEntity.id);
|
||||||
|
listItems.add(listItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
libraryItemPage.setListItems(listItems);
|
||||||
|
|
||||||
|
return libraryItemPage;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<String> createFolder(String parentId, String name) {
|
public CompletableFuture<String> createFolder(String parentId, String name) {
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
package one.nem.lacerta.feature.library;
|
package one.nem.lacerta.feature.library;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
@ -14,34 +11,18 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.google.android.material.appbar.AppBarLayout;
|
import com.google.android.material.appbar.AppBarLayout;
|
||||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import org.w3c.dom.Text;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import one.nem.lacerta.component.viewer.ViewerMainActivity;
|
import one.nem.lacerta.component.viewer.ViewerMainActivity;
|
||||||
import one.nem.lacerta.data.Document;
|
|
||||||
import one.nem.lacerta.data.LacertaLibrary;
|
import one.nem.lacerta.data.LacertaLibrary;
|
||||||
import one.nem.lacerta.model.FragmentNavigation;
|
|
||||||
import one.nem.lacerta.model.LibraryItemPage;
|
import one.nem.lacerta.model.LibraryItemPage;
|
||||||
import one.nem.lacerta.model.PublicPath;
|
|
||||||
import one.nem.lacerta.utils.FeatureSwitch;
|
import one.nem.lacerta.utils.FeatureSwitch;
|
||||||
import one.nem.lacerta.utils.LacertaLogger;
|
import one.nem.lacerta.utils.LacertaLogger;
|
||||||
|
|
||||||
|
@ -220,13 +201,17 @@ public class LibraryPageFragment extends Fragment {
|
||||||
* Currentにフォルダを作成する
|
* Currentにフォルダを作成する
|
||||||
*/
|
*/
|
||||||
private void createFolder(String pageId) {
|
private void createFolder(String pageId) {
|
||||||
// TODO-rca: デザインをMaterial Design 3に合わせたカスタムダイアログにする
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
|
||||||
builder.setTitle("フォルダの作成");
|
builder.setTitle("フォルダの作成");
|
||||||
builder.setMessage("フォルダ名を入力してください");
|
builder.setMessage("フォルダ名を入力してください");
|
||||||
final android.widget.EditText input = new android.widget.EditText(getContext());
|
|
||||||
input.setText("フォルダ名");
|
View view = LayoutInflater.from(requireContext()).inflate(one.nem.lacerta.shared.ui.R.layout.lacerta_dialog_edit_text_layout, null);
|
||||||
builder.setView(input);
|
final com.google.android.material.textfield.TextInputEditText input = view.findViewById(one.nem.lacerta.shared.ui.R.id.custom_edit_text);
|
||||||
|
final com.google.android.material.textfield.TextInputLayout inputLayout = view.findViewById(one.nem.lacerta.shared.ui.R.id.custom_text_input_layout);
|
||||||
|
inputLayout.setHint("フォルダ名");
|
||||||
|
|
||||||
|
builder.setView(view);
|
||||||
|
|
||||||
builder.setPositiveButton("作成", (dialog, which) -> {
|
builder.setPositiveButton("作成", (dialog, which) -> {
|
||||||
lacertaLibrary.createFolder(pageId, input.getText().toString()).thenAccept(folderId -> {
|
lacertaLibrary.createFolder(pageId, input.getText().toString()).thenAccept(folderId -> {
|
||||||
// Refresh
|
// Refresh
|
||||||
|
@ -236,6 +221,7 @@ public class LibraryPageFragment extends Fragment {
|
||||||
builder.setNegativeButton("キャンセル", (dialog, which) -> {
|
builder.setNegativeButton("キャンセル", (dialog, which) -> {
|
||||||
dialog.cancel();
|
dialog.cancel();
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ package one.nem.lacerta.model;
|
||||||
public enum ListItemType {
|
public enum ListItemType {
|
||||||
|
|
||||||
ITEM_TYPE_FOLDER(one.nem.lacerta.shared.ui.R.drawable.folder_24px),
|
ITEM_TYPE_FOLDER(one.nem.lacerta.shared.ui.R.drawable.folder_24px),
|
||||||
ITEM_TYPE_DOCUMENT(one.nem.lacerta.shared.ui.R.drawable.description_24px);
|
ITEM_TYPE_DOCUMENT(one.nem.lacerta.shared.ui.R.drawable.description_24px),
|
||||||
|
ITEM_TYPE_ACTION_BACK(one.nem.lacerta.shared.ui.R.drawable.arrow_back_24px);
|
||||||
|
|
||||||
private int iconId;
|
private int iconId;
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,5 @@ dependencies {
|
||||||
testImplementation libs.junit
|
testImplementation libs.junit
|
||||||
androidTestImplementation libs.androidx.test.ext.junit
|
androidTestImplementation libs.androidx.test.ext.junit
|
||||||
androidTestImplementation libs.androidx.test.espresso.core
|
androidTestImplementation libs.androidx.test.espresso.core
|
||||||
|
|
||||||
}
|
}
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/item_title"
|
android:id="@+id/item_title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/item_description"
|
android:id="@+id/item_description"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:text="Placeholder Description"
|
android:text="Placeholder Description"
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/custom_text_input_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/custom_edit_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
|
@ -39,4 +39,6 @@
|
||||||
<!-- common -->
|
<!-- common -->
|
||||||
|
|
||||||
<string name="placeholder">Placeholder(TODO: Replace)</string>
|
<string name="placeholder">Placeholder(TODO: Replace)</string>
|
||||||
|
<!-- TODO: Remove or change this placeholder text -->
|
||||||
|
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user