diff --git a/app/src/main/java/one/nem/lacerta/MainActivity.java b/app/src/main/java/one/nem/lacerta/MainActivity.java index d7fac694..885ef7ed 100644 --- a/app/src/main/java/one/nem/lacerta/MainActivity.java +++ b/app/src/main/java/one/nem/lacerta/MainActivity.java @@ -8,9 +8,11 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import androidx.navigation.NavController; +import androidx.navigation.NavOptions; import androidx.navigation.fragment.NavHostFragment; import androidx.navigation.ui.NavigationUI; +import android.app.ActivityOptions; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Color; @@ -60,6 +62,19 @@ public class MainActivity extends AppCompatActivity implements FragmentNavigatio assert navHostFragment != null; NavController navController = navHostFragment.getNavController(); NavigationUI.setupWithNavController(bottomNavigationView, navController); + + bottomNavigationView.setOnItemSelectedListener(item -> { + NavOptions navOptions = new NavOptions.Builder() + .setLaunchSingleTop(true) + .setEnterAnim(androidx.navigation.ui.R.anim.nav_default_enter_anim) + .setExitAnim(androidx.navigation.ui.R.anim.nav_default_exit_anim) + .setPopEnterAnim(androidx.navigation.ui.R.anim.nav_default_pop_enter_anim) + .setPopExitAnim(androidx.navigation.ui.R.anim.nav_default_pop_exit_anim) + .build(); + + navController.navigate(item.getItemId(), null, navOptions); + return true; + }); } catch (Exception e) { Log.e("Init", "Failed to init navigation"); @@ -83,7 +98,8 @@ public class MainActivity extends AppCompatActivity implements FragmentNavigatio findViewById(R.id.scanFab).setOnClickListener(v -> { Toast.makeText(this, "Scan", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(this.getApplicationContext(), ScannerManagerActivity.class); - startActivity(intent); +// startActivity(intent); + startActivity(intent, ActivityOptions.makeCustomAnimation(this, one.nem.lacerta.shared.ui.R.anim.nav_up_enter_anim, one.nem.lacerta.shared.ui.R.anim.nav_up_exit_anim).toBundle()); }); } diff --git a/component/common/build.gradle b/component/common/build.gradle index cf064b8f..d6dd1b67 100644 --- a/component/common/build.gradle +++ b/component/common/build.gradle @@ -42,4 +42,6 @@ dependencies { implementation project(':utils') implementation project(':model') implementation project(':data') + + implementation project(':vcs') } \ No newline at end of file diff --git a/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectDirDialog.java b/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectDirDialog.java index 7d3d4b81..6ac7e938 100644 --- a/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectDirDialog.java +++ b/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectDirDialog.java @@ -79,8 +79,8 @@ public class LacertaSelectDirDialog extends DialogFragment { LayoutInflater inflater = requireActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.lacerta_dialog_select_dir, null); - // 高さを画面の60%にする - int height = (int) (getResources().getDisplayMetrics().heightPixels * 0.6); + // 高さを画面の40%にする + int height = (int) (getResources().getDisplayMetrics().heightPixels * 0.4); view.setMinimumHeight(height); this.recyclerView = view.findViewById(R.id.select_dir_recycler_view); diff --git a/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectRevDialog.java b/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectRevDialog.java new file mode 100644 index 00000000..c3650eb3 --- /dev/null +++ b/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectRevDialog.java @@ -0,0 +1,112 @@ +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.Toast; + +import androidx.fragment.app.DialogFragment; +import androidx.recyclerview.widget.LinearLayoutManager; +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.utils.LacertaLogger; +import one.nem.lacerta.vcs.LacertaVcs; +import one.nem.lacerta.vcs.factory.LacertaVcsFactory; + + +@AndroidEntryPoint +public class LacertaSelectRevDialog extends DialogFragment { + + @Inject + LacertaVcsFactory lacertaVcsFactory; + + @Inject + LacertaLogger logger; + + String title; + String documentId; + String message; + String negativeButtonText; + + LacertaSelectRevDialogListener listener; + + public LacertaSelectRevDialog setTitle(String title) { + this.title = title; + return this; + } + + public LacertaSelectRevDialog setDocumentId(String documentId) { + this.documentId = documentId; + return this; + } + + public LacertaSelectRevDialog setMessage(String message) { + this.message = message; + return this; + } + + public LacertaSelectRevDialog setNegativeButtonText(String negativeButtonText) { + this.negativeButtonText = negativeButtonText; + return this; + } + + public LacertaSelectRevDialog setListener(LacertaSelectRevDialogListener listener) { + this.listener = listener; + 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_rev, null); + + int height = (int) (getResources().getDisplayMetrics().heightPixels * 0.4); + view.setMinimumHeight(height); + + RecyclerView recyclerView = view.findViewById(R.id.select_rev_recycler_view); + + SelectRevDialogItemAdapter adapter = new SelectRevDialogItemAdapter(revId -> { + if (listener != null) { + listener.onItemSelected(revId); + dismiss(); + } + }); + recyclerView.setAdapter(adapter); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + builder.setView(view); + + if (this.documentId == null) { + logger.error("SelectRevDialog", "documentId is null"); + logger.e_code("0296fb0c-07a3-4971-a280-bd1a61461bb7"); + Toast.makeText(getContext(), "Sorry, something went wrong", Toast.LENGTH_SHORT).show(); + dismiss(); + } + LacertaVcs lacertaVcs = lacertaVcsFactory.create(this.documentId); + lacertaVcs.getRevisionHistory().thenAccept(revList -> { + adapter.setRevList(revList); + adapter.notifyDataSetChanged(); // TODO-rca:時間に応じてアニメーションをつける + }); + + + builder.setTitle(title == null ? "Select Rev" : title); + builder.setMessage(message == null ? "Select Rev" : message); + builder.setNegativeButton(negativeButtonText == null ? "Cancel" : negativeButtonText, (dialog, which) -> { + if (listener != null) { + listener.onDialogCanceled(); + dismiss(); + } + }); + + return builder.create(); + } +} diff --git a/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectRevDialogInternalListener.java b/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectRevDialogInternalListener.java new file mode 100644 index 00000000..7988bd22 --- /dev/null +++ b/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectRevDialogInternalListener.java @@ -0,0 +1,6 @@ +package one.nem.lacerta.component.common; + +public interface LacertaSelectRevDialogInternalListener { + + void onItemSelected(String revId); +} diff --git a/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectRevDialogListener.java b/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectRevDialogListener.java new file mode 100644 index 00000000..3a7f808d --- /dev/null +++ b/component/common/src/main/java/one/nem/lacerta/component/common/LacertaSelectRevDialogListener.java @@ -0,0 +1,8 @@ +package one.nem.lacerta.component.common; + +public interface LacertaSelectRevDialogListener { + + void onItemSelected(String revId); + + void onDialogCanceled(); +} diff --git a/component/common/src/main/java/one/nem/lacerta/component/common/SelectRevDialogItemAdapter.java b/component/common/src/main/java/one/nem/lacerta/component/common/SelectRevDialogItemAdapter.java new file mode 100644 index 00000000..6b26d4fc --- /dev/null +++ b/component/common/src/main/java/one/nem/lacerta/component/common/SelectRevDialogItemAdapter.java @@ -0,0 +1,66 @@ +package one.nem.lacerta.component.common; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; + +import one.nem.lacerta.model.VcsRevModel; + +public class SelectRevDialogItemAdapter extends RecyclerView.Adapter{ + + ArrayList revList; + + LacertaSelectRevDialogInternalListener listener; + + public SelectRevDialogItemAdapter(LacertaSelectRevDialogInternalListener listener) { + this.listener = listener; + } + + public void setRevList(ArrayList revList) { + this.revList = revList; + } + + @NonNull + @Override + public SelectRevDialogItemAdapter.SelectRevDialogItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.common_rev_list_item, parent, false); + return new SelectRevDialogItemAdapter.SelectRevDialogItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull SelectRevDialogItemAdapter.SelectRevDialogItemViewHolder holder, int position) { + VcsRevModel rev = revList.get(position); + holder.title.setText(rev.getCommitMessage()); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + holder.description.setText(simpleDateFormat.format(rev.getCreatedAt())); + holder.revId.setText("RevID: " + rev.getId()); + + holder.itemView.setOnClickListener(v -> listener.onItemSelected(rev.getId())); + } + + @Override + public int getItemCount() { + return this.revList == null ? 0 : this.revList.size(); + } + + public class SelectRevDialogItemViewHolder extends RecyclerView.ViewHolder { + + TextView title; + TextView description; + TextView revId; + + public SelectRevDialogItemViewHolder(@NonNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.rev_item_title); + description = itemView.findViewById(R.id.rev_item_detail); + revId = itemView.findViewById(R.id.rev_item_id); + } + } +} diff --git a/component/common/src/main/res/layout/common_rev_list_item.xml b/component/common/src/main/res/layout/common_rev_list_item.xml new file mode 100644 index 00000000..682c3133 --- /dev/null +++ b/component/common/src/main/res/layout/common_rev_list_item.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/component/common/src/main/res/layout/lacerta_dialog_select_rev.xml b/component/common/src/main/res/layout/lacerta_dialog_select_rev.xml new file mode 100644 index 00000000..59ea619b --- /dev/null +++ b/component/common/src/main/res/layout/lacerta_dialog_select_rev.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/component/viewer/src/main/java/one/nem/lacerta/component/viewer/ViewerListFragment.java b/component/viewer/src/main/java/one/nem/lacerta/component/viewer/ViewerListFragment.java index 7a35379a..349bc99a 100644 --- a/component/viewer/src/main/java/one/nem/lacerta/component/viewer/ViewerListFragment.java +++ b/component/viewer/src/main/java/one/nem/lacerta/component/viewer/ViewerListFragment.java @@ -21,7 +21,11 @@ import javax.inject.Inject; import dagger.hilt.android.AndroidEntryPoint; import one.nem.lacerta.component.common.LacertaSelectDirDialog; import one.nem.lacerta.component.common.LacertaSelectDirDialogListener; +import one.nem.lacerta.component.common.LacertaSelectRevDialog; +import one.nem.lacerta.component.common.LacertaSelectRevDialogListener; import one.nem.lacerta.data.Document; +import one.nem.lacerta.data.LacertaLibrary; +import one.nem.lacerta.model.ListItemType; import one.nem.lacerta.model.document.page.Page; import one.nem.lacerta.utils.FeatureSwitch; import one.nem.lacerta.utils.LacertaLogger; @@ -39,6 +43,9 @@ public class ViewerListFragment extends Fragment { @Inject Document document; + @Inject + LacertaLibrary lacertaLibrary; + @Inject LacertaLogger logger; @@ -92,7 +99,7 @@ public class ViewerListFragment extends Fragment { // Toolbar Toolbar toolbar = view.findViewById(R.id.toolbar); - toolbarSetup(toolbar, true, this.documentName == null ? "Document" : this.documentName); + toolbarSetup(toolbar, true, this.documentName == null ? "Document" : this.documentName, null); RecyclerView recyclerView = view.findViewById(R.id.body_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); @@ -112,6 +119,8 @@ public class ViewerListFragment extends Fragment { viewerBodyAdapter.notifyItemRangeChanged(0, pages.size()); if (FeatureSwitch.Viewer.showProgressBarWhenLoading) view.findViewById(R.id.loading_progress_bar).setVisibility(View.GONE); }); + }).thenCompose(aVoid -> lacertaLibrary.getPublicPath(documentId, ListItemType.ITEM_TYPE_DOCUMENT)).thenAccept(publicPath -> { + updateToolbarSubtitle(toolbar, "/" + publicPath.parent().getStringPath()); }); } else { logger.debug(TAG, "revisionId: " + revisionId); @@ -127,23 +136,35 @@ public class ViewerListFragment extends Fragment { if (FeatureSwitch.Viewer.showProgressBarWhenLoading) view.findViewById(R.id.loading_progress_bar).setVisibility(View.GONE); }); }); + }).thenCompose(aVoid -> lacertaLibrary.getPublicPath(documentId, ListItemType.ITEM_TYPE_DOCUMENT)).thenAccept(publicPath -> { + updateToolbarSubtitle(toolbar, "/" + publicPath.parent().getStringPath()); // TODO-rca: リビジョンの場合はリビジョン名を表示する? }); } return view; } + /** + * Toolbarのサブタイトルを更新 + * @param subtitle サブタイトル + */ + private void updateToolbarSubtitle(Toolbar toolbar, String subtitle) { + getActivity().runOnUiThread(() -> { + toolbar.setSubtitle(subtitle); + }); + } + /** * ToolbarをInitする * * @param toolbar Toolbar - * @param showBackButton 戻るボタンを表示するか + * @param showCloseButton 戻るボタンを表示するか * @param title タイトル */ - private void toolbarSetup(Toolbar toolbar, boolean showBackButton, String title) { + private void toolbarSetup(Toolbar toolbar, boolean showCloseButton, String title, String Subtitle) { getActivity().runOnUiThread(() -> { - if (showBackButton) { - toolbar.setNavigationIcon(one.nem.lacerta.shared.ui.R.drawable.arrow_back_24px); + if (showCloseButton) { + toolbar.setNavigationIcon(one.nem.lacerta.shared.ui.R.drawable.close_24px); toolbar.setNavigationOnClickListener(v -> { // Stop Activity getActivity().finish(); @@ -152,13 +173,26 @@ public class ViewerListFragment extends Fragment { toolbar.setNavigationIcon(null); } toolbar.setTitle(title); + if (Subtitle != null) toolbar.setSubtitle(Subtitle); toolbar.inflateMenu(R.menu.viewer_menu); toolbar.setOnMenuItemClickListener(item -> { if (item.getItemId() == R.id.action_open_vcs_rev_list) { - // Open vcs rev list - getParentFragmentManager().beginTransaction() - .replace(R.id.nav_host_fragment, ViewerVcsRevListFragment.newInstance(documentId, documentName)) - .commit(); + LacertaSelectRevDialog lacertaSelectRevDialog = new LacertaSelectRevDialog(); + lacertaSelectRevDialog.setDocumentId(this.documentId).setTitle("リビジョンの選択").setMessage("リビジョンを選択してください。").setNegativeButtonText("キャンセル"); + lacertaSelectRevDialog.setListener(new LacertaSelectRevDialogListener() { + @Override + public void onItemSelected(String revId) { + getParentFragmentManager().beginTransaction() + .replace(R.id.nav_host_fragment, ViewerListFragment.newInstance(documentId, documentName, revisionId)) + .commit(); + } + + @Override + public void onDialogCanceled() { + logger.debug(TAG, "Canceled"); + } + }); + lacertaSelectRevDialog.show(getParentFragmentManager(), "select_rev_dialog"); return true; } else if (item.getItemId() == R.id.action_rename) { @@ -205,7 +239,6 @@ public class ViewerListFragment extends Fragment { builder.show(); return true; } else if (item.getItemId() == R.id.action_move) { -// Toast.makeText(getContext(), "Work in progress", Toast.LENGTH_SHORT).show(); LacertaSelectDirDialog lacertaSelectDirDialog = new LacertaSelectDirDialog(); lacertaSelectDirDialog.setListener(new LacertaSelectDirDialogListener() { @Override diff --git a/component/viewer/src/main/java/one/nem/lacerta/component/viewer/ViewerMainActivity.java b/component/viewer/src/main/java/one/nem/lacerta/component/viewer/ViewerMainActivity.java index 6c079c11..0b9a3e59 100644 --- a/component/viewer/src/main/java/one/nem/lacerta/component/viewer/ViewerMainActivity.java +++ b/component/viewer/src/main/java/one/nem/lacerta/component/viewer/ViewerMainActivity.java @@ -5,6 +5,7 @@ import android.os.Bundle; import android.widget.Toast; import androidx.activity.EdgeToEdge; +import androidx.activity.OnBackPressedCallback; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; @@ -41,6 +42,9 @@ public class ViewerMainActivity extends AppCompatActivity { return insets; }); +// // Transition +// overridePendingTransition(one.nem.lacerta.shared.ui.R.anim.nav_up_enter_anim, one.nem.lacerta.shared.ui.R.anim.nav_up_exit_anim); + Intent intent = getIntent(); try { documentId = intent.getStringExtra("documentId"); @@ -58,4 +62,5 @@ public class ViewerMainActivity extends AppCompatActivity { .replace(R.id.nav_host_fragment, ViewerListFragment.newInstance(documentId, documentName)) .commit(); } + } \ No newline at end of file diff --git a/component/viewer/src/main/res/layout/fragment_component_viewer_top.xml b/component/viewer/src/main/res/layout/fragment_component_viewer_top.xml index 6c8791de..9d83ea68 100644 --- a/component/viewer/src/main/res/layout/fragment_component_viewer_top.xml +++ b/component/viewer/src/main/res/layout/fragment_component_viewer_top.xml @@ -13,7 +13,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - - + { + long endTime = System.currentTimeMillis(); if (listItems == null) { return; } this.listItemAdapter.setListItems(listItems); - getActivity().runOnUiThread(() -> { - Log.d("HomeTopFragment", "onViewCreated: " + listItems.size()); - if (FeatureSwitch.RecyclerView.useSimpleNotifyMethod) { + if (endTime - startTime > 500) { // 500ms以上かかった場合は表示アニメーションをする + getActivity().runOnUiThread(() -> { + this.listItemAdapter.notifyItemRangeInserted(0, listItems.size()); + }); + } else { + getActivity().runOnUiThread(() -> { this.listItemAdapter.notifyDataSetChanged(); - } else { - // IndexOutOfBoundsExceptionを吐くことがあったので いったん - this.listItemAdapter.notifyItemRangeInserted(0, listItems.size() - 1); - } - }); + }); + } }); } diff --git a/feature/library/build.gradle b/feature/library/build.gradle index 6b102535..6a661620 100644 --- a/feature/library/build.gradle +++ b/feature/library/build.gradle @@ -55,5 +55,6 @@ dependencies { implementation project(':component:viewer') - + // TODO-rca: バージョンカタログに切り出す + implementation "com.hendraanggrian.material:collapsingtoolbarlayout-subtitle:1.5.0" } \ No newline at end of file diff --git a/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryPageFragment.java b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryPageFragment.java index df1ad96b..e23d2089 100644 --- a/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryPageFragment.java +++ b/feature/library/src/main/java/one/nem/lacerta/feature/library/LibraryPageFragment.java @@ -23,6 +23,7 @@ import dagger.hilt.android.AndroidEntryPoint; import one.nem.lacerta.component.viewer.ViewerMainActivity; import one.nem.lacerta.data.LacertaLibrary; import one.nem.lacerta.model.LibraryItemPage; +import one.nem.lacerta.model.ListItemType; import one.nem.lacerta.utils.FeatureSwitch; import one.nem.lacerta.utils.LacertaLogger; @@ -43,6 +44,7 @@ public class LibraryPageFragment extends Fragment { String folderId; String title; String parentId; + Toolbar toolbar; @Inject @@ -128,12 +130,19 @@ public class LibraryPageFragment extends Fragment { logger.debug("LibraryTopFragment", "getArguments() is null(maybe root)"); this.libraryItemPage = new LibraryItemPage(); } + this.toolbar = view.findViewById(R.id.library_toolbar); // Toolbar Setup - toolbarSetup(view.findViewById(R.id.library_toolbar), this.folderId != null, this.title != null ? this.title : "ライブラリ"); + toolbarSetup(this.toolbar, this.folderId != null, this.title != null ? this.title : "ライブラリ"); + if(this.folderId == null) { + updateToolbarSubtitle(this.toolbar, null); //負荷軽減のため+邪魔なので(folderIdがnullの場合は、ルートフォルダを表示しているので) + } else { + lacertaLibrary.getPublicPath(this.folderId, ListItemType.ITEM_TYPE_FOLDER).thenAccept(publicPath -> { + updateToolbarSubtitle(this.toolbar, "/" + publicPath.parent().getStringPath()); + }); + } // RecyclerView Setup - RecyclerView recyclerView = view.findViewById(R.id.library_item_recycler_view); this.listItemAdapter = new ListItemAdapter(new DocumentSelectListener() { @Override @@ -168,33 +177,8 @@ public class LibraryPageFragment extends Fragment { recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); // Get library page and update RecyclerView items - lacertaLibrary.getLibraryPage(this.folderId, 10).thenAccept(libraryItemPage -> { - this.libraryItemPage = libraryItemPage; - if (this.parentId == null) { - this.parentId = libraryItemPage.getParentId(); - } - if (this.title == null) { - this.title = libraryItemPage.getPageTitle(); - // Toolbar init again - toolbarSetup(view.findViewById(R.id.library_toolbar), this.folderId != null, this.title != null ? this.title : "ライブラリ"); - } - - logger.debug("LibraryTopFragment", "Item selected! Total item page: " + this.libraryItemPage.getListItems().size()); - if (!FeatureSwitch.RecyclerView.useSimpleNotifyMethod) { - getActivity().runOnUiThread(() -> { // TODO-rca: 実行条件を考える? - listItemAdapter.notifyItemRangeRemoved(0, this.libraryItemPage.getListItems().size() - 1); - }); - } - listItemAdapter.setLibraryItemPage(this.libraryItemPage); - getActivity().runOnUiThread(() -> { - if (FeatureSwitch.RecyclerView.useSimpleNotifyMethod) { - listItemAdapter.notifyDataSetChanged(); - } else { - listItemAdapter.notifyItemRangeInserted(0, this.libraryItemPage.getListItems().size() - 1); - } - }); - }); + updateItem(this.folderId); } /** @@ -216,6 +200,7 @@ public class LibraryPageFragment extends Fragment { lacertaLibrary.createFolder(pageId, input.getText().toString()).thenAccept(folderId -> { // Refresh updateItem(pageId); + }); }); builder.setNegativeButton("キャンセル", (dialog, which) -> { @@ -226,19 +211,34 @@ public class LibraryPageFragment extends Fragment { } /** - * RecyclerViewのアイテムを更新する + * RecyclerViewのアイテムとUIを更新する */ private void updateItem(String pageId) { + long startTime = System.currentTimeMillis(); lacertaLibrary.getLibraryPage(pageId, 10).thenAccept(libraryItemPage -> { + long endTime = System.currentTimeMillis(); this.libraryItemPage = libraryItemPage; logger.debug("LibraryTopFragment", "Item selected! libraryItemPage.getListItems().size(): " + libraryItemPage.getListItems().size()); - getActivity().runOnUiThread(() -> { - listItemAdapter.notifyItemRangeRemoved(0, libraryItemPage.getListItems().size() - 1); - }); listItemAdapter.setLibraryItemPage(libraryItemPage); - getActivity().runOnUiThread(() -> { - listItemAdapter.notifyItemRangeInserted(0, libraryItemPage.getListItems().size() - 1); - }); + if (endTime - startTime > 500) { // 500ms以上かかった場合は表示アニメーションをする + getActivity().runOnUiThread(() -> { + listItemAdapter.notifyItemRangeInserted(0, this.libraryItemPage.getListItems().size()); + }); + } else { + getActivity().runOnUiThread(() -> { + listItemAdapter.notifyDataSetChanged(); + }); + } + }); + } + + /** + * Toolbarのサブタイトルを更新 + * @param subtitle サブタイトル + */ + private void updateToolbarSubtitle(Toolbar toolbar, String subtitle) { + getActivity().runOnUiThread(() -> { + toolbar.setSubtitle(subtitle); }); } diff --git a/feature/library/src/main/res/layout/fragment_library_top.xml b/feature/library/src/main/res/layout/fragment_library_top.xml index f9d53d56..29f1bcbf 100644 --- a/feature/library/src/main/res/layout/fragment_library_top.xml +++ b/feature/library/src/main/res/layout/fragment_library_top.xml @@ -13,7 +13,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - - + 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 3a5dcd14..a914d07c 100644 --- a/feature/library/src/main/res/navigation/feature_library_navigation.xml +++ b/feature/library/src/main/res/navigation/feature_library_navigation.xml @@ -12,10 +12,10 @@ diff --git a/shared/ui/src/main/res/anim/nav_dynamic_enter_anim.xml b/shared/ui/src/main/res/anim/nav_dynamic_enter_anim.xml new file mode 100644 index 00000000..e74131cc --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_dynamic_enter_anim.xml @@ -0,0 +1,25 @@ + + + + + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_dynamic_exit_anim.xml b/shared/ui/src/main/res/anim/nav_dynamic_exit_anim.xml new file mode 100644 index 00000000..507b9e99 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_dynamic_exit_anim.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_dynamic_pop_enter_anim.xml b/shared/ui/src/main/res/anim/nav_dynamic_pop_enter_anim.xml new file mode 100644 index 00000000..ad403d7f --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_dynamic_pop_enter_anim.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_dynamic_pop_exit_anim.xml b/shared/ui/src/main/res/anim/nav_dynamic_pop_exit_anim.xml new file mode 100644 index 00000000..a056da6c --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_dynamic_pop_exit_anim.xml @@ -0,0 +1,25 @@ + + + + + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_ios_enter_anim.xml b/shared/ui/src/main/res/anim/nav_ios_enter_anim.xml new file mode 100644 index 00000000..d306bde5 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_ios_enter_anim.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_ios_exit_anim.xml b/shared/ui/src/main/res/anim/nav_ios_exit_anim.xml new file mode 100644 index 00000000..04bca2eb --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_ios_exit_anim.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_ios_pop_enter_anim.xml b/shared/ui/src/main/res/anim/nav_ios_pop_enter_anim.xml new file mode 100644 index 00000000..ae8e57d7 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_ios_pop_enter_anim.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_ios_pop_exit_anim.xml b/shared/ui/src/main/res/anim/nav_ios_pop_exit_anim.xml new file mode 100644 index 00000000..4459fd2d --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_ios_pop_exit_anim.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_rotate_enter_anim.xml b/shared/ui/src/main/res/anim/nav_rotate_enter_anim.xml new file mode 100644 index 00000000..b036d2b1 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_rotate_enter_anim.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_rotate_exit_anim.xml b/shared/ui/src/main/res/anim/nav_rotate_exit_anim.xml new file mode 100644 index 00000000..6e888fb2 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_rotate_exit_anim.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_rotate_pop_enter_anim.xml b/shared/ui/src/main/res/anim/nav_rotate_pop_enter_anim.xml new file mode 100644 index 00000000..0bd0db3b --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_rotate_pop_enter_anim.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_rotate_pop_exit_anim.xml b/shared/ui/src/main/res/anim/nav_rotate_pop_exit_anim.xml new file mode 100644 index 00000000..15d761c6 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_rotate_pop_exit_anim.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_slide_enter_anim.xml b/shared/ui/src/main/res/anim/nav_slide_enter_anim.xml new file mode 100644 index 00000000..dedef17b --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_slide_enter_anim.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_slide_exit_anim.xml b/shared/ui/src/main/res/anim/nav_slide_exit_anim.xml new file mode 100644 index 00000000..83d47c79 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_slide_exit_anim.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_slide_pop_enter_anim.xml b/shared/ui/src/main/res/anim/nav_slide_pop_enter_anim.xml new file mode 100644 index 00000000..4e3d476c --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_slide_pop_enter_anim.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_slide_pop_exit_anim.xml b/shared/ui/src/main/res/anim/nav_slide_pop_exit_anim.xml new file mode 100644 index 00000000..4013e294 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_slide_pop_exit_anim.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_twitter_enter_anim.xml b/shared/ui/src/main/res/anim/nav_twitter_enter_anim.xml new file mode 100644 index 00000000..d306bde5 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_twitter_enter_anim.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_twitter_exit_anim.xml b/shared/ui/src/main/res/anim/nav_twitter_exit_anim.xml new file mode 100644 index 00000000..0ca28555 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_twitter_exit_anim.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_twitter_pop_enter_anim.xml b/shared/ui/src/main/res/anim/nav_twitter_pop_enter_anim.xml new file mode 100644 index 00000000..af2f005a --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_twitter_pop_enter_anim.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_twitter_pop_exit_anim.xml b/shared/ui/src/main/res/anim/nav_twitter_pop_exit_anim.xml new file mode 100644 index 00000000..4459fd2d --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_twitter_pop_exit_anim.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_up_enter_anim.xml b/shared/ui/src/main/res/anim/nav_up_enter_anim.xml new file mode 100644 index 00000000..0f7ec42b --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_up_enter_anim.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_up_exit_anim.xml b/shared/ui/src/main/res/anim/nav_up_exit_anim.xml new file mode 100644 index 00000000..b851c737 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_up_exit_anim.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_up_pop_enter_anim.xml b/shared/ui/src/main/res/anim/nav_up_pop_enter_anim.xml new file mode 100644 index 00000000..b851c737 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_up_pop_enter_anim.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_up_pop_exit_anim.xml b/shared/ui/src/main/res/anim/nav_up_pop_exit_anim.xml new file mode 100644 index 00000000..0c962854 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_up_pop_exit_anim.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_zoom_enter_anim.xml b/shared/ui/src/main/res/anim/nav_zoom_enter_anim.xml new file mode 100644 index 00000000..7f038753 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_zoom_enter_anim.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_zoom_exit_anim.xml b/shared/ui/src/main/res/anim/nav_zoom_exit_anim.xml new file mode 100644 index 00000000..88ddc418 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_zoom_exit_anim.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_zoom_pop_enter_anim.xml b/shared/ui/src/main/res/anim/nav_zoom_pop_enter_anim.xml new file mode 100644 index 00000000..66c8593a --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_zoom_pop_enter_anim.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/shared/ui/src/main/res/anim/nav_zoom_pop_exit_anim.xml b/shared/ui/src/main/res/anim/nav_zoom_pop_exit_anim.xml new file mode 100644 index 00000000..ba3d2b03 --- /dev/null +++ b/shared/ui/src/main/res/anim/nav_zoom_pop_exit_anim.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file