Set base to show custom blocks on part-picker menu.

This commit is contained in:
Sergio Martínez Portela 2020-05-20 16:53:18 +02:00
parent 4d477cfa5d
commit de2d474294
15 changed files with 455 additions and 105 deletions

View File

@ -32,7 +32,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
class CanvasView extends View implements PartGrid { public class CanvasView extends View implements PartGrid {
@NonNull @NonNull
List<Part> parts = new ArrayList<>(); List<Part> parts = new ArrayList<>();

View File

@ -3,13 +3,16 @@ package com.codigoparallevar.minicards;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import com.codigoparallevar.minicards.toolbox.PartsHolder;
import com.codigoparallevar.minicards.types.functional.Consumer; import com.codigoparallevar.minicards.types.functional.Consumer;
import com.codigoparallevar.minicards.types.functional.Producer; import com.codigoparallevar.minicards.types.functional.Producer;
import com.codigoparallevar.minicards.types.functional.Tuple2; import com.codigoparallevar.minicards.types.functional.Tuple2;
import com.codigoparallevar.minicards.types.functional.Tuple3;
import com.codigoparallevar.minicards.ui_helpers.GetAsync; import com.codigoparallevar.minicards.ui_helpers.GetAsync;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.programaker.api.ProgramakerApi; import com.programaker.api.ProgramakerApi;
import com.programaker.api.data.ProgramakerCustomBlock; import com.programaker.api.data.ProgramakerBridgeInfo;
import com.programaker.api.data.api_results.ProgramakerBridgeCustomBlockResult;
import com.programaker.api.data.api_results.ProgramakerGetCustomBlocksResult; import com.programaker.api.data.api_results.ProgramakerGetCustomBlocksResult;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
@ -30,6 +33,7 @@ public class CardActivity extends AppCompatActivity {
public static final String CARD_PATH_KEY = "CARD_PATH"; public static final String CARD_PATH_KEY = "CARD_PATH";
public static final String VISUALIZATION_MODE_KEY = "VISUALIZATION_MODE"; public static final String VISUALIZATION_MODE_KEY = "VISUALIZATION_MODE";
public static final String DEVELOPER_VISUALIZATION_MODE = "DEVELOPER_VISUALIZATION_MODE"; public static final String DEVELOPER_VISUALIZATION_MODE = "DEVELOPER_VISUALIZATION_MODE";
public static final String USER_VISUALIZATION_MODE = "USER_VISUALIZATION_MODE";
CanvasView canvasView; CanvasView canvasView;
com.getbase.floatingactionbutton.AddFloatingActionButton AddPartButton; com.getbase.floatingactionbutton.AddFloatingActionButton AddPartButton;
@ -47,6 +51,7 @@ public class CardActivity extends AppCompatActivity {
private PartsHolder partsHolder; private PartsHolder partsHolder;
private ProgramakerApi ProgramakerApi; private ProgramakerApi ProgramakerApi;
private ConfigManager Config; private ConfigManager Config;
private ProgramakerGetCustomBlocksResult CustomBlocks = null;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -59,21 +64,27 @@ public class CardActivity extends AppCompatActivity {
this.ProgramakerApi.setToken(token); this.ProgramakerApi.setToken(token);
} }
new GetAsync<ProgramakerGetCustomBlocksResult>().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, partsHolder = new PartsHolder(this);
new Tuple2<>(new Producer<ProgramakerGetCustomBlocksResult>() {
new GetAsync<Tuple2<List<ProgramakerBridgeInfo>, List<ProgramakerBridgeCustomBlockResult>>>()
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
new Tuple3<>(new Producer<Tuple2<List<ProgramakerBridgeInfo>, List<ProgramakerBridgeCustomBlockResult>>>() {
@Override @Override
public ProgramakerGetCustomBlocksResult get() { public Tuple2<List<ProgramakerBridgeInfo>, List<ProgramakerBridgeCustomBlockResult>> get() {
return CardActivity.this.ProgramakerApi.fetchCustomBlocks(); return new Tuple2<>(
CardActivity.this.ProgramakerApi.fetchConnectedBridges(),
CardActivity.this.ProgramakerApi.fetchCustomBlocks());
} }
}, new Consumer<ProgramakerGetCustomBlocksResult>() { }, new Consumer<Tuple2<List<ProgramakerBridgeInfo>,List<ProgramakerBridgeCustomBlockResult>>>() {
@Override @Override
public void apply(ProgramakerGetCustomBlocksResult result) { public void apply(Tuple2<List<ProgramakerBridgeInfo>,List<ProgramakerBridgeCustomBlockResult>> result) {
if (result == null) { partsHolder.addCustomBlocks(result.item1, result.item2);
Log.e("CARDActivity", "error retrieving custom blocks");
}
else {
Log.d("CARDActivity", "custom blocks: " + result.toString()); Log.d("CARDActivity", "custom blocks: " + result.toString());
} }
}, new Consumer<Throwable> () {
@Override
public void apply(Throwable exception) {
Log.e("CARDActivity", "error retrieving custom blocks: " + exception.toString());
} }
})); }));
@ -91,7 +102,6 @@ public class CardActivity extends AppCompatActivity {
canvasView.setParentActivity(this); canvasView.setParentActivity(this);
// Initialize auxiliary elements // Initialize auxiliary elements
partsHolder = new PartsHolder(this);
removePartFab = (FloatingActionButton) findViewById(R.id.remove_part_fab); removePartFab = (FloatingActionButton) findViewById(R.id.remove_part_fab);
canvasView.setDropZone( canvasView.setDropZone(
@ -235,12 +245,12 @@ public class CardActivity extends AppCompatActivity {
if (canvasView.isDragging()){ if (canvasView.isDragging()){
devFabMenu.setVisibility(View.GONE); devFabMenu.setVisibility(View.GONE);
userFabMenu.setVisibility(View.GONE); userFabMenu.setVisibility(View.GONE);
removePartFab.setVisibility(View.VISIBLE); ((View)removePartFab).setVisibility(View.VISIBLE);
Log.d("Main", "Changing visibility!"); Log.d("Main", "Changing visibility!");
} }
else { else {
this.setDevMode(devMode); this.setDevMode(devMode);
removePartFab.setVisibility(View.GONE); ((View)removePartFab).setVisibility(View.GONE);
Log.d("Main", "Now changing visibility!"); Log.d("Main", "Now changing visibility!");
} }
canvasView.setDropZone( canvasView.setDropZone(
@ -250,8 +260,16 @@ public class CardActivity extends AppCompatActivity {
} }
public static void openCard(Context context, CardFile cardfile, String visualizationMode) { public static void openCard(Context context, CardFile cardfile, String visualizationMode) {
openCardByPath(context, cardfile.getPath(), visualizationMode);
}
public static void openCard(Context context, PreviewCard cardfile, String visualizationMode) {
openCardByPath(context, cardfile.getPath(), visualizationMode);
}
private static void openCardByPath(Context context, String path, String visualizationMode) {
Intent i = new Intent(INTENT); Intent i = new Intent(INTENT);
i.putExtra(CARD_PATH_KEY, cardfile.getPath()); i.putExtra(CARD_PATH_KEY, path);
if (visualizationMode != null) { if (visualizationMode != null) {
i.putExtra(VISUALIZATION_MODE_KEY, visualizationMode); i.putExtra(VISUALIZATION_MODE_KEY, visualizationMode);
} }

View File

@ -50,9 +50,7 @@ class CardPreviewArrayAdapter extends ArrayAdapter<PreviewCard> {
cardView.setOnClickListener(new View.OnClickListener() { cardView.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
Intent i = new Intent(CardActivity.INTENT); CardActivity.openCard(getContext(), card, CardActivity.DEVELOPER_VISUALIZATION_MODE);
i.putExtra(CardActivity.CARD_PATH_KEY, card.getPath());
CardPreviewArrayAdapter.this.getContext().startActivity(i);
} }
}); });

View File

@ -1,67 +0,0 @@
package com.codigoparallevar.minicards;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import androidx.appcompat.app.AlertDialog;
import android.util.Log;
import com.codigoparallevar.minicards.parts.buttons.RoundButton;
import com.codigoparallevar.minicards.parts.logic.Ticker;
import com.codigoparallevar.minicards.parts.logic.Toggle;
import com.codigoparallevar.minicards.parts.samples.ColorBox;
import com.codigoparallevar.minicards.parts.strings.ConvertToString;
import com.codigoparallevar.minicards.types.Part;
import com.codigoparallevar.minicards.types.functional.Tuple2;
import java.util.List;
import java.util.Vector;
class PartsHolder {
private final Context context;
private final static List<Tuple2<String, PartInstantiator>> BuiltInParts =
new Vector<Tuple2<String, PartInstantiator>>(){{
add(new Tuple2<>("Round button", RoundButton.getInstantiator()));
add(new Tuple2<>("Ticker", Ticker.getInstantiator()));
add(new Tuple2<>("Red/Green box", ColorBox.getInstantiator()));
add(new Tuple2<>("Toggle", Toggle.getInstantiator()));
add(new Tuple2<>("ToString", ConvertToString.getInstantiator()));
}};
public PartsHolder(Context context) {
this.context = context;
}
public void openAddPartModal(final CanvasView canvasView) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose part type")
.setItems(getPartTypes(), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if ((which >= 0) && (which < BuiltInParts.size())){
Log.d("Minicards partsHolder",
"Spawning " + BuiltInParts.get(which).item1);
PartInstantiator instantiator = BuiltInParts.get(which).item2;
PartsHolder.this.runInstantiator(instantiator, canvasView);
}
}
});
Dialog dialog = builder.create();
dialog.show();
}
private void runInstantiator(PartInstantiator instantiator, CanvasView canvasView) {
Part part = instantiator.build(canvasView);
canvasView.addPart(part);
}
private static String[] getPartTypes() {
String[] partTypes = new String[BuiltInParts.size()];
for (int i = 0; i < BuiltInParts.size(); i++){
partTypes[i] = BuiltInParts.get(i).item1;
}
return partTypes;
}
}

View File

@ -0,0 +1,142 @@
package com.codigoparallevar.minicards.parts;
import android.util.Log;
import com.codigoparallevar.minicards.ScrolledCanvas;
import com.codigoparallevar.minicards.types.Moveable;
import com.codigoparallevar.minicards.types.Part;
import com.codigoparallevar.minicards.types.PartGrid;
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
import com.codigoparallevar.minicards.types.functional.Tuple2;
import com.codigoparallevar.minicards.types.wireData.WireDataType;
import com.programaker.api.data.ProgramakerCustomBlock;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import java.util.UUID;
public class ProgramakerCustomBlockPart implements Part {
private final PartGrid _partGrid;
private final String _id;
private int _xCenter;
private int _yCenter;
private final ProgramakerCustomBlock _block;
public ProgramakerCustomBlockPart(String id, PartGrid grid, Tuple2<Integer, Integer> center, ProgramakerCustomBlock block) {
this._id = id;
this._partGrid = grid;
this._xCenter = center.item1;
this._yCenter = center.item2;
this._block = block;
}
public ProgramakerCustomBlockPart(PartGrid grid, Tuple2<Integer, Integer> center, ProgramakerCustomBlock block) {
this(UUID.randomUUID().toString(), grid, center, block);
}
@Override
public int get_left() {
return 0; // TODO: Implement
}
@Override
public int get_right() {
return 0; // TODO: Implement
}
@Override
public int get_top() {
return 0; // TODO: Implement
}
@Override
public int get_bottom() {
return 0; // TODO: Implement
}
@Override
public void touched() {
Log.i("CustomBlockPart", "Part touched (block_fun=" + this._block.getFunction_name() + ")");
}
@Override
public List<InputConnector> getInputConnectors() {
return null;
}
@Override
public List<OutputConnector> getOutputConnectors() {
return null;
}
@Override
public JSONObject serialize() throws JSONException {
return null;
}
@Override
public void send(InputConnector inputConnector, WireDataType signal) {
}
@Override
public String get_id() {
return _id;
}
@Override
public InputConnector getConnectorWithId(String inputConnectorId) {
return null;
}
@Override
public String getConnectorId(InputConnector inputConnector) {
return null;
}
@Override
public void resume() {
// Intentionally left empty
}
@Override
public void pause() {
// Intentionally left empty
}
@Override
public void draw(ScrolledCanvas canvas, boolean devMode) {
// TODO: Implement
}
@Override
public void moveEnd(int x, int y) {
// TODO: Implement moving connectors
}
@Override
public void drop(int x, int y) {
moveEnd(x, y);
}
@Override
public boolean containsPoint(int x, int y) {
return ((x >= this.get_left()) && (x <= this.get_right())
&& (y >= this.get_top()) && (y <= this.get_top()));
}
@Override
public Moveable getMoveable() {
return this;
}
@Override
public void unlink() {
// TODO: Implement
}
}

View File

@ -0,0 +1,24 @@
package com.codigoparallevar.minicards.toolbox;
import com.codigoparallevar.minicards.PartInstantiator;
import com.codigoparallevar.minicards.types.functional.Tuple2;
import java.util.List;
class PartCategory {
private final String _name;
private final List<Tuple2<String, PartInstantiator>> _parts;
public PartCategory(String name, List<Tuple2<String, PartInstantiator>> parts) {
this._name = name;
this._parts = parts;
}
public String getName() {
return _name;
}
public List<Tuple2<String, PartInstantiator>> getParts() {
return this._parts;
}
}

View File

@ -0,0 +1,132 @@
package com.codigoparallevar.minicards.toolbox;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import androidx.appcompat.app.AlertDialog;
import android.util.Log;
import com.codigoparallevar.minicards.CanvasView;
import com.codigoparallevar.minicards.PartInstantiator;
import com.codigoparallevar.minicards.parts.buttons.RoundButton;
import com.codigoparallevar.minicards.parts.logic.Ticker;
import com.codigoparallevar.minicards.parts.logic.Toggle;
import com.codigoparallevar.minicards.parts.samples.ColorBox;
import com.codigoparallevar.minicards.parts.strings.ConvertToString;
import com.codigoparallevar.minicards.types.Part;
import com.codigoparallevar.minicards.types.functional.Tuple2;
import com.programaker.api.data.ProgramakerBridgeInfo;
import com.programaker.api.data.ProgramakerCustomBlock;
import com.programaker.api.data.api_results.ProgramakerBridgeCustomBlockResult;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Vector;
public class PartsHolder {
private final Context context;
private final static List<Tuple2<String, PartInstantiator>> BuiltInParts =
new Vector<Tuple2<String, PartInstantiator>>(){{
add(new Tuple2<>("Round button", RoundButton.getInstantiator()));
add(new Tuple2<>("Ticker", Ticker.getInstantiator()));
add(new Tuple2<>("Red/Green box", ColorBox.getInstantiator()));
add(new Tuple2<>("Toggle", Toggle.getInstantiator()));
add(new Tuple2<>("ToString", ConvertToString.getInstantiator()));
}};
private final static List<PartCategory> Categories = new Vector<PartCategory>() {{
add(new PartCategory("Testing", BuiltInParts));
}};
private Map<String, ProgramakerBridgeInfo> bridgeInfoMap;
public PartsHolder(Context context) {
this.context = context;
}
public void openAddPartModal(final CanvasView canvasView) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
Map<String, PartCategory> categoryOptions = getPartCategories();
String[] categoryNames = categoryOptions.keySet().toArray(new String[0]);
builder.setTitle("Choose part category")
.setItems(categoryNames, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichCategory) {
if ((whichCategory >= 0) && (whichCategory < categoryNames.length)){
Map<String, PartInstantiator> parts = getPartTypes(categoryOptions.get(categoryNames[whichCategory]));
String[] partNames = parts.keySet().toArray(new String[0]);
builder.setTitle("Choose part type")
.setItems(partNames, (dialog1, whichPart) -> {
if ((whichPart >= 0) && (whichPart < partNames.length)) {
String partName = partNames[whichPart];
Log.d("Minicards partsHolder",
"Spawning " + partName);
PartInstantiator instantiator = parts.get(partName);
PartsHolder.this.runInstantiator(instantiator, canvasView);
}
});
Dialog dialog2 = builder.create();
dialog2.show();
}
}
});
Dialog dialog = builder.create();
dialog.show();
}
private void runInstantiator(PartInstantiator instantiator, CanvasView canvasView) {
Part part = instantiator.build(canvasView);
canvasView.addPart(part);
}
private static Map<String,PartCategory> getPartCategories() {
Map<String, PartCategory> partTypes = new LinkedHashMap<>(Categories.size());
for (int i = 0; i < Categories.size(); i++){
partTypes.put(Categories.get(i).getName(), Categories.get(i));
}
return partTypes;
}
private static Map<String, PartInstantiator> getPartTypes(PartCategory categoryOption) {
HashMap<String, PartInstantiator> partMap = new LinkedHashMap<>();
for (Tuple2<String, PartInstantiator> part : categoryOption.getParts()) {
partMap.put(part.item1, part.item2);
}
return partMap;
}
public void addCustomBlocks(List<ProgramakerBridgeInfo> bridgeInfo, List<ProgramakerBridgeCustomBlockResult> customBlocks) {
Map<String, ProgramakerBridgeInfo> bridgeInfoMap = new LinkedHashMap<>();
for (ProgramakerBridgeInfo info : bridgeInfo) {
bridgeInfoMap.put(info.getId(), info);
}
this.bridgeInfoMap = bridgeInfoMap;
for (ProgramakerBridgeCustomBlockResult res : customBlocks) {
List<Tuple2<String, PartInstantiator>> parts = new LinkedList<>();
for (ProgramakerCustomBlock block : res.getBlocks()) {
parts.add(new Tuple2<>(block.getMessage(), new ProgramakerCustomBlockInstantiator(block)));
}
if (bridgeInfoMap.containsKey(res.getBridge_id())) {
Categories.add(new PartCategory(bridgeInfoMap.get(res.getBridge_id()).getName(), parts));
}
else {
Categories.add(new PartCategory("Bridge ID="+res.getBridge_id(), parts));
}
}
}
}

View File

@ -0,0 +1,22 @@
package com.codigoparallevar.minicards.toolbox;
import com.codigoparallevar.minicards.PartInstantiator;
import com.codigoparallevar.minicards.parts.ProgramakerCustomBlockPart;
import com.codigoparallevar.minicards.parts.buttons.RoundButton;
import com.codigoparallevar.minicards.types.Part;
import com.codigoparallevar.minicards.types.PartGrid;
import com.codigoparallevar.minicards.types.functional.Tuple2;
import com.programaker.api.data.ProgramakerCustomBlock;
class ProgramakerCustomBlockInstantiator extends PartInstantiator {
private final ProgramakerCustomBlock _block;
public ProgramakerCustomBlockInstantiator(ProgramakerCustomBlock block) {
this._block = block;
}
@Override
protected Part instantiate(PartGrid grid, Tuple2<Integer, Integer> center) {
return new ProgramakerCustomBlockPart(grid, center, this._block);
}
}

View File

@ -6,24 +6,31 @@ import android.util.Log;
import com.codigoparallevar.minicards.types.functional.Consumer; import com.codigoparallevar.minicards.types.functional.Consumer;
import com.codigoparallevar.minicards.types.functional.Producer; import com.codigoparallevar.minicards.types.functional.Producer;
import com.codigoparallevar.minicards.types.functional.Tuple2; import com.codigoparallevar.minicards.types.functional.Tuple2;
import com.codigoparallevar.minicards.types.functional.Tuple3;
public class GetAsync<T> extends AsyncTask<Tuple2<Producer<T>, Consumer<T>>, public class GetAsync<T> extends AsyncTask<Tuple3<Producer<T>, Consumer<T>, Consumer<Throwable>>,
Void, Void,
Tuple2<T, Consumer<T>>> { Tuple2<T, Consumer<T>>> {
@Override @Override
protected Tuple2<T, Consumer<T>> doInBackground(Tuple2<Producer<T>, Consumer<T>>... data) { protected Tuple2<T, Consumer<T>> doInBackground(Tuple3<Producer<T>, Consumer<T>, Consumer<Throwable>>... data) {
try { try {
return new Tuple2<>(data[0].item1.get(), data[0].item2); T result = data[0]._x.get();
return new Tuple2<>(result, data[0]._y);
} }
catch (Exception ex) { catch (Throwable ex) {
Log.e("GetAsync", ex.toString()); data[0]._z.apply(ex);
return new Tuple2<>(null, data[0].item2); return null;
} }
} }
@Override @Override
protected void onPostExecute(Tuple2<T, Consumer<T>> result) { protected void onPostExecute(Tuple2<T, Consumer<T>> result) {
if (result == null) {
return;
}
else {
result.item2.apply(result.item1); result.item2.apply(result.item1);
} }
} }
}

View File

@ -4,11 +4,9 @@ import android.os.Build
import android.util.Log import android.util.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import com.programaker.api.data.ProgramakerBridgeInfo
import com.programaker.api.data.ProgramakerCustomBlock import com.programaker.api.data.ProgramakerCustomBlock
import com.programaker.api.data.api_results.ProgramakerCheckResult import com.programaker.api.data.api_results.*
import com.programaker.api.data.api_results.ProgramakerGetCustomBlocksResult
import com.programaker.api.data.api_results.ProgramakerGetCustomBlocksResultTypeAdapter
import com.programaker.api.data.api_results.ProgramakerLoginResult
import com.programaker.api.exceptions.ProgramakerLoginRequiredException import com.programaker.api.exceptions.ProgramakerLoginRequiredException
import com.programaker.api.exceptions.ProgramakerProtocolException import com.programaker.api.exceptions.ProgramakerProtocolException
import com.programaker.api.exceptions.TokenNotFoundException import com.programaker.api.exceptions.TokenNotFoundException
@ -84,7 +82,7 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
return result.token return result.token
} }
fun fetchCustomBlocks(): ProgramakerGetCustomBlocksResult { fun fetchCustomBlocks(): List<ProgramakerBridgeCustomBlockResult> {
val conn = URL(getCustomBlocksUrl()).openConnection() as HttpURLConnection val conn = URL(getCustomBlocksUrl()).openConnection() as HttpURLConnection
addAuthHeader(conn) addAuthHeader(conn)
@ -106,7 +104,32 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
ex.logError(LogTag) ex.logError(LogTag)
throw ProgramakerProtocolException() throw ProgramakerProtocolException()
} }
return result return result.result
}
fun fetchConnectedBridges(): List<ProgramakerBridgeInfo> {
val conn = URL(getConnectedBridgesUrl()).openConnection() as HttpURLConnection
addAuthHeader(conn)
val result: ProgramakerGetBridgeInfoResult
try {
val builder = GsonBuilder()
builder.registerTypeAdapter(ProgramakerGetBridgeInfoResult::class.java, ProgramakerGetBridgeInfoTypeAdapter())
val gson = builder.create()
val reader = InputStreamReader(conn.inputStream)
result = gson.fromJson(reader, ProgramakerGetBridgeInfoResult::class.java)
} catch(ex: JsonParseException) {
ex.logError(LogTag)
throw ProgramakerProtocolException()
} catch (ex: FileNotFoundException) {
ex.logError(LogTag)
throw ProgramakerProtocolException()
}
return result.result
} }
// Initialization // Initialization
@ -128,6 +151,16 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
} }
private fun getCustomBlocksUrl(): String { private fun getCustomBlocksUrl(): String {
this.withUserName()
return "$ApiRoot/v0/users/$userName/custom-blocks/"
}
private fun getConnectedBridgesUrl(): String {
this.withUserName()
return "$ApiRoot/v0/users/$userName/bridges/"
}
private fun withUserName() {
if (userName == null) { if (userName == null) {
if (token == null) { if (token == null) {
throw ProgramakerLoginRequiredException() throw ProgramakerLoginRequiredException()
@ -138,8 +171,6 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
throw ProgramakerProtocolException() throw ProgramakerProtocolException()
} }
} }
return "$ApiRoot/v0/users/$userName/custom-blocks/"
} }
private fun addAuthHeader(conn: URLConnection) { private fun addAuthHeader(conn: URLConnection) {

View File

@ -0,0 +1,9 @@
package com.programaker.api.data
class ProgramakerBridgeInfo (
val id: String,
val name: String
// val is_connected: boolean
// val icon: Map<String, Object>
) {
}

View File

@ -0,0 +1,6 @@
package com.programaker.api.data.api_results
import com.programaker.api.data.ProgramakerBridgeInfo
internal class ProgramakerGetBridgeInfoResult(val result: List<ProgramakerBridgeInfo>) {
}

View File

@ -0,0 +1,28 @@
package com.programaker.api.data.api_results
import com.google.gson.*
import com.programaker.api.data.ProgramakerBridgeInfo
import com.programaker.api.data.ProgramakerCustomBlock
import java.lang.reflect.Type
import java.util.*
internal class ProgramakerGetBridgeInfoTypeAdapter : JsonSerializer<ProgramakerGetBridgeInfoResult?>, JsonDeserializer<ProgramakerGetBridgeInfoResult> {
var gson = Gson()
override fun serialize(customBlock: ProgramakerGetBridgeInfoResult?, typeOfT: Type, context: JsonSerializationContext): JsonElement {
throw NotImplementedError()
}
@Throws(JsonParseException::class)
override fun deserialize(element: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ProgramakerGetBridgeInfoResult {
val array = element.asJsonArray
val bridges: MutableList<ProgramakerBridgeInfo> = LinkedList()
for (value in array) {
val bridge = gson.fromJson(value, ProgramakerBridgeInfo::class.java)
bridges.add(bridge)
}
return ProgramakerGetBridgeInfoResult(bridges)
}
}

View File

@ -1,4 +1,4 @@
package com.programaker.api.data.api_results package com.programaker.api.data.api_results
class ProgramakerGetCustomBlocksResult(val result: List<ProgramakerBridgeCustomBlockResult>) { internal class ProgramakerGetCustomBlocksResult(val result: List<ProgramakerBridgeCustomBlockResult>) {
} }

View File

@ -5,7 +5,7 @@ import com.programaker.api.data.ProgramakerCustomBlock
import java.lang.reflect.Type import java.lang.reflect.Type
import java.util.* import java.util.*
class ProgramakerGetCustomBlocksResultTypeAdapter : JsonSerializer<ProgramakerGetCustomBlocksResult?>, JsonDeserializer<ProgramakerGetCustomBlocksResult> { internal class ProgramakerGetCustomBlocksResultTypeAdapter : JsonSerializer<ProgramakerGetCustomBlocksResult?>, JsonDeserializer<ProgramakerGetCustomBlocksResult> {
var gson = Gson() var gson = Gson()
override fun serialize(customBlock: ProgramakerGetCustomBlocksResult?, typeOfT: Type, context: JsonSerializationContext): JsonElement { override fun serialize(customBlock: ProgramakerGetCustomBlocksResult?, typeOfT: Type, context: JsonSerializationContext): JsonElement {
throw NotImplementedError() throw NotImplementedError()