Skip to content

Commit

Permalink
feat: Redesign Local Libraries UI
Browse files Browse the repository at this point in the history
  • Loading branch information
aikrq committed Dec 29, 2024
1 parent 371284d commit 9f5f49f
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public class LibraryDownloaderDialogFragment extends DialogFragment {
private String local_lib_file = "";
private LibraryDownloaderListener listener;


@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,35 @@

import pro.sketchware.databinding.ManageLocallibrariesBinding;
import pro.sketchware.databinding.ViewItemLocalLibBinding;
import pro.sketchware.databinding.ViewItemLocalLibSearchBinding;
import pro.sketchware.utility.FileUtil;
import pro.sketchware.utility.SketchwareUtil;

public class ManageLocalLibraryActivity extends AppCompatActivity implements View.OnClickListener {
private static String local_libs_path = "";
private boolean notAssociatedWithProject = false;
private String local_lib_file = "";
private ArrayList<HashMap<String, Object>> lookup_list = new ArrayList<>();
private ArrayList<HashMap<String, Object>> project_used_libs = new ArrayList<>();
public class ManageLocalLibraryActivity extends AppCompatActivity {

private static String localLibsPath;
private boolean notAssociatedWithProject;
private String localLibFile;
private ArrayList<HashMap<String, Object>> lookupList = new ArrayList<>();
private ArrayList<HashMap<String, Object>> projectUsedLibs = new ArrayList<>();
private BuildSettings buildSettings;
private final ArrayList<String> arrayList = new ArrayList<>();
private ManageLocallibrariesBinding binding;
private LibraryAdapter adapter;
private SearchAdapter searchAdapter;

static {
localLibsPath = FileUtil.getExternalStorageDir().concat("/.sketchware/libs/local_libs/");
}

public static HashMap<String, Object> createLibraryMap(String name, String dependency) {
String configPath = local_libs_path + name + "/config";
String resPath = local_libs_path + name + "/res";
String jarPath = local_libs_path + name + "/classes.jar";
String dexPath = local_libs_path + name + "/classes.dex";
String manifestPath = local_libs_path + name + "/AndroidManifest.xml";
String pgRulesPath = local_libs_path + name + "/proguard.txt";
String assetsPath = local_libs_path + name + "/assets";
String configPath = localLibsPath + name + "/config";
String resPath = localLibsPath + name + "/res";
String jarPath = localLibsPath + name + "/classes.jar";
String dexPath = localLibsPath + name + "/classes.dex";
String manifestPath = localLibsPath + name + "/AndroidManifest.xml";
String pgRulesPath = localLibsPath + name + "/proguard.txt";
String assetsPath = localLibsPath + name + "/assets";

HashMap<String, Object> localLibrary = new HashMap<>();
localLibrary.put("name", name);
Expand Down Expand Up @@ -93,73 +101,67 @@ protected void onCreate(Bundle savedInstanceState) {

ViewCompat.setOnApplyWindowInsetsListener(binding.downloadLibraryButton, new AddMarginOnApplyWindowInsetsListener(WindowInsetsCompat.Type.navigationBars(), WindowInsetsCompat.CONSUMED));

initButtons();
if (getIntent().hasExtra("sc_id")) {
String sc_id = Objects.requireNonNull(getIntent().getStringExtra("sc_id"));
buildSettings = new BuildSettings(sc_id);
notAssociatedWithProject = sc_id.equals("system");
local_lib_file = FileUtil.getExternalStorageDir().concat("/.sketchware/data/").concat(sc_id.concat("/local_library"));
String scId = Objects.requireNonNull(getIntent().getStringExtra("sc_id"));
buildSettings = new BuildSettings(scId);
notAssociatedWithProject = scId.equals("system");
localLibFile = FileUtil.getExternalStorageDir().concat("/.sketchware/data/").concat(scId.concat("/local_library"));
}
local_libs_path = FileUtil.getExternalStorageDir().concat("/.sketchware/libs/local_libs/");
loadFiles();
setUpSearchView();
}

private void initButtons() {
binding.topAppBar.setNavigationOnClickListener(Helper.getBackPressedClickListener(this));
binding.downloadLibraryButton.setOnClickListener(this);
}
loadLibraries();
setupSearchBar();

@Override
@SuppressLint("SetTextI18n")
public void onClick(View v) {

LibraryDownloaderDialogFragment dialogFragment = new LibraryDownloaderDialogFragment();
Bundle bundle = new Bundle();
bundle.putBoolean("notAssociatedWithProject", notAssociatedWithProject);
bundle.putSerializable("buildSettings", buildSettings);
bundle.putString("local_lib_file", local_lib_file);
dialogFragment.setArguments(bundle);
if (getSupportFragmentManager().findFragmentByTag("library_downloader_dialog") != null)
return;
dialogFragment.setListener(this::loadFiles);
dialogFragment.show(getSupportFragmentManager(), "library_downloader_dialog");
binding.downloadLibraryButton.setOnClickListener(v -> {
if (getSupportFragmentManager().findFragmentByTag("library_downloader_dialog") != null) {
return;
}

Bundle bundle = new Bundle();
bundle.putBoolean("notAssociatedWithProject", notAssociatedWithProject);
bundle.putSerializable("buildSettings", buildSettings);
bundle.putString("localLibFile", localLibFile);

LibraryDownloaderDialogFragment fragment = new LibraryDownloaderDialogFragment();
fragment.setArguments(bundle);
fragment.setListener(this::loadLibraries);
fragment.show(getSupportFragmentManager(), "library_downloader_dialog");
});
}

private void setUpSearchView() {
binding.searchInput.addTextChangedListener(new TextWatcher() {
private void setupSearchBar() {
binding.searchView.getEditText().addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}

@Override
public void afterTextChanged(Editable s) {
String value = s.toString().trim();
adapter.filter(value);
searchAdapter.filter(value);
}

@Override
public void onTextChanged(CharSequence newText, int start, int before, int count) {
if (newText.toString().isEmpty()) {
loadFiles();
loadLibraries();
}
}
});
}

private void loadFiles() {
project_used_libs.clear();
lookup_list.clear();
private void loadLibraries() {
projectUsedLibs.clear();
lookupList.clear();
if (!notAssociatedWithProject) {
String fileContent;
if (!FileUtil.isExistFile(local_lib_file) || (fileContent = FileUtil.readFile(local_lib_file)).isEmpty()) {
FileUtil.writeFile(local_lib_file, "[]");
if (!FileUtil.isExistFile(localLibFile) || (fileContent = FileUtil.readFile(localLibFile)).isEmpty()) {
FileUtil.writeFile(localLibFile, "[]");
} else {
project_used_libs = new Gson().fromJson(fileContent, Helper.TYPE_MAP_LIST);
projectUsedLibs = new Gson().fromJson(fileContent, Helper.TYPE_MAP_LIST);
}
}

FileUtil.listDir(local_libs_path, arrayList);
FileUtil.listDir(localLibsPath, arrayList);
arrayList.sort(String.CASE_INSENSITIVE_ORDER);

List<String> localLibraryNames = new LinkedList<>();
Expand All @@ -168,38 +170,127 @@ private void loadFiles() {
localLibraryNames.add(Uri.parse(filename).getLastPathSegment());
}
}
if (localLibraryNames.isEmpty()) {
binding.noContentLayout.setVisibility(View.VISIBLE);
} else {
binding.noContentLayout.setVisibility(View.GONE);
}
binding.librariesList.setLayoutManager(new LinearLayoutManager(this));

adapter = new LibraryAdapter(localLibraryNames);
searchAdapter = new SearchAdapter(localLibraryNames);
binding.noContentLayout.setVisibility(localLibraryNames.isEmpty() ? View.VISIBLE : View.GONE);
binding.librariesList.setAdapter(adapter);
binding.searchList.setAdapter(searchAdapter);
}

public class LibraryAdapter extends RecyclerView.Adapter<LibraryAdapter.ViewHolder> {
private final List<String> libraryNames;

public LibraryAdapter(List<String> libraryNames) {
this.libraryNames = libraryNames;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
var binding = ViewItemLocalLibBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new ViewHolder(binding);
}

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
var binding = holder.binding;

final String libraryName = libraryNames.get(position);
binding.checkboxContent.setText(libraryName);

binding.checkboxContent.setOnClickListener(v -> {
String name = binding.checkboxContent.getText().toString();

HashMap<String, Object> localLibrary;
if (!binding.checkboxContent.isChecked()) {
// Remove the library from the list
int indexToRemove = -1;
for (int i = 0; i < projectUsedLibs.size(); i++) {
HashMap<String, Object> lib = projectUsedLibs.get(i);
if (name.equals(lib.get("name"))) {
indexToRemove = i;
break;
}
}
if (indexToRemove != -1) {
projectUsedLibs.remove(indexToRemove);
}
} else {
// Add the library to the list
// Here, we need to find the dependency string if it exists
String dependency = null;
for (HashMap<String, Object> lib : lookupList) {
if (name.equals(lib.get("name"))) {
dependency = (String) lib.get("dependency");
break;
}
}
localLibrary = createLibraryMap(name, dependency);
projectUsedLibs.add(localLibrary);
}
FileUtil.writeFile(localLibFile, new Gson().toJson(projectUsedLibs));
});

binding.checkboxContent.setChecked(false);
if (!notAssociatedWithProject) {
lookupList = new Gson().fromJson(FileUtil.readFile(localLibFile), Helper.TYPE_MAP_LIST);
for (HashMap<String, Object> localLibrary : lookupList) {
if (binding.checkboxContent.getText().toString().equals(Objects.requireNonNull(localLibrary.get("name")).toString())) {
binding.checkboxContent.setChecked(true);
}
}
} else {
binding.checkboxContent.setEnabled(false);
}

binding.imgDelete.setOnClickListener(v -> {
PopupMenu popupMenu = new PopupMenu(ManageLocalLibraryActivity.this, v);
popupMenu.getMenu().add(Menu.NONE, Menu.NONE, Menu.NONE, "Delete");
popupMenu.setOnMenuItemClickListener(menuItem -> {
FileUtil.deleteFile(localLibsPath.concat(binding.checkboxContent.getText().toString()));
SketchwareUtil.toast("Deleted successfully");
loadLibraries();
return true;
});
popupMenu.show();
});
}

@Override
public int getItemCount() {
return libraryNames.size();
}

static class ViewHolder extends RecyclerView.ViewHolder {
private final ViewItemLocalLibBinding binding;

public ViewHolder(@NonNull ViewItemLocalLibBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}

public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder> {
private final List<String> originalList;
private final List<String> filteredList;

public LibraryAdapter(List<String> localLibraries) {
this.originalList = new ArrayList<>(localLibraries);
this.filteredList = new ArrayList<>(localLibraries);
public SearchAdapter(List<String> localLibraries) {
this.originalList = localLibraries;
this.filteredList = localLibraries;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
var listBinding = ViewItemLocalLibBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
var layoutParams = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
listBinding.getRoot().setLayoutParams(layoutParams);
return new ViewHolder(listBinding);
var binding = ViewItemLocalLibSearchBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new ViewHolder(binding);
}

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
var binding = holder.listBinding;
var binding = holder.binding;

final String libraryName = filteredList.get(position);
binding.checkboxContent.setText(libraryName);
Expand All @@ -211,37 +302,37 @@ public void onBindViewHolder(ViewHolder holder, final int position) {
if (!binding.checkboxContent.isChecked()) {
// Remove the library from the list
int indexToRemove = -1;
for (int i = 0; i < project_used_libs.size(); i++) {
HashMap<String, Object> lib = project_used_libs.get(i);
for (int i = 0; i < projectUsedLibs.size(); i++) {
HashMap<String, Object> lib = projectUsedLibs.get(i);
if (name.equals(lib.get("name"))) {
indexToRemove = i;
break;
}
}
if (indexToRemove != -1) {
project_used_libs.remove(indexToRemove);
projectUsedLibs.remove(indexToRemove);
}
} else {
// Add the library to the list
// Here, we need to find the dependency string if it exists
String dependency = null;
for (HashMap<String, Object> lib : lookup_list) {
for (HashMap<String, Object> lib : lookupList) {
if (name.equals(lib.get("name"))) {
dependency = (String) lib.get("dependency");
break;
}
}
localLibrary = createLibraryMap(name, dependency);
project_used_libs.add(localLibrary);
projectUsedLibs.add(localLibrary);
}
FileUtil.writeFile(local_lib_file, new Gson().toJson(project_used_libs));
FileUtil.writeFile(localLibFile, new Gson().toJson(projectUsedLibs));
});


binding.checkboxContent.setChecked(false);
if (!notAssociatedWithProject) {
lookup_list = new Gson().fromJson(FileUtil.readFile(local_lib_file), Helper.TYPE_MAP_LIST);
for (HashMap<String, Object> localLibrary : lookup_list) {
lookupList = new Gson().fromJson(FileUtil.readFile(localLibFile), Helper.TYPE_MAP_LIST);
for (HashMap<String, Object> localLibrary : lookupList) {
if (binding.checkboxContent.getText().toString().equals(Objects.requireNonNull(localLibrary.get("name")).toString())) {
binding.checkboxContent.setChecked(true);
}
Expand All @@ -254,9 +345,9 @@ public void onBindViewHolder(ViewHolder holder, final int position) {
PopupMenu popupMenu = new PopupMenu(ManageLocalLibraryActivity.this, v);
popupMenu.getMenu().add(Menu.NONE, Menu.NONE, Menu.NONE, "Delete");
popupMenu.setOnMenuItemClickListener(menuItem -> {
FileUtil.deleteFile(local_libs_path.concat(binding.checkboxContent.getText().toString()));
FileUtil.deleteFile(localLibsPath.concat(binding.checkboxContent.getText().toString()));
SketchwareUtil.toast("Deleted successfully");
loadFiles();
loadLibraries();
return true;
});
popupMenu.show();
Expand All @@ -283,11 +374,11 @@ public void filter(String query) {
}

static class ViewHolder extends RecyclerView.ViewHolder {
private final ViewItemLocalLibBinding listBinding;
private final ViewItemLocalLibSearchBinding binding;

public ViewHolder(@NonNull ViewItemLocalLibBinding listBinding) {
super(listBinding.getRoot());
this.listBinding = listBinding;
public ViewHolder(@NonNull ViewItemLocalLibSearchBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}
Expand Down
Loading

0 comments on commit 9f5f49f

Please sign in to comment.