diff --git a/app/src/main/java/one/nem/lacerta/MainActivity.java b/app/src/main/java/one/nem/lacerta/MainActivity.java index 85ba4ded..9146c04f 100644 --- a/app/src/main/java/one/nem/lacerta/MainActivity.java +++ b/app/src/main/java/one/nem/lacerta/MainActivity.java @@ -71,8 +71,37 @@ public class MainActivity extends AppCompatActivity { // Set status bar color getWindow().setStatusBarColor(ContextCompat.getColor(this, one.nem.lacerta.shared.ui.R.color.colorSurface)); + // Set app bar color + AppBarLayout appBarLayout = findViewById(R.id.app_bar_layout); + appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { + if (Math.abs(verticalOffset) == appBarLayout.getTotalScrollRange()) { + // Collapsed + getWindow().setStatusBarColor(ContextCompat.getColor(getApplicationContext(), one.nem.lacerta.shared.ui.R.color.colorSecondaryContainer)); + } else if (verticalOffset == 0) { + // Expanded + getWindow().setStatusBarColor(ContextCompat.getColor(getApplicationContext(), one.nem.lacerta.shared.ui.R.color.colorSurface)); + } else { + // Somewhere in between + // Here you can add a color transition if you want + } + } + }); + + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); } + // Public + public void setActionBarTitle(String title) { + getSupportActionBar().setTitle(title); + } + + public void setActionBarBackButton(boolean isEnabled) { + getSupportActionBar().setDisplayHomeAsUpEnabled(isEnabled); + } private void initializeApp() { Log.d("Init", "Initializing app"); @@ -88,4 +117,12 @@ public class MainActivity extends AppCompatActivity { boolean isEnabled = FeatureSwitch.Meta.canOverrideSwitch ? sharedPrefUtils.getFeatureSwitchOverride(featureSwitchOverride) : defaultValue; if (!isEnabled) bottomNavigationView.getMenu().removeItem(menuId); } + + @Override + public void navigateToFragment(Fragment fragment) { + getSupportFragmentManager().beginTransaction() + .replace(R.id.nav_host_fragment, fragment) + .addToBackStack(null) + .commit(); + } } 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 f2e87da9..f1897557 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 @@ -135,7 +135,52 @@ public class LacertaLibraryImpl implements LacertaLibrary { @Override public CompletableFuture getLibraryPage(String pageId, int limit) { return CompletableFuture.supplyAsync(() -> { - return null; + LibraryItemPage libraryItemPage = new LibraryItemPage(); + + FolderEntity folderEntity = database.folderDao().findById(pageId); + if (folderEntity == null) { + return null; + } + + PublicPath publicPath = new PublicPath().parse(folderEntity.publicPath); + + String resolvedPublicPath = publicPath.resolve(folderEntity.name).getStringPath(); + + logger.debug("LacertaLibraryImpl", "Resolved publicPath: " + resolvedPublicPath); + + List folderEntities = getFolderEntitiesByPublicPath(resolvedPublicPath).join(); + logger.debug("LacertaLibraryImpl", "folderEntities.size(): " + folderEntities.size()); + List documentEntities = getDocumentEntitiesByPublicPath(resolvedPublicPath).join(); + logger.debug("LacertaLibraryImpl", "documentEntities.size(): " + documentEntities.size()); + + ArrayList 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); + } + + for (DocumentEntity documentEntity : documentEntities) { + logger.debug("LacertaLibraryImpl", "documentEntity.title: " + documentEntity.title); + ListItem listItem = new ListItem(); + listItem.setItemType(ListItemType.ITEM_TYPE_DOCUMENT); + listItem.setTitle(documentEntity.title); +// listItem.setDescription(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm").format(documentEntity.updatedAt.toInstant())); + listItem.setItemId(documentEntity.id); + listItems.add(listItem); + } + + libraryItemPage.setPageTitle(folderEntity.name); + libraryItemPage.setPageId(folderEntity.id); + libraryItemPage.setListItems(listItems); + + logger.debug("LacertaLibraryImpl", "libraryItemPage.getListItems().size(): " + libraryItemPage.getListItems().size()); + + return libraryItemPage; }); } diff --git a/feature/library/src/main/java/one/nem/lacerta/feature/library/DocumentSelectListener.java b/feature/library/src/main/java/one/nem/lacerta/feature/library/DocumentSelectListener.java index 94ebe0bc..5aa5294a 100644 --- a/feature/library/src/main/java/one/nem/lacerta/feature/library/DocumentSelectListener.java +++ b/feature/library/src/main/java/one/nem/lacerta/feature/library/DocumentSelectListener.java @@ -1,5 +1,6 @@ package one.nem.lacerta.feature.library; public interface DocumentSelectListener { - void onDocumentSelect(String documentId); + void onFolderSelected(String folderId, String folderName); + void onDocumentSelected(String documentId, String documentName); } 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/LibraryPageFragment.java similarity index 56% rename from feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryTopFragment.java rename to feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryPageFragment.java index 30f31b4e..4b62e086 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/LibraryPageFragment.java @@ -35,17 +35,20 @@ import javax.inject.Inject; import dagger.hilt.android.AndroidEntryPoint; import one.nem.lacerta.data.Document; 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.model.FragmentNavigation; import one.nem.lacerta.utils.LacertaLogger; + /** * A simple {@link Fragment} subclass. - * Use the {@link LibraryTopFragment#newInstance} factory method to + * Use the {@link LibraryPageFragment#newInstance} factory method to * create an instance of this fragment. */ @AndroidEntryPoint -public class LibraryTopFragment extends Fragment { +public class LibraryPageFragment extends Fragment { + + // Param + private String folderId; @Inject LacertaLibrary lacertaLibrary; @@ -57,12 +60,21 @@ public class LibraryTopFragment extends Fragment { int currentTotalItemCount = 0; - public LibraryTopFragment() { + public LibraryPageFragment() { // Required empty public constructor } - public static LibraryTopFragment newInstance() { - LibraryTopFragment fragment = new LibraryTopFragment(); + public static LibraryPageFragment newInstance(String folderId) { + LibraryPageFragment fragment = new LibraryPageFragment(); Bundle args = new Bundle(); + args.putString("folderId", folderId); + fragment.setArguments(args); + return fragment; + } + + public static LibraryPageFragment newInstance() { + LibraryPageFragment fragment = new LibraryPageFragment(); + Bundle args = new Bundle(); + args.putString("folderId", null); fragment.setArguments(args); return fragment; } @@ -89,20 +101,55 @@ public class LibraryTopFragment extends Fragment { RecyclerView recyclerView = view.findViewById(R.id.library_item_recycler_view); - this.listItemAdapter = new ListItemAdapter(documentId -> { - Toast.makeText(getContext(), documentId, Toast.LENGTH_SHORT).show(); + this.listItemAdapter = new ListItemAdapter(new DocumentSelectListener() { + @Override + public void onFolderSelected(String folderId, String folderName) { + logger.debug("LibraryTopFragment", "Folder selected! folderId: " + folderId + ", folderName: " + folderName); + // 画面遷移 + FragmentNavigation fragmentNavigation = (FragmentNavigation) getActivity(); + assert fragmentNavigation != null; + fragmentNavigation.navigateToFragment(LibraryPageFragment.newInstance(folderId)); + } + + @Override + public void onDocumentSelected(String documentId, String documentName) { + Toast.makeText(getContext(), "Document selected! documentId: " + documentId + ", documentName: " + documentName, Toast.LENGTH_SHORT).show(); + } }); recyclerView.setAdapter(listItemAdapter); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - 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, this.currentTotalItemCount - 1); + if (getArguments() != null) { + this.folderId = getArguments().getString("folderId"); + } + + if (this.folderId == null) { // Root + lacertaLibrary.getLibraryPage(10).thenAccept(libraryItemPage -> { + logger.debug("LibraryTopFragment", "Item selected! libraryItemPage.getListItems().size(): " + libraryItemPage.getListItems().size()); + listItemAdapter.setLibraryItemPage(libraryItemPage); + getActivity().runOnUiThread(() -> { + // ActionBarのタイトルを変更する + getActivity().setTitle("ライブラリ"); + // ActionBarに戻るボタンを非表示にする +// getActivity().getActionBar().setDisplayHomeAsUpEnabled(false); + listItemAdapter.notifyItemRangeInserted(0, libraryItemPage.getListItems().size() - 1); + }); + this.currentTotalItemCount = libraryItemPage.getListItems().size(); }); - }); + } else { // Root以外 + lacertaLibrary.getLibraryPage(this.folderId, 10).thenAccept(libraryItemPage -> { + logger.debug("LibraryTopFragment", "Item selected! libraryItemPage.getListItems().size(): " + libraryItemPage.getListItems().size()); + listItemAdapter.setLibraryItemPage(libraryItemPage); + getActivity().runOnUiThread(() -> { + // ActionBarのタイトルを変更する + getActivity().setTitle(libraryItemPage.getPageTitle()); + // ActionBarに戻るボタンを表示する +// getActivity().getActionBar().setDisplayHomeAsUpEnabled(true); + listItemAdapter.notifyItemRangeInserted(0, libraryItemPage.getListItems().size() - 1); + }); + this.currentTotalItemCount = libraryItemPage.getListItems().size(); + }); + } } @Override diff --git a/feature/library/src/main/java/one/nem/lacerta/feature/library/ListItemAdapter.java b/feature/library/src/main/java/one/nem/lacerta/feature/library/ListItemAdapter.java index e47c465f..9d538716 100644 --- a/feature/library/src/main/java/one/nem/lacerta/feature/library/ListItemAdapter.java +++ b/feature/library/src/main/java/one/nem/lacerta/feature/library/ListItemAdapter.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import one.nem.lacerta.model.LibraryItemPage; import one.nem.lacerta.model.ListItem; +import one.nem.lacerta.model.ListItemType; public class ListItemAdapter extends RecyclerView.Adapter{ @@ -46,9 +47,12 @@ public class ListItemAdapter extends RecyclerView.Adapter { -// Intent intent = new Intent(v.getContext(), ViewerMainActivity.class); -// intent.putExtra("documentId", listItem.getItemId()); -// v.getContext().startActivity(intent); + if (listItem.getItemType() == ListItemType.ITEM_TYPE_DOCUMENT) { + listener.onDocumentSelected(listItem.getItemId(), listItem.getTitle()); + } + else if (listItem.getItemType() == ListItemType.ITEM_TYPE_FOLDER) { + listener.onFolderSelected(listItem.getItemId(), listItem.getTitle()); + } }); } diff --git a/feature/library/src/main/res/navigation/feature_library_navigation.xml b/feature/library/src/main/res/navigation/feature_library_navigation.xml index 9f25086b..136b7b98 100644 --- a/feature/library/src/main/res/navigation/feature_library_navigation.xml +++ b/feature/library/src/main/res/navigation/feature_library_navigation.xml @@ -6,7 +6,7 @@ app:startDestination="@id/feature_library_top_fragment"> \ No newline at end of file diff --git a/model/src/main/java/one/nem/lacerta/model/FragmentNavigation.java b/model/src/main/java/one/nem/lacerta/model/FragmentNavigation.java new file mode 100644 index 00000000..f7cddea6 --- /dev/null +++ b/model/src/main/java/one/nem/lacerta/model/FragmentNavigation.java @@ -0,0 +1,7 @@ +package one.nem.lacerta.model; + +import androidx.fragment.app.Fragment; + +public interface FragmentNavigation { + void navigateToFragment(Fragment fragment); +} 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 de000fbc..ccd902cb 100644 --- a/model/src/main/java/one/nem/lacerta/model/PublicPath.java +++ b/model/src/main/java/one/nem/lacerta/model/PublicPath.java @@ -1,5 +1,7 @@ package one.nem.lacerta.model; +import android.util.Log; + import java.util.ArrayList; import java.util.List; @@ -27,23 +29,23 @@ public class PublicPath { } private void resolveInternal(String path) { - if (path.startsWith("/")) { - this.path.clear(); - this.path.add("/"); + if (path.equals("..")) { + this.path.remove(this.path.size() - 1); + } else if (path.equals(".")) { + // do nothing } else { - if (path.equals("..")) { - this.path.remove(this.path.size() - 1); - } else if (path.equals(".")) { - // do nothing - } else { - this.path.add(path); - } + this.path.add(path); } } public PublicPath parse(String path) { + if (path.startsWith("/")) { + this.path.clear(); + path = path.substring(1); + } String[] pathArray = path.split("/"); for (String p : pathArray) { + Log.d("PublicPath", "parse: " + p); resolveInternal(p); } return this; diff --git a/utils/src/main/java/one/nem/lacerta/utils/FeatureSwitch.java b/utils/src/main/java/one/nem/lacerta/utils/FeatureSwitch.java index f2b6f742..5d8dbc57 100644 --- a/utils/src/main/java/one/nem/lacerta/utils/FeatureSwitch.java +++ b/utils/src/main/java/one/nem/lacerta/utils/FeatureSwitch.java @@ -7,8 +7,8 @@ public class FeatureSwitch { } public static class FeatureMaster { - public static boolean enableSearch = true; - public static boolean enableDebugMenu = true; + public static boolean enableSearch = false; + public static boolean enableDebugMenu = false; } public static class Setting {