mirror of
https://github.com/lacerta-doc/Lacerta.git
synced 2024-11-26 17:53:14 +00:00
commit
517b7d2c39
|
@ -12,6 +12,7 @@ import java.text.SimpleDateFormat;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import one.nem.lacerta.component.viewer.model.RevSelectListener;
|
||||||
import one.nem.lacerta.model.VcsRevModel;
|
import one.nem.lacerta.model.VcsRevModel;
|
||||||
import one.nem.lacerta.utils.FeatureSwitch;
|
import one.nem.lacerta.utils.FeatureSwitch;
|
||||||
|
|
||||||
|
@ -19,11 +20,14 @@ public class RevAdapter extends RecyclerView.Adapter<RevAdapter.RevViewHolder>{
|
||||||
|
|
||||||
private ArrayList<VcsRevModel> revModels;
|
private ArrayList<VcsRevModel> revModels;
|
||||||
|
|
||||||
|
private RevSelectListener revSelectListener;
|
||||||
|
|
||||||
public RevAdapter(ArrayList<VcsRevModel> revModels) {
|
public RevAdapter(ArrayList<VcsRevModel> revModels) {
|
||||||
this.revModels = revModels;
|
this.revModels = revModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RevAdapter() {
|
public RevAdapter(RevSelectListener revSelectListener) {
|
||||||
|
this.revSelectListener = revSelectListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRevModels(ArrayList<VcsRevModel> revModels) {
|
public void setRevModels(ArrayList<VcsRevModel> revModels) {
|
||||||
|
@ -52,6 +56,13 @@ public class RevAdapter extends RecyclerView.Adapter<RevAdapter.RevViewHolder>{
|
||||||
}
|
}
|
||||||
holder.revId.setText("RevID: " + revModel.getId());
|
holder.revId.setText("RevID: " + revModel.getId());
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
revSelectListener.onRevSelect(revModel.getId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package one.nem.lacerta.component.viewer;
|
package one.nem.lacerta.component.viewer;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.navigation.Navigation;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
@ -16,24 +14,24 @@ import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
import one.nem.lacerta.data.Document;
|
import one.nem.lacerta.data.Document;
|
||||||
import one.nem.lacerta.model.document.DocumentDetail;
|
|
||||||
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;
|
||||||
import one.nem.lacerta.utils.LacertaLogger;
|
import one.nem.lacerta.utils.LacertaLogger;
|
||||||
|
import one.nem.lacerta.vcs.LacertaVcs;
|
||||||
|
import one.nem.lacerta.vcs.factory.LacertaVcsFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* A simple {@link Fragment} subclass.
|
||||||
* Use the {@link ComponentViewerTopFragment#newInstance} factory method to
|
* Use the {@link ViewerListFragment#newInstance} factory method to
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class ComponentViewerTopFragment extends Fragment {
|
public class ViewerListFragment extends Fragment {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Document document;
|
Document document;
|
||||||
|
@ -41,17 +39,21 @@ public class ComponentViewerTopFragment extends Fragment {
|
||||||
@Inject
|
@Inject
|
||||||
LacertaLogger logger;
|
LacertaLogger logger;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
LacertaVcsFactory lacertaVcsFactory;
|
||||||
|
|
||||||
private static final String TAG = "ComponentViewerTopFragment";
|
private static final String TAG = "ComponentViewerTopFragment";
|
||||||
|
|
||||||
private String documentId;
|
private String documentId;
|
||||||
private String documentName;
|
private String documentName;
|
||||||
|
private String revisionId;
|
||||||
|
|
||||||
public ComponentViewerTopFragment() {
|
public ViewerListFragment() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ComponentViewerTopFragment newInstance(String documentId, String documentName) {
|
public static ViewerListFragment newInstance(String documentId, String documentName) {
|
||||||
ComponentViewerTopFragment fragment = new ComponentViewerTopFragment();
|
ViewerListFragment fragment = new ViewerListFragment();
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString("documentId", documentId);
|
args.putString("documentId", documentId);
|
||||||
args.putString("documentName", documentName);
|
args.putString("documentName", documentName);
|
||||||
|
@ -59,12 +61,23 @@ public class ComponentViewerTopFragment extends Fragment {
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ViewerListFragment newInstance(String documentId, String documentName, String revisionId) {
|
||||||
|
ViewerListFragment fragment = new ViewerListFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString("documentId", documentId);
|
||||||
|
args.putString("documentName", documentName);
|
||||||
|
args.putString("revisionId", revisionId);
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
documentId = getArguments().getString("documentId");
|
documentId = getArguments().getString("documentId");
|
||||||
documentName = getArguments().getString("documentName");
|
documentName = getArguments().getString("documentName");
|
||||||
|
revisionId = getArguments().getString("revisionId");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +98,8 @@ public class ComponentViewerTopFragment extends Fragment {
|
||||||
});
|
});
|
||||||
recyclerView.setAdapter(viewerBodyAdapter);
|
recyclerView.setAdapter(viewerBodyAdapter);
|
||||||
|
|
||||||
|
if (revisionId == null) {
|
||||||
|
logger.debug(TAG, "revisionId is empty, loading latest revision");
|
||||||
if (FeatureSwitch.Viewer.showProgressBarWhenLoading) view.findViewById(R.id.loading_progress_bar).setVisibility(View.VISIBLE);
|
if (FeatureSwitch.Viewer.showProgressBarWhenLoading) view.findViewById(R.id.loading_progress_bar).setVisibility(View.VISIBLE);
|
||||||
document.getDocument(documentId).thenAccept(documentDetail -> {
|
document.getDocument(documentId).thenAccept(documentDetail -> {
|
||||||
ArrayList<Page> pages = documentDetail.getPages();
|
ArrayList<Page> pages = documentDetail.getPages();
|
||||||
|
@ -95,6 +110,22 @@ public class ComponentViewerTopFragment extends Fragment {
|
||||||
if (FeatureSwitch.Viewer.showProgressBarWhenLoading) view.findViewById(R.id.loading_progress_bar).setVisibility(View.GONE);
|
if (FeatureSwitch.Viewer.showProgressBarWhenLoading) view.findViewById(R.id.loading_progress_bar).setVisibility(View.GONE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
logger.debug(TAG, "revisionId: " + revisionId);
|
||||||
|
if (FeatureSwitch.Viewer.showProgressBarWhenLoading) view.findViewById(R.id.loading_progress_bar).setVisibility(View.VISIBLE);
|
||||||
|
LacertaVcs lacertaVcs = lacertaVcsFactory.create(documentId);
|
||||||
|
lacertaVcs.getDocumentPagePathListRev(revisionId).thenAccept(documentPathList -> {
|
||||||
|
logger.debug(TAG, "documentPathList.size(): " + documentPathList.size());
|
||||||
|
document.getDocumentPageListByFileNameList(documentId, documentPathList).thenAccept(pages -> {
|
||||||
|
logger.debug(TAG, "pages.size(): " + pages.size());
|
||||||
|
viewerBodyAdapter.setPages(pages);
|
||||||
|
getActivity().runOnUiThread(() -> {
|
||||||
|
viewerBodyAdapter.notifyItemRangeChanged(0, pages.size());
|
||||||
|
if (FeatureSwitch.Viewer.showProgressBarWhenLoading) view.findViewById(R.id.loading_progress_bar).setVisibility(View.GONE);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -123,7 +154,7 @@ public class ComponentViewerTopFragment extends Fragment {
|
||||||
if (item.getItemId() == R.id.action_open_vcs_rev_list) {
|
if (item.getItemId() == R.id.action_open_vcs_rev_list) {
|
||||||
// Open vcs rev list
|
// Open vcs rev list
|
||||||
getParentFragmentManager().beginTransaction()
|
getParentFragmentManager().beginTransaction()
|
||||||
.replace(R.id.nav_host_fragment, ViewerVcsRevListFragment.newInstance(documentId))
|
.replace(R.id.nav_host_fragment, ViewerVcsRevListFragment.newInstance(documentId, documentName))
|
||||||
.commit();
|
.commit();
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.action_rename) {
|
} else if (item.getItemId() == R.id.action_rename) {
|
|
@ -2,7 +2,6 @@ package one.nem.lacerta.component.viewer;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.activity.EdgeToEdge;
|
import androidx.activity.EdgeToEdge;
|
||||||
|
@ -10,12 +9,6 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.graphics.Insets;
|
import androidx.core.graphics.Insets;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
import androidx.fragment.app.FragmentManager;
|
|
||||||
import androidx.navigation.NavController;
|
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
|
||||||
import androidx.navigation.ui.NavigationUI;
|
|
||||||
|
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@ -62,7 +55,7 @@ public class ViewerMainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.replace(R.id.nav_host_fragment, ComponentViewerTopFragment.newInstance(documentId, documentName))
|
.replace(R.id.nav_host_fragment, ViewerListFragment.newInstance(documentId, documentName))
|
||||||
.commit();
|
.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,15 +34,17 @@ public class ViewerVcsRevListFragment extends Fragment {
|
||||||
LacertaVcs lacertaVcs;
|
LacertaVcs lacertaVcs;
|
||||||
|
|
||||||
private String documentId;
|
private String documentId;
|
||||||
|
private String documentName;
|
||||||
|
|
||||||
public ViewerVcsRevListFragment() {
|
public ViewerVcsRevListFragment() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ViewerVcsRevListFragment newInstance(String documentId) {
|
public static ViewerVcsRevListFragment newInstance(String documentId, String documentName) {
|
||||||
ViewerVcsRevListFragment fragment = new ViewerVcsRevListFragment();
|
ViewerVcsRevListFragment fragment = new ViewerVcsRevListFragment();
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString("documentId", documentId);
|
args.putString("documentId", documentId);
|
||||||
|
args.putString("documentName", documentName);
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
@ -66,17 +68,22 @@ public class ViewerVcsRevListFragment extends Fragment {
|
||||||
// Init arg
|
// Init arg
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
this.documentId = getArguments().getString("documentId");
|
this.documentId = getArguments().getString("documentId");
|
||||||
logger.debug("ViewerVcsRevListFragment", "documentId: " + documentId);
|
logger.debug("ViewerVcsRevListFragment", "documentId: " + this.documentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init vcs
|
// Init vcs
|
||||||
lacertaVcs = lacertaVcsFactory.create(documentId);
|
lacertaVcs = lacertaVcsFactory.create(this.documentId);
|
||||||
|
|
||||||
// Init view
|
// Init view
|
||||||
RecyclerView recyclerView = view.findViewById(R.id.rev_list);
|
RecyclerView recyclerView = view.findViewById(R.id.rev_list);
|
||||||
|
|
||||||
// Init adapter
|
// Init adapter
|
||||||
RevAdapter revAdapter = new RevAdapter();
|
RevAdapter revAdapter = new RevAdapter(revisionId -> {
|
||||||
|
logger.debug("ViewerVcsRevListFragment", "Selected revisionId: " + revisionId);
|
||||||
|
getParentFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.nav_host_fragment, ViewerListFragment.newInstance(this.documentId, this.documentName, revisionId))
|
||||||
|
.commit();
|
||||||
|
});
|
||||||
|
|
||||||
// Set adapter
|
// Set adapter
|
||||||
recyclerView.setAdapter(revAdapter);
|
recyclerView.setAdapter(revAdapter);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package one.nem.lacerta.component.viewer.model;
|
||||||
|
|
||||||
|
public interface RevSelectListener {
|
||||||
|
void onRevSelect(String revisionId);
|
||||||
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/nav_host_fragment"
|
android:id="@+id/nav_host_fragment"
|
||||||
android:name="one.nem.lacerta.component.viewer.ComponentViewerTopFragment"
|
android:name="one.nem.lacerta.component.viewer.ViewerListFragment"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:defaultNavHost="true"
|
app:defaultNavHost="true"
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/component_viewer_navigation"
|
android:id="@+id/component_viewer_navigation"
|
||||||
app:startDestination="@id/componentViewerTopFragment">
|
app:startDestination="@id/viewerListFragment">
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/componentViewerTopFragment"
|
android:id="@+id/viewerListFragment"
|
||||||
android:name="one.nem.lacerta.component.viewer.ComponentViewerTopFragment"
|
android:name="one.nem.lacerta.component.viewer.ViewerListFragment"
|
||||||
android:label="ComponentViewerTopFragment" >
|
android:label="ComponentViewerTopFragment" >
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_componentViewerTopFragment_to_viewerVcsRevListFragment"
|
android:id="@+id/action_componentViewerTopFragment_to_viewerVcsRevListFragment"
|
||||||
|
|
|
@ -6,6 +6,7 @@ import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import one.nem.lacerta.model.document.DocumentMeta;
|
import one.nem.lacerta.model.document.DocumentMeta;
|
||||||
import one.nem.lacerta.model.document.DocumentDetail;
|
import one.nem.lacerta.model.document.DocumentDetail;
|
||||||
|
import one.nem.lacerta.model.document.page.Page;
|
||||||
import one.nem.lacerta.model.document.path.DocumentPath;
|
import one.nem.lacerta.model.document.path.DocumentPath;
|
||||||
import one.nem.lacerta.model.document.tag.DocumentTag;
|
import one.nem.lacerta.model.document.tag.DocumentTag;
|
||||||
|
|
||||||
|
@ -25,4 +26,6 @@ public interface Document {
|
||||||
CompletableFuture<Void> updateDocument(DocumentDetail detail);
|
CompletableFuture<Void> updateDocument(DocumentDetail detail);
|
||||||
|
|
||||||
CompletableFuture<DocumentDetail> getDocument(String documentId);
|
CompletableFuture<DocumentDetail> getDocument(String documentId);
|
||||||
|
|
||||||
|
CompletableFuture<ArrayList<Page>> getDocumentPageListByFileNameList(String documentId, ArrayList<String> fileNameList);
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,6 +173,34 @@ public class DocumentImpl implements Document {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<ArrayList<Page>> getDocumentPageListByFileNameList(String documentId, ArrayList<String> fileNameList) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
ArrayList<Page> pages = new ArrayList<>();
|
||||||
|
FileManager fileManager;
|
||||||
|
try {
|
||||||
|
fileManager = fileManagerFactory.create(deviceInfoUtils.getExternalStorageDirectory()).resolve(documentId).resolve("raw");
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error(TAG, "FileManager resolve error");
|
||||||
|
logger.trace(TAG, e.getMessage());
|
||||||
|
logger.e_code("1210ae5b-dd2f-42ef-bc15-40b9a9bbdb16");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileNameList.forEach(fileName -> {
|
||||||
|
try {
|
||||||
|
pages.add(new Page(fileName, fileManager.loadBitmap(fileName)));
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error(TAG, "Bitmap decode error");
|
||||||
|
logger.trace(TAG, e.getMessage());
|
||||||
|
logger.e_code("6f9ba0dc-ac63-401c-8f50-a2bd9ff5cb91");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return pages;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private CompletableFuture<ArrayList<XmlMetaPageModel>> getPagesByXmlMeta(String documentId) {
|
private CompletableFuture<ArrayList<XmlMetaPageModel>> getPagesByXmlMeta(String documentId) {
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
FileManager fileManager = fileManagerFactory.create(deviceInfoUtils.getExternalStorageDirectory());
|
FileManager fileManager = fileManagerFactory.create(deviceInfoUtils.getExternalStorageDirectory());
|
||||||
|
|
64
model/src/main/java/one/nem/lacerta/model/VcsLogModel.java
Normal file
64
model/src/main/java/one/nem/lacerta/model/VcsLogModel.java
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package one.nem.lacerta.model;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class VcsLogModel {
|
||||||
|
|
||||||
|
String id;
|
||||||
|
String documentId;
|
||||||
|
String branchName;
|
||||||
|
String action;
|
||||||
|
Date createdAt;
|
||||||
|
|
||||||
|
public VcsLogModel(String id, String documentId, String branchName, String action, Date createdAt) {
|
||||||
|
this.id = id;
|
||||||
|
this.documentId = documentId;
|
||||||
|
this.branchName = branchName;
|
||||||
|
this.action = action;
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty constructor
|
||||||
|
public VcsLogModel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDocumentId() {
|
||||||
|
return documentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBranchName() {
|
||||||
|
return branchName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDocumentId(String documentId) {
|
||||||
|
this.documentId = documentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBranchName(String branchName) {
|
||||||
|
this.branchName = branchName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAction(String action) {
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedAt(Date createdAt) {
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,18 +74,24 @@ public class DocumentProcessorImpl implements DocumentProcessor{
|
||||||
logger.debug("addNewPageToLast", "called");
|
logger.debug("addNewPageToLast", "called");
|
||||||
String filename = UUID.randomUUID().toString() + ".png"; // TODO-rca: 拡張子を動的にする
|
String filename = UUID.randomUUID().toString() + ".png"; // TODO-rca: 拡張子を動的にする
|
||||||
|
|
||||||
|
lacertaVcs.insertPage(this.documentDetail.getPages().size(), filename);
|
||||||
|
|
||||||
|
try {
|
||||||
Page page = new Page();
|
Page page = new Page();
|
||||||
page.setFileName(filename);
|
page.setFileName(filename);
|
||||||
page.setBitmap(bitmap);
|
page.setBitmap(bitmap);
|
||||||
this.documentDetail.getPages().add(page);
|
this.documentDetail.getPages().add(page);
|
||||||
|
|
||||||
lacertaVcs.insertPage(documentDetail.getPages().size(), filename);
|
|
||||||
|
|
||||||
this.fileManager.getNewInstance().createDirectoryIfNotExist(DEFAULT_SAVE_DIR).resolve(DEFAULT_SAVE_DIR).saveBitmap(bitmap, filename);
|
this.fileManager.getNewInstance().createDirectoryIfNotExist(DEFAULT_SAVE_DIR).resolve(DEFAULT_SAVE_DIR).saveBitmap(bitmap, filename);
|
||||||
|
|
||||||
logger.info("addNewPageToLast", "finished");
|
logger.info("addNewPageToLast", "finished");
|
||||||
logger.info("addNewPageToLast", "filename: " + filename);
|
logger.info("addNewPageToLast", "filename: " + filename);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("addNewPageToLast", "failed: Unknown error");
|
||||||
|
logger.e_code("d9191286-6092-40b3-80ed-9239106a8c65");
|
||||||
|
// Recover (Undo latest action)
|
||||||
|
lacertaVcs.undo();
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import one.nem.lacerta.source.database.dao.LibraryDao;
|
||||||
import one.nem.lacerta.source.database.dao.VcsRevDao;
|
import one.nem.lacerta.source.database.dao.VcsRevDao;
|
||||||
import one.nem.lacerta.source.database.dao.VcsLogDao;
|
import one.nem.lacerta.source.database.dao.VcsLogDao;
|
||||||
|
|
||||||
@Database(entities = {TagEntity.class, DocumentEntity.class, LibraryEntity.class, VcsRevEntity.class, VcsLogEntity.class, FolderEntity.class}, version = 5)
|
@Database(entities = {TagEntity.class, DocumentEntity.class, LibraryEntity.class, VcsRevEntity.class, VcsLogEntity.class, FolderEntity.class}, version = 4)
|
||||||
public abstract class LacertaDatabase extends RoomDatabase {
|
public abstract class LacertaDatabase extends RoomDatabase {
|
||||||
public abstract TagDao tagDao();
|
public abstract TagDao tagDao();
|
||||||
public abstract DocumentDao documentDao();
|
public abstract DocumentDao documentDao();
|
||||||
|
|
|
@ -52,4 +52,11 @@ public interface VcsLogDao {
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
void updateAll(List<VcsLogEntity> vcsLogs);
|
void updateAll(List<VcsLogEntity> vcsLogs);
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
@Query("DELETE FROM vcs_log WHERE id = :id")
|
||||||
|
void deleteById(String id);
|
||||||
|
|
||||||
|
@Query("DELETE FROM vcs_log WHERE id = (SELECT id FROM vcs_log WHERE document_id = :documentId ORDER BY created_at DESC LIMIT 1)")
|
||||||
|
void deleteLatestByDocumentId(String documentId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public interface VcsRevDao {
|
||||||
@Query("SELECT * FROM vcs_rev WHERE id IN (:ids)")
|
@Query("SELECT * FROM vcs_rev WHERE id IN (:ids)")
|
||||||
List<VcsRevEntity> findByIds(List<String> ids);
|
List<VcsRevEntity> findByIds(List<String> ids);
|
||||||
|
|
||||||
@Query("SELECT * FROM vcs_rev WHERE document_id = :documentId")
|
@Query("SELECT * FROM vcs_rev WHERE document_id = :documentId ORDER BY created_at ASC")
|
||||||
List<VcsRevEntity> findByDocumentId(String documentId);
|
List<VcsRevEntity> findByDocumentId(String documentId);
|
||||||
|
|
||||||
@Query("SELECT * FROM vcs_rev WHERE document_id = :documentId ORDER BY created_at DESC LIMIT 1")
|
@Query("SELECT * FROM vcs_rev WHERE document_id = :documentId ORDER BY created_at DESC LIMIT 1")
|
||||||
|
|
|
@ -40,6 +40,12 @@ public class VcsLogEntity {
|
||||||
@ColumnInfo(name = "created_at")
|
@ColumnInfo(name = "created_at")
|
||||||
public Date createdAt;
|
public Date createdAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* アクションタイプ
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name = "action_type")
|
||||||
|
public String actionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 発生アクション
|
* 発生アクション
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,7 +3,9 @@ package one.nem.lacerta.vcs;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import one.nem.lacerta.model.VcsLogModel;
|
||||||
import one.nem.lacerta.model.VcsRevModel;
|
import one.nem.lacerta.model.VcsRevModel;
|
||||||
|
import one.nem.lacerta.model.document.DocumentDetail;
|
||||||
|
|
||||||
public interface LacertaVcs {
|
public interface LacertaVcs {
|
||||||
|
|
||||||
|
@ -14,12 +16,20 @@ public interface LacertaVcs {
|
||||||
|
|
||||||
public void deletePage(int index);
|
public void deletePage(int index);
|
||||||
|
|
||||||
|
public void undo();
|
||||||
|
|
||||||
public void createDocument(String documentId);
|
public void createDocument(String documentId);
|
||||||
|
|
||||||
public void generateRevisionAtCurrent(String message);
|
public void generateRevisionAtCurrent(String message);
|
||||||
|
|
||||||
public CompletableFuture<ArrayList<VcsRevModel>> getRevisionHistory();
|
public CompletableFuture<ArrayList<VcsRevModel>> getRevisionHistory();
|
||||||
|
|
||||||
|
public CompletableFuture<ArrayList<VcsLogModel>> getLogHistory();
|
||||||
|
|
||||||
|
public CompletableFuture<ArrayList<VcsLogModel>> getLogHistoryInRev(String revId);
|
||||||
|
|
||||||
|
public CompletableFuture<ArrayList<String>> getDocumentPagePathListRev(String revId);
|
||||||
|
|
||||||
|
|
||||||
// debug
|
// debug
|
||||||
public void printLog();
|
public void printLog();
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
package one.nem.lacerta.vcs.impl;
|
package one.nem.lacerta.vcs.impl;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.assisted.Assisted;
|
import dagger.assisted.Assisted;
|
||||||
import dagger.assisted.AssistedInject;
|
import dagger.assisted.AssistedInject;
|
||||||
|
import one.nem.lacerta.model.VcsLogModel;
|
||||||
import one.nem.lacerta.model.VcsRevModel;
|
import one.nem.lacerta.model.VcsRevModel;
|
||||||
import one.nem.lacerta.source.database.LacertaDatabase;
|
import one.nem.lacerta.source.database.LacertaDatabase;
|
||||||
import one.nem.lacerta.source.database.entity.VcsLogEntity;
|
import one.nem.lacerta.source.database.entity.VcsLogEntity;
|
||||||
|
@ -18,7 +16,9 @@ import one.nem.lacerta.utils.LacertaLogger;
|
||||||
import one.nem.lacerta.vcs.ActionType;
|
import one.nem.lacerta.vcs.ActionType;
|
||||||
import one.nem.lacerta.vcs.LacertaVcs;
|
import one.nem.lacerta.vcs.LacertaVcs;
|
||||||
import one.nem.lacerta.vcs.internal.JsonUtils;
|
import one.nem.lacerta.vcs.internal.JsonUtils;
|
||||||
|
import one.nem.lacerta.vcs.model.action.DeletePage;
|
||||||
import one.nem.lacerta.vcs.model.action.InsertPage;
|
import one.nem.lacerta.vcs.model.action.InsertPage;
|
||||||
|
import one.nem.lacerta.vcs.model.action.UpdatePage;
|
||||||
|
|
||||||
public class LacertaVcsImpl implements LacertaVcs {
|
public class LacertaVcsImpl implements LacertaVcs {
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ public class LacertaVcsImpl implements LacertaVcs {
|
||||||
vcsLogEntity.documentId = documentId;
|
vcsLogEntity.documentId = documentId;
|
||||||
vcsLogEntity.branchName = "master";
|
vcsLogEntity.branchName = "master";
|
||||||
vcsLogEntity.createdAt = new java.util.Date();
|
vcsLogEntity.createdAt = new java.util.Date();
|
||||||
|
vcsLogEntity.actionType = ActionType.INSERT_PAGE.getValue();
|
||||||
vcsLogEntity.action = JsonUtils.toJson(insertPage);
|
vcsLogEntity.action = JsonUtils.toJson(insertPage);
|
||||||
database.vcsLogDao().insert(vcsLogEntity);
|
database.vcsLogDao().insert(vcsLogEntity);
|
||||||
}
|
}
|
||||||
|
@ -66,6 +67,11 @@ public class LacertaVcsImpl implements LacertaVcs {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void undo() {
|
||||||
|
database.vcsLogDao().deleteLatestByDocumentId(documentId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createDocument(String documentId) {
|
public void createDocument(String documentId) {
|
||||||
logger.debug(TAG, "createDocument");
|
logger.debug(TAG, "createDocument");
|
||||||
|
@ -75,7 +81,8 @@ public class LacertaVcsImpl implements LacertaVcs {
|
||||||
vcsLogEntity.documentId = documentId;
|
vcsLogEntity.documentId = documentId;
|
||||||
vcsLogEntity.branchName = "master";
|
vcsLogEntity.branchName = "master";
|
||||||
vcsLogEntity.createdAt = new java.util.Date();
|
vcsLogEntity.createdAt = new java.util.Date();
|
||||||
vcsLogEntity.action = "ph-createDocument";
|
vcsLogEntity.actionType = ActionType.CREATE_DOCUMENT.getValue();
|
||||||
|
vcsLogEntity.action = "";
|
||||||
database.vcsLogDao().insert(vcsLogEntity);
|
database.vcsLogDao().insert(vcsLogEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +154,108 @@ public class LacertaVcsImpl implements LacertaVcs {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<ArrayList<VcsLogModel>> getLogHistory() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<ArrayList<VcsLogModel>> getLogHistoryInRev(String revId) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
logger.debug(TAG, "getLogHistoryInRev");
|
||||||
|
ArrayList<VcsLogModel> vcsLogModels = new ArrayList<>();
|
||||||
|
|
||||||
|
VcsRevEntity vcsRevEntity = database.vcsRevDao().findById(revId);
|
||||||
|
ArrayList<VcsLogEntity> vcsLogEntities = getLogInRevAsync(vcsRevEntity).join(); // TODO-rca: リファクタリング
|
||||||
|
vcsLogEntities.forEach(vcsLogEntity -> {
|
||||||
|
VcsLogModel vcsLogModel = new VcsLogModel();
|
||||||
|
vcsLogModel.setId(vcsLogEntity.id);
|
||||||
|
vcsLogModel.setDocumentId(vcsLogEntity.documentId);
|
||||||
|
vcsLogModel.setBranchName(vcsLogEntity.branchName);
|
||||||
|
vcsLogModel.setCreatedAt(vcsLogEntity.createdAt);
|
||||||
|
vcsLogModel.setAction(vcsLogEntity.action);
|
||||||
|
vcsLogModels.add(vcsLogModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
return vcsLogModels;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<ArrayList<VcsRevEntity>> getRevBeforeTargetIdAsync(String revId){
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
ArrayList<VcsRevEntity> vcsRevEntities = new ArrayList<>(database.vcsRevDao().findByDocumentId(this.documentId));
|
||||||
|
ArrayList<VcsRevEntity> vcsRevEntitiesBeforeTarget = new ArrayList<>();
|
||||||
|
vcsRevEntities.forEach(vcsRevEntity -> {
|
||||||
|
if(vcsRevEntity.id.equals(revId)){
|
||||||
|
vcsRevEntitiesBeforeTarget.add(vcsRevEntity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vcsRevEntitiesBeforeTarget.add(vcsRevEntity);
|
||||||
|
});
|
||||||
|
logger.debug(TAG, "getRevBeforeTargetIdAsync finished\nResult size: " + vcsRevEntitiesBeforeTarget.size());
|
||||||
|
return vcsRevEntitiesBeforeTarget;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<ArrayList<VcsLogEntity>> getLogInRevsAsync(ArrayList<VcsRevEntity> vcsRevEntities){
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
List<String> logIds = new ArrayList<>();
|
||||||
|
vcsRevEntities.forEach(vcsRevEntity -> {
|
||||||
|
logIds.addAll(vcsRevEntity.logIds);
|
||||||
|
});
|
||||||
|
// TODO-rca: ソートしないといけないかも(順番が保証されているわけではない + 順番が変わるとほぼ確実に壊れる)
|
||||||
|
ArrayList<VcsLogEntity> vcsLogEntities = new ArrayList<>(database.vcsLogDao().findByIds(logIds));
|
||||||
|
logger.debug(TAG, "getLogInRevsAsync finished\nResult size: " + vcsLogEntities.size());
|
||||||
|
return vcsLogEntities;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<ArrayList<VcsLogEntity>> getLogInRevAsync(VcsRevEntity revEntity) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
ArrayList<VcsLogEntity> vcsLogEntities = new ArrayList<>(database.vcsLogDao().findByIds(revEntity.logIds));
|
||||||
|
logger.debug(TAG, "getLogInRevAsync finished\nResult size: " + vcsLogEntities.size());
|
||||||
|
return vcsLogEntities;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<ArrayList<String>> getDocumentPagePathListRev(String revId) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
logger.debug(TAG, "getDocumentPagePathListRev");
|
||||||
|
ArrayList<VcsLogEntity> vcsLogEntities = getRevBeforeTargetIdAsync(revId).thenCompose(this::getLogInRevsAsync).join();
|
||||||
|
|
||||||
|
ArrayList<String> fileNameList = new ArrayList<>();
|
||||||
|
for(VcsLogEntity vcsLogEntity : vcsLogEntities){
|
||||||
|
logger.debug(TAG, "getDocumentPagePathListRev: processing " + vcsLogEntity.id + "(Type: " + vcsLogEntity.actionType + ")");
|
||||||
|
if (vcsLogEntity.actionType.equals(ActionType.INSERT_PAGE.getValue())){
|
||||||
|
InsertPage insertPage = (InsertPage) JsonUtils.fromJson(vcsLogEntity.action, ActionType.INSERT_PAGE);
|
||||||
|
logger.debug(TAG, "getDocumentPagePathListRev: Inserting " + insertPage.getFileName() + " at " + insertPage.getIndex());
|
||||||
|
if (fileNameList.size() <= insertPage.getIndex()) {
|
||||||
|
logger.debug(TAG, "Index out of range, appending");
|
||||||
|
fileNameList.add(insertPage.getFileName());
|
||||||
|
} else {
|
||||||
|
fileNameList.add(insertPage.getIndex(), insertPage.getFileName());
|
||||||
|
}
|
||||||
|
} else if (vcsLogEntity.actionType.equals(ActionType.UPDATE_PAGE.getValue())){
|
||||||
|
UpdatePage updatePage = (UpdatePage) JsonUtils.fromJson(vcsLogEntity.action, ActionType.UPDATE_PAGE);
|
||||||
|
logger.debug(TAG, "getDocumentPagePathListRev: Updating " + updatePage.getFileName() + " at " + updatePage.getIndex());
|
||||||
|
fileNameList.set(updatePage.getIndex(), updatePage.getFileName());
|
||||||
|
} else if (vcsLogEntity.actionType.equals(ActionType.DELETE_PAGE.getValue())){
|
||||||
|
DeletePage deletePage = (DeletePage) JsonUtils.fromJson(vcsLogEntity.action, ActionType.DELETE_PAGE);
|
||||||
|
logger.debug(TAG, "getDocumentPagePathListRev: Deleting " + deletePage.getIndex());
|
||||||
|
fileNameList.remove(deletePage.getIndex());
|
||||||
|
} else if (vcsLogEntity.actionType.equals(ActionType.CREATE_DOCUMENT.getValue())) {
|
||||||
|
// Ignore
|
||||||
|
logger.debug(TAG, "getDocumentPagePathListRev: Ignored action type: " + vcsLogEntity.actionType);
|
||||||
|
} else {
|
||||||
|
logger.error(TAG, "getDocumentPagePathListRev: Unknown action type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileNameList;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printLog() {
|
public void printLog() {
|
||||||
logger.debug(TAG, "printLog");
|
logger.debug(TAG, "printLog");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user