diff --git a/README.md b/README.md
index 146a9ac..cea0793 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,6 @@
[![GitHub last commit](https://img.shields.io/github/last-commit/Iyxan23/sk-collab.svg?style=flat)]()
[![GitHub commit activity](https://img.shields.io/github/commit-activity/w/Iyxan23/sk-collab?style=flat)]()
[![GitHub pull-requests](https://img.shields.io/github/issues-pr/Iyxan23/sk-collab.svg)](https://GitHub.com/Iyxan23/sk-collab/pull/)
-[![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/Iyxan23/sk-collab.svg)](https://GitHub.com/Iyxan23/sk-collab/pull/)
[![PR's Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com)
[![Open Source? Yes!](https://badgen.net/badge/Open%20Source%20%3F/Yes%21/blue?icon=github)](https://github.com/Iyxan23/sk-collab)
[![GitHub forks](https://img.shields.io/github/forks/Iyxan23/sk-collab.svg?style=social&label=Fork&maxAge=2592000)](https://GitHub.com/Iyxan23/sk-collab/network/)
@@ -37,10 +36,14 @@ SketchCollab break these limits, SketchCollab allows you to edit the project at
## Note
I didn't invent version control. SketchCollab is only a version control system for Sketchware projects.
+## Building
+Steps in building SketchCollab on your own is written in this [wiki](https://github.com/Iyxan23/sk-collab/wiki/Building-Sketch-Collab).
+
## Branches
- [release](https://github.com/Iyxan23/sk-collab/tree/release): The branch where every release / beta / alpha version will be pushed into
- [main](https://github.com/Iyxan23/sk-collab/tree/main): Development branch, checked, and tested
- [dev](https://github.com/Iyxan23/sk-collab/tree/dev): Development branch, unstable, unchecked, and untested, bugs are expected in this branch
- [new-old-kotlin](https://github.com/Iyxan23/sk-collab/tree/new-old-kotlin): The old Kotlin codebase and unfinished version of SketchCollab
- [old-java](https://github.com/Iyxan23/sk-collab/tree/old-java): The old Java and unfinished version of SketchCollab
+ - [feature/ branches] - Usually used to add big / important features for the app, will soon be merged with dev when it's complete.
- [other branches] - Usually used to add breaking features and soon will be merged into dev when it's complete.
diff --git a/app/build.gradle b/app/build.gradle
index 8bcb739..6e29ac1 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -37,7 +37,6 @@ dependencies {
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-auth'
implementation 'com.google.firebase:firebase-firestore'
- implementation 'com.google.firebase:firebase-database'
implementation 'org.jetbrains:annotations:16.0.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 75de35b..299c9bd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,7 +7,7 @@
-
+
+
diff --git a/app/src/main/java/com/iyxan23/sketch/collab/CheckActivity.java b/app/src/main/java/com/iyxan23/sketch/collab/CheckActivity.java
index c327044..c37c42c 100644
--- a/app/src/main/java/com/iyxan23/sketch/collab/CheckActivity.java
+++ b/app/src/main/java/com/iyxan23/sketch/collab/CheckActivity.java
@@ -72,8 +72,10 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Ight, get the exception and print the stacktrace
task.getException().printStackTrace();
- // And also tell it to the user
- Toast.makeText(CheckActivity.this, "An error occured: " + task.getException().getMessage(), Toast.LENGTH_LONG).show();
+ // And also tell the use that we've failed to connect to the server
+ loading_text.setText("Failed to reach the server, check if you have an interent connection.");
+ loading_text.setTextColor(0xFFE51515);
+ progressbar.setVisibility(View.INVISIBLE);
}
});
}
diff --git a/app/src/main/java/com/iyxan23/sketch/collab/Util.java b/app/src/main/java/com/iyxan23/sketch/collab/Util.java
index 0c330a0..9f2828e 100644
--- a/app/src/main/java/com/iyxan23/sketch/collab/Util.java
+++ b/app/src/main/java/com/iyxan23/sketch/collab/Util.java
@@ -127,23 +127,21 @@ public static String sha512(byte[] input) {
// This function should be ran on a different thread
public static ArrayList fetch_sketchware_projects() {
ArrayList projects = new ArrayList<>();
- ArrayList files = listDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/data/");
-
- for (String project_folder_path: files) {
- File project_folder = new File(project_folder_path);
+ ArrayList files = listDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/data/");
+ for (File project_folder_path: files) {
// Just in case
- if (project_folder.isFile())
+ if (project_folder_path.isFile())
continue;
try {
- FileInputStream file = new FileInputStream(new File(project_folder.getAbsolutePath() + "/file"));
- FileInputStream logic = new FileInputStream(new File(project_folder.getAbsolutePath() + "/logic"));
- FileInputStream library = new FileInputStream(new File(project_folder.getAbsolutePath() + "/library"));
- FileInputStream view = new FileInputStream(new File(project_folder.getAbsolutePath() + "/view"));
- FileInputStream resource = new FileInputStream(new File(project_folder.getAbsolutePath() + "/resource"));
+ FileInputStream file = new FileInputStream(new File(project_folder_path.getAbsolutePath() + "/file"));
+ FileInputStream logic = new FileInputStream(new File(project_folder_path.getAbsolutePath() + "/logic"));
+ FileInputStream library = new FileInputStream(new File(project_folder_path.getAbsolutePath() + "/library"));
+ FileInputStream view = new FileInputStream(new File(project_folder_path.getAbsolutePath() + "/view"));
+ FileInputStream resource = new FileInputStream(new File(project_folder_path.getAbsolutePath() + "/resource"));
- FileInputStream mysc_project = new FileInputStream(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/mysc/list/" + project_folder.getName() + "/project"));
+ FileInputStream mysc_project = new FileInputStream(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/mysc/list/" + project_folder_path.getName() + "/project"));
projects.add(new SketchwareProject(readFile(logic), readFile(view), readFile(resource), readFile(library), readFile(file), readFile(mysc_project)));
@@ -176,19 +174,11 @@ public static SketchwareProject get_sketchware_project(int id) {
return null;
}
- public static int getFreeId() {
- ArrayList files = listDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/data/");
+ public static int getLatestId() {
+ ArrayList files = listDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/data/");
- int anchor = 601;
- for (String file : files) {
- if (!file.equals(String.valueOf(anchor))) {
- // Heres the free id
- return anchor;
- }
- anchor++;
- }
// Get the last empty ID
- return Integer.parseInt(files.get(files.size() - 1)) + 1;
+ return Integer.parseInt(files.get(files.size() - 1).getName()) + 1;
}
// Copied from: https://www.journaldev.com/9400/android-external-storage-read-write-save-file
@@ -266,6 +256,10 @@ public void run() {
}
public static void writeFile(File file, byte[] data) throws IOException {
+ if (!file.exists()) {
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ }
FileOutputStream outputStream = new FileOutputStream(file);
outputStream.write(data);
outputStream.flush();
@@ -316,15 +310,15 @@ public static byte[] joinByteArrays(final byte[] array1, @Nullable byte[] array2
return joinedArray;
}
- public static ArrayList listDir(String str) {
- ArrayList arrayList = new ArrayList<>();
+ public static ArrayList listDir(String str) {
+ ArrayList arrayList = new ArrayList<>();
File file = new File(str);
if (file.exists() && !file.isFile()) {
File[] listFiles = file.listFiles();
if (listFiles != null && listFiles.length > 0) {
arrayList.clear();
- for (File absolutePath : listFiles) {
- arrayList.add(absolutePath.getAbsolutePath());
+ for (File f : listFiles) {
+ arrayList.add(f);
}
}
}
diff --git a/app/src/main/java/com/iyxan23/sketch/collab/adapters/SketchwareProjectAdapter.java b/app/src/main/java/com/iyxan23/sketch/collab/adapters/SketchwareProjectAdapter.java
index 7b0433b..14a9598 100644
--- a/app/src/main/java/com/iyxan23/sketch/collab/adapters/SketchwareProjectAdapter.java
+++ b/app/src/main/java/com/iyxan23/sketch/collab/adapters/SketchwareProjectAdapter.java
@@ -55,6 +55,11 @@ public void onBindViewHolder(@NonNull final ViewHolder holder, final int positio
Log.d(TAG, "onBindViewHolder: called.");
SketchwareProject project = datas.get(position);
+ // Fixes #18
+ // Check if the project metadata is null, if it is, the project is corrupted and we will
+ // just continue on with our day - RecyclerView
+ if (project.metadata == null) return;
+
holder.title.setText(project.metadata.app_name);
holder.subtitle.setText(project.metadata.project_name);
holder.details.setText(project.metadata.project_package + "(" + project.metadata.id + ")");
diff --git a/app/src/main/java/com/iyxan23/sketch/collab/models/SketchwareProject.java b/app/src/main/java/com/iyxan23/sketch/collab/models/SketchwareProject.java
index 8748598..dc6e32e 100644
--- a/app/src/main/java/com/iyxan23/sketch/collab/models/SketchwareProject.java
+++ b/app/src/main/java/com/iyxan23/sketch/collab/models/SketchwareProject.java
@@ -48,38 +48,23 @@ public SketchwareProject(byte[] logic, byte[] view, byte[] resource, byte[] libr
}
public void applyChanges() throws IOException {
- String project_folder = Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/data/" + project_id;
- FileOutputStream file = new FileOutputStream(new File(project_folder + "/file"));
- FileOutputStream logic = new FileOutputStream(new File(project_folder + "/logic"));
- FileOutputStream library = new FileOutputStream(new File(project_folder + "/library"));
- FileOutputStream view = new FileOutputStream(new File(project_folder + "/view"));
- FileOutputStream resource = new FileOutputStream(new File(project_folder + "/resource"));
-
- FileOutputStream mysc_project = new FileOutputStream(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/mysc/list/" + project_id + "/project"));
-
- file.write(this.file);
- file.flush();
- file.close();
-
- logic.write(this.logic);
- file.flush();
- logic.close();
-
- library.write(this.library);
- library.flush();
- library.close();
-
- view.write(this.view);
- view.flush();
- view.close();
-
- resource.write(this.resource);
- resource.flush();
- resource.close();
-
- mysc_project.write(this.mysc_project);
- mysc_project.flush();
- mysc_project.close();
+ String project_folder = Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/data/" + project_id + "/";
+
+ File file = new File(project_folder + "file");
+ File logic = new File(project_folder + "logic");
+ File library = new File(project_folder + "library");
+ File view = new File(project_folder + "view");
+ File resource = new File(project_folder + "resource");
+
+ File mysc_project = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/mysc/list/" + project_id + "/project");
+
+ Util.writeFile(file , this.file );
+ Util.writeFile(logic , this.logic );
+ Util.writeFile(library , this.library );
+ Util.writeFile(view , this.view );
+ Util.writeFile(resource , this.resource );
+
+ Util.writeFile(mysc_project, this.mysc_project);
}
@Nullable
diff --git a/app/src/main/java/com/iyxan23/sketch/collab/online/BrowseCodeActivity.java b/app/src/main/java/com/iyxan23/sketch/collab/online/BrowseCodeActivity.java
new file mode 100644
index 0000000..872dbd6
--- /dev/null
+++ b/app/src/main/java/com/iyxan23/sketch/collab/online/BrowseCodeActivity.java
@@ -0,0 +1,158 @@
+package com.iyxan23.sketch.collab.online;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.google.android.gms.tasks.Tasks;
+import com.google.firebase.firestore.CollectionReference;
+import com.google.firebase.firestore.DocumentReference;
+import com.google.firebase.firestore.DocumentSnapshot;
+import com.google.firebase.firestore.FirebaseFirestore;
+import com.google.firebase.firestore.Query;
+import com.google.firebase.firestore.QuerySnapshot;
+import com.google.firebase.firestore.Source;
+import com.iyxan23.sketch.collab.R;
+import com.iyxan23.sketch.collab.Util;
+import com.iyxan23.sketch.collab.models.SketchwareProject;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.concurrent.ExecutionException;
+
+import name.fraser.neil.plaintext.diff_match_patch;
+
+public class BrowseCodeActivity extends AppCompatActivity {
+
+ TextView code_logic;
+ TextView code_view;
+ TextView code_file;
+ TextView code_library;
+ TextView code_resource;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_browse_code);
+
+ // Bind these textviews
+ code_logic = findViewById(R.id.code_logic );
+ code_view = findViewById(R.id.code_view );
+ code_file = findViewById(R.id.code_file );
+ code_library = findViewById(R.id.code_library );
+ code_resource = findViewById(R.id.code_resource );
+
+ // Get the project key and project name
+ Intent intent = getIntent();
+ String project_key = intent.getStringExtra("project_key" );
+ String project_name = intent.getStringExtra("project_name" );
+
+ ((TextView) findViewById(R.id.project_name)).setText("on " + project_name);
+
+ // Fetch the snapshot of the project
+ new Thread(() -> {
+ try {
+ FirebaseFirestore firestore = FirebaseFirestore.getInstance();
+ CollectionReference project_snapshot = firestore.collection("projects").document(project_key).collection("snapshot");
+ CollectionReference project_commits = firestore.collection("projects").document(project_key).collection("commits");
+
+ // Project data in their decrypted string format
+ HashMap project_data = new HashMap<>();
+
+ String[] keys = new String[] {"mysc_project", "logic", "view", "library", "resource", "file"};
+
+ // Get the snapshot, get the commits, and apply the commits to the snapshot
+ QuerySnapshot snapshot = Tasks.await(project_snapshot.get());
+ QuerySnapshot commits = Tasks.await(project_commits .orderBy("timestamp", Query.Direction.ASCENDING).get());
+
+ for (DocumentSnapshot doc: snapshot.getDocuments()) {
+ project_data.put(doc.getId(), Util.decrypt(doc.getBlob("data").toBytes()));
+ }
+
+ diff_match_patch dmp = new diff_match_patch();
+ // Apply the patch
+ for (DocumentSnapshot commit: commits) {
+ HashMap patch = (HashMap) commit.get("patch");
+
+ if (patch == null) continue;
+
+ for (String key: keys) {
+ if (!patch.containsKey(key)) continue;
+
+ LinkedList patches = (LinkedList) dmp.patch_fromText(patch.get(key));
+ // TODO: CHECK PATCH STATUSES
+ Object[] result = dmp.patch_apply(patches, project_data.get(key));
+
+ project_data.put(key, (String) result[0]);
+ }
+ }
+
+ runOnUiThread(() -> {
+ code_logic.setText(project_data.get("logic"));
+ code_view.setText(project_data.get("view"));
+ code_file.setText(project_data.get("file"));
+ code_library.setText(project_data.get("library"));
+ code_resource.setText(project_data.get("resource"));
+ });
+
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+
+ Toast.makeText(this, "An error occured: " + e.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ }).start();
+ }
+
+ @SuppressLint("WrongConstant")
+ public void chevron_logic(View view) {
+ // Kinda hacky, but this code is to toggle the view's visibility between VISIBLE (0x0) and GONE (0x8)
+ // I don't really like the branching way of doing it, so I'm doing it mathematically
+ code_logic.setVisibility(code_logic.getVisibility() ^ View.GONE);
+
+ // Rotate the chevron 180 degree(s)
+ view.setRotation((view.getRotation() + 180) % 360);
+ }
+
+ @SuppressLint("WrongConstant")
+ public void chevron_view(View view) {
+ code_view.setVisibility(code_view.getVisibility() ^ View.GONE);
+
+ // Rotate the chevron 180 degree(s)
+ view.setRotation((view.getRotation() + 180) % 360);
+ }
+
+ @SuppressLint("WrongConstant")
+ public void chevron_file(View view) {
+ code_file.setVisibility(code_file.getVisibility() ^ View.GONE);
+
+ // Rotate the chevron 180 degree(s)
+ view.setRotation((view.getRotation() + 180) % 360);
+ }
+
+ @SuppressLint("WrongConstant")
+ public void chevron_library(View view) {
+ code_library.setVisibility(code_library.getVisibility() ^ View.GONE);
+
+ // Rotate the chevron 180 degree(s)
+ view.setRotation((view.getRotation() + 180) % 360);
+ }
+
+ @SuppressLint("WrongConstant")
+ public void chevron_resource(View view) {
+ code_resource.setVisibility(code_resource.getVisibility() ^ View.GONE);
+
+ // Rotate the chevron 180 degree(s)
+ view.setRotation((view.getRotation() + 180) % 360);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/iyxan23/sketch/collab/online/UploadActivity.java b/app/src/main/java/com/iyxan23/sketch/collab/online/UploadActivity.java
index 224a793..325fa89 100644
--- a/app/src/main/java/com/iyxan23/sketch/collab/online/UploadActivity.java
+++ b/app/src/main/java/com/iyxan23/sketch/collab/online/UploadActivity.java
@@ -13,11 +13,9 @@
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.firebase.Timestamp;
import com.google.firebase.auth.FirebaseAuth;
-import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.firestore.Blob;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentReference;
-import com.google.firebase.firestore.FieldValue;
import com.google.firebase.firestore.FirebaseFirestore;
import com.iyxan23.sketch.collab.R;
import com.iyxan23.sketch.collab.Util;
@@ -28,7 +26,6 @@
import java.io.IOException;
import java.util.HashMap;
-import java.util.Map;
public class UploadActivity extends AppCompatActivity {
@@ -67,7 +64,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
EditText description = findViewById(R.id.description_upload);
EditText name = findViewById(R.id.name_upload);
- FirebaseDatabase database = FirebaseDatabase.getInstance();
FirebaseFirestore firestore = FirebaseFirestore.getInstance();
FirebaseAuth auth = FirebaseAuth.getInstance();
diff --git a/app/src/main/java/com/iyxan23/sketch/collab/online/ViewOnlineProjectActivity.java b/app/src/main/java/com/iyxan23/sketch/collab/online/ViewOnlineProjectActivity.java
index fec77b6..7972991 100644
--- a/app/src/main/java/com/iyxan23/sketch/collab/online/ViewOnlineProjectActivity.java
+++ b/app/src/main/java/com/iyxan23/sketch/collab/online/ViewOnlineProjectActivity.java
@@ -169,7 +169,10 @@ protected void onCreate(Bundle savedInstanceState) {
// onClick for the "Browse Code" button
public void browseCodeOnClick(View v) {
-
+ Intent i = new Intent(this, BrowseCodeActivity.class);
+ i.putExtra("project_key", project_key);
+ i.putExtra("project_name", project_name);
+ startActivity(i);
}
// onClick for the "Commits" button
diff --git a/app/src/main/java/com/iyxan23/sketch/collab/services/CloneService.java b/app/src/main/java/com/iyxan23/sketch/collab/services/CloneService.java
index a6c4e42..4c58785 100644
--- a/app/src/main/java/com/iyxan23/sketch/collab/services/CloneService.java
+++ b/app/src/main/java/com/iyxan23/sketch/collab/services/CloneService.java
@@ -5,9 +5,12 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
+import android.content.Context;
import android.content.Intent;
import android.os.Build;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
@@ -125,7 +128,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {
LinkedList patches = (LinkedList) dmp.patch_fromText(patch.get(key));
// TODO: CHECK PATCH STATUSES
- Object[] result = dmp.patch_apply(patches, patch.get(key));
+ Object[] result = dmp.patch_apply(patches, project_data.get(key));
project_data.put(key, (String) result[0]);
}
@@ -155,12 +158,12 @@ public int onStartCommand(Intent intent, int flags, int startId) {
*/
}
- int free_id = Util.getFreeId();
+ int free_id = Util.getLatestId();
// Alter the mysc project
JSONObject project_json = new JSONObject(project_data.get("mysc_project"));
- project_json.put("sc_id", free_id);
+ project_json.put("sc_id", String.valueOf(free_id));
project_json.put("sk-collab-project-key", project_key);
project_json.put("sk-collab-owner", project_metadata.getString("author"));
@@ -180,11 +183,21 @@ public int onStartCommand(Intent intent, int flags, int startId) {
Util.encrypt(project_data.get("mysc_project").getBytes())
).applyChanges();
- } catch (InterruptedException | ExecutionException | JSONException | IOException e) {
+ } catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
+ } catch (ExecutionException | JSONException | IOException e) {
+ e.printStackTrace();
+
+ // So it will appear on the debug page
+ throw new RuntimeException(e);
}
+ // Show a "clone finished" toast
+ new Handler(Looper.getMainLooper()).post(() ->
+ Toast.makeText(this, "Clone " + project_name + " finished, check and refresh your sketchware.", Toast.LENGTH_LONG).show()
+ );
+
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf();
diff --git a/app/src/main/res/drawable/ic_check.xml b/app/src/main/res/drawable/ic_check.xml
new file mode 100644
index 0000000..2501e9f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_check.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_chevron_down.xml b/app/src/main/res/drawable/ic_chevron_down.xml
new file mode 100644
index 0000000..1aeaa99
--- /dev/null
+++ b/app/src/main/res/drawable/ic_chevron_down.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_code_braces.xml b/app/src/main/res/drawable/ic_code_braces.xml
new file mode 100644
index 0000000..6b5ba25
--- /dev/null
+++ b/app/src/main/res/drawable/ic_code_braces.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_browse_code.xml b/app/src/main/res/layout/activity_browse_code.xml
new file mode 100644
index 0000000..b1b8b8a
--- /dev/null
+++ b/app/src/main/res/layout/activity_browse_code.xml
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_check.xml b/app/src/main/res/layout/activity_check.xml
index 03cd171..1a115bf 100644
--- a/app/src/main/res/layout/activity_check.xml
+++ b/app/src/main/res/layout/activity_check.xml
@@ -36,11 +36,14 @@