diff --git a/data/src/main/java/one/nem/lacerta/data/LacertaLibrary.java b/data/src/main/java/one/nem/lacerta/data/LacertaLibrary.java index cb19b425..6d424179 100644 --- a/data/src/main/java/one/nem/lacerta/data/LacertaLibrary.java +++ b/data/src/main/java/one/nem/lacerta/data/LacertaLibrary.java @@ -21,4 +21,7 @@ public interface LacertaLibrary { CompletableFuture getLibraryPage(String pageId, int limit); CompletableFuture getLibraryPage(String pageId, int limit, int offset); + // Create Folder + CompletableFuture createFolder(String path, String name); + } diff --git a/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryImpl.java b/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryImpl.java index 7fcf9cb5..f2e87da9 100644 --- a/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryImpl.java +++ b/data/src/main/java/one/nem/lacerta/data/impl/LacertaLibraryImpl.java @@ -5,6 +5,7 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import javax.inject.Inject; @@ -13,6 +14,7 @@ import one.nem.lacerta.data.LacertaLibrary; import one.nem.lacerta.model.LibraryItemPage; import one.nem.lacerta.model.ListItem; import one.nem.lacerta.model.ListItemType; +import one.nem.lacerta.model.PublicPath; import one.nem.lacerta.model.document.DocumentDetail; import one.nem.lacerta.source.database.LacertaDatabase; import one.nem.lacerta.source.database.common.DateTypeConverter; @@ -143,4 +145,25 @@ public class LacertaLibraryImpl implements LacertaLibrary { return null; }); } + + @Override + public CompletableFuture createFolder(String parentId, String name) { + return CompletableFuture.supplyAsync(() -> { + + FolderEntity parentFolderEntity = database.folderDao().findById(parentId); + PublicPath publicPath; + if (parentFolderEntity == null) { + publicPath = new PublicPath().resolve("/"); + } else { + publicPath = new PublicPath().resolve(parentFolderEntity.publicPath); + } + + FolderEntity folderEntity = new FolderEntity(); + folderEntity.id = UUID.randomUUID().toString(); + folderEntity.name = name; + folderEntity.publicPath = publicPath.getStringPath(); + database.folderDao().insert(folderEntity); + return folderEntity.id; + }); + } } diff --git a/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryTopFragment.java b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryTopFragment.java index 8dd366d8..172246f4 100644 --- a/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryTopFragment.java +++ b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryTopFragment.java @@ -1,5 +1,6 @@ package one.nem.lacerta.feature.library; +import android.app.AlertDialog; import android.os.Bundle; import androidx.annotation.NonNull; @@ -13,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; @@ -23,6 +25,8 @@ import android.widget.Toast; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; +import org.w3c.dom.Text; + import java.util.ArrayList; import java.util.List; @@ -34,7 +38,7 @@ import one.nem.lacerta.data.LacertaLibrary; import one.nem.lacerta.model.document.DocumentMeta; import one.nem.lacerta.model.document.tag.DocumentTag; import one.nem.lacerta.utils.LacertaLogger; - +import one.nem.lacerta.utils.TextInputDialog; /** @@ -51,6 +55,10 @@ public class LibraryTopFragment extends Fragment { @Inject LacertaLogger logger; + ListItemAdapter listItemAdapter; + + int currentTotalItemCount = 0; + public LibraryTopFragment() { // Required empty public constructor } @@ -83,7 +91,7 @@ public class LibraryTopFragment extends Fragment { RecyclerView recyclerView = view.findViewById(R.id.library_item_recycler_view); - ListItemAdapter listItemAdapter = new ListItemAdapter(documentId -> { + this.listItemAdapter = new ListItemAdapter(documentId -> { Toast.makeText(getContext(), documentId, Toast.LENGTH_SHORT).show(); }); recyclerView.setAdapter(listItemAdapter); @@ -92,8 +100,9 @@ public class LibraryTopFragment extends Fragment { lacertaLibrary.getLibraryPage(10).thenAccept(libraryItemPage -> { logger.debug("LibraryTopFragment", "Item selected! libraryItemPage.getListItems().size(): " + libraryItemPage.getListItems().size()); listItemAdapter.setLibraryItemPage(libraryItemPage); + this.currentTotalItemCount = libraryItemPage.getListItems().size(); getActivity().runOnUiThread(() -> { - listItemAdapter.notifyItemRangeInserted(0, libraryItemPage.getListItems().size() - 1); + listItemAdapter.notifyItemRangeInserted(0, this.currentTotalItemCount - 1); }); }); } @@ -103,4 +112,45 @@ public class LibraryTopFragment extends Fragment { inflater.inflate(R.menu.dir_menu, menu); super.onCreateOptionsMenu(menu, inflater); } + + // Selected + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.menu_item_create_new_folder) { + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setTitle("フォルダの作成"); + builder.setMessage("フォルダ名を入力してください"); + final android.widget.EditText input = new android.widget.EditText(getContext()); + input.setText("フォルダ名"); + builder.setView(input); + builder.setPositiveButton("作成", (dialog, which) -> { + lacertaLibrary.createFolder(null, input.getText().toString()).thenAccept(folderId -> { + logger.debug("LibraryTopFragment", "folderId: " + folderId); + }); + // Refresh + updateItem(); + }); + builder.setNegativeButton("キャンセル", (dialog, which) -> { + dialog.cancel(); + }); + builder.show(); + return true; + } else { + return super.onOptionsItemSelected(item); + } + } + + private void updateItem() { + lacertaLibrary.getLibraryPage(10).thenAccept(libraryItemPage -> { + logger.debug("LibraryTopFragment", "Item selected! libraryItemPage.getListItems().size(): " + libraryItemPage.getListItems().size()); + getActivity().runOnUiThread(() -> { + listItemAdapter.notifyItemRangeRemoved(0, this.currentTotalItemCount - 1); + }); + listItemAdapter.setLibraryItemPage(libraryItemPage); + getActivity().runOnUiThread(() -> { + listItemAdapter.notifyItemRangeInserted(0, libraryItemPage.getListItems().size() - 1); + }); + this.currentTotalItemCount = libraryItemPage.getListItems().size(); + }); + } } diff --git a/model/src/main/java/one/nem/lacerta/model/PublicPath.java b/model/src/main/java/one/nem/lacerta/model/PublicPath.java index 47f68ca7..de000fbc 100644 --- a/model/src/main/java/one/nem/lacerta/model/PublicPath.java +++ b/model/src/main/java/one/nem/lacerta/model/PublicPath.java @@ -27,13 +27,28 @@ public class PublicPath { } private void resolveInternal(String path) { - if (path.equals("..")) { - this.path.remove(this.path.size() - 1); + if (path.startsWith("/")) { + this.path.clear(); + this.path.add("/"); } else { - add(path); + if (path.equals("..")) { + this.path.remove(this.path.size() - 1); + } else if (path.equals(".")) { + // do nothing + } else { + this.path.add(path); + } } } + public PublicPath parse(String path) { + String[] pathArray = path.split("/"); + for (String p : pathArray) { + resolveInternal(p); + } + return this; + } + public PublicPath resolve(String path) { resolveInternal(path); return this;