Skip to content

Commit

Permalink
Add BrowseCodeActivity and Fixes on CloneService
Browse files Browse the repository at this point in the history
(#21)
  • Loading branch information
iyxan23 authored Feb 2, 2021
2 parents 4d7e081 + 6469e2a commit 64b59aa
Show file tree
Hide file tree
Showing 16 changed files with 594 additions and 73 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/)
Expand Down Expand Up @@ -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.
1 change: 0 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

<application
android:name=".DebugApplication"
Expand Down Expand Up @@ -57,6 +57,9 @@
<activity
android:name=".DebugActivity"
android:theme="@style/Theme.SketchCollab.NoActionBar" />
<activity
android:name=".online.BrowseCodeActivity"
android:theme="@style/Theme.SketchCollab.NoActionBar" />

<service
android:name=".services.CloneService" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
});
}
Expand Down
46 changes: 20 additions & 26 deletions app/src/main/java/com/iyxan23/sketch/collab/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,23 +127,21 @@ public static String sha512(byte[] input) {
// This function should be ran on a different thread
public static ArrayList<SketchwareProject> fetch_sketchware_projects() {
ArrayList<SketchwareProject> projects = new ArrayList<>();
ArrayList<String> files = listDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/data/");

for (String project_folder_path: files) {
File project_folder = new File(project_folder_path);
ArrayList<File> 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)));

Expand Down Expand Up @@ -176,19 +174,11 @@ public static SketchwareProject get_sketchware_project(int id) {
return null;
}

public static int getFreeId() {
ArrayList<String> files = listDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/.sketchware/data/");
public static int getLatestId() {
ArrayList<File> 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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -316,15 +310,15 @@ public static byte[] joinByteArrays(final byte[] array1, @Nullable byte[] array2
return joinedArray;
}

public static ArrayList<String> listDir(String str) {
ArrayList<String> arrayList = new ArrayList<>();
public static ArrayList<File> listDir(String str) {
ArrayList<File> 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);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 + ")");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String, String> 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<String, String> patch = (HashMap<String, String>) commit.get("patch");

if (patch == null) continue;

for (String key: keys) {
if (!patch.containsKey(key)) continue;

LinkedList<diff_match_patch.Patch> patches = (LinkedList<diff_match_patch.Patch>) 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);
}
}
Loading

0 comments on commit 64b59aa

Please sign in to comment.