Commit e1b6287a by Arturo Montejo Ráez

Merge branch 'develop' of http://gitlab.ujaen.es/yotta/pictogram into develop

parents e18a8568 8d2df29d
Showing with 519 additions and 130 deletions
......@@ -31,4 +31,5 @@ dependencies {
compile project(':commonlibrary')
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:support-v4:24.2.1'
compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.+'
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yottacode.pictogram.tabletlibrary">
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application
android:allowBackup="true"
android:label="@string/app_name"
......
package com.yottacode.pictogram.tabletlibrary.gui.communicator;
import com.yottacode.pictogram.tabletlibrary.R;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.ColorRes;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;
public class BotonCircular extends android.support.v7.widget.AppCompatImageView {
private static final int PRESSED_COLOR_LIGHTUP = 255 / 25;
private static final int PRESSED_RING_ALPHA = 75;
private static final int DEFAULT_PRESSED_RING_WIDTH_DIP = 4;
private static final int ANIMATION_TIME_ID = android.R.integer.config_shortAnimTime;
private int centerY;
private int centerX;
private int outerRadius;
private int pressedRingRadius;
private Paint circlePaint;
private Paint focusPaint;
private float animationProgress;
private int pressedRingWidth;
private int defaultColor;
private int pressedColor;
private ObjectAnimator pressedAnimator;
public BotonCircular(Context context) {
super(context);
init(context, null);
}
public BotonCircular(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public BotonCircular(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
@Override
public void setPressed(boolean pressed) {
super.setPressed(pressed);
if (circlePaint != null) {
circlePaint.setColor(pressed ? pressedColor : defaultColor);
}
if (pressed) {
showPressedRing();
} else {
hidePressedRing();
}
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(centerX, centerY, pressedRingRadius + animationProgress, focusPaint);
canvas.drawCircle(centerX, centerY, outerRadius - pressedRingWidth, circlePaint);
super.onDraw(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = w / 2;
centerY = h / 2;
outerRadius = Math.min(w, h) / 2;
pressedRingRadius = outerRadius - pressedRingWidth - pressedRingWidth / 2;
}
public float getAnimationProgress() {
return animationProgress;
}
public void setAnimationProgress(float animationProgress) {
this.animationProgress = animationProgress;
this.invalidate();
}
public void setColor(int color) {
this.defaultColor = color;
this.pressedColor = getHighlightColor(color,PRESSED_COLOR_LIGHTUP);
circlePaint.setColor(defaultColor);
focusPaint.setColor(pressedColor);
focusPaint.setAlpha(PRESSED_RING_ALPHA);
this.invalidate();
}
/**Esconder anillo exterior animacion*/
private void hidePressedRing() {
pressedAnimator.setFloatValues(pressedRingWidth, 0f);
pressedAnimator.start();
}
public void PhidePressedRing() {
pressedAnimator.setFloatValues(pressedRingWidth, 0f);
pressedAnimator.start();
}
/**Mostrar anillo exterior animacion*/
private void showPressedRing() {
pressedAnimator.setFloatValues(animationProgress, pressedRingWidth);
pressedAnimator.start();
}
public void PshowPressedRing() {
pressedAnimator.setFloatValues(animationProgress, pressedRingWidth);
pressedAnimator.start();
}
private void init(Context context, AttributeSet attrs) {
this.setFocusable(true);
this.setScaleType(ScaleType.CENTER_INSIDE);
setClickable(true);
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setStyle(Paint.Style.FILL);
focusPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
focusPaint.setStyle(Paint.Style.STROKE);
pressedRingWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_PRESSED_RING_WIDTH_DIP, getResources()
.getDisplayMetrics());
//int color = Color.rgb(106, 142, 26);
/*if (attrs != null) {
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleButton);
color = a.getColor(R.styleable.CircleButton_cb_color, color);
pressedRingWidth = (int) a.getDimension(R.styleable.CircleButton_cb_pressedRingWidth, pressedRingWidth);
a.recycle();
}*/
int color = getResources().getColor(R.color.VerdeApp);
setColor(color);
focusPaint.setStrokeWidth(pressedRingWidth);
final int pressedAnimationTime = getResources().getInteger(ANIMATION_TIME_ID);
pressedAnimator = ObjectAnimator.ofFloat(this, "animationProgress", 0f, 0f);
pressedAnimator.setDuration(pressedAnimationTime);
}
private int getHighlightColor(int color, int amount) {
return Color.argb(Math.min(255, Color.alpha(color)), Math.min(255, Color.red(color) + amount),
Math.min(255, Color.green(color) + amount), Math.min(255, Color.blue(color) + amount));
}
}
package com.yottacode.pictogram.tabletlibrary.gui.communicator;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.yottacode.pictogram.dao.Picto;
import com.yottacode.pictogram.tabletlibrary.R;
import com.yottacode.pictogram.tabletlibrary.gui.communicator.cropper.EditPictoActivity;
import com.yottacode.pictogram.tabletlibrary.gui.login.MainActivity;
import com.yottacode.pictogram.tools.PCBcontext;
import com.yottacode.tools.GUITools;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -80,7 +87,7 @@ public class PictoMenu {
activity.getIntent().putExtra(Picto.JSON_ATTTRS.EXPRESSION, expression);
//Enviar al PictogramActivity los datos necesarios para crear el picto despues
if (PCBcontext.getPcbdb().getCurrentUser().has_categories()) {
activity.getIntent().putExtra("cat", cat);
activity.getIntent().putExtra(Picto.JSON_ATTTRS.CATEGORY, cat);
activity.getIntent().putExtra(Picto.JSON_ATTTRS.ROW, row);
activity.getIntent().putExtra(Picto.JSON_ATTTRS.COLUMN, col);
} else {
......@@ -100,6 +107,42 @@ public class PictoMenu {
}
public void setPicto(int row, int col, int cat, String expression, Bitmap bitmap){
Intent intent = new Intent(activity, EditPictoActivity.class);
intent.putExtra(Picto.JSON_ATTTRS.EXPRESSION, expression);
//Enviar al PictogramActivity los datos necesarios para editar el picto despues
if (PCBcontext.getPcbdb().getCurrentUser().has_categories()) {
intent.putExtra(Picto.JSON_ATTTRS.CATEGORY, cat);
intent.putExtra(Picto.JSON_ATTTRS.ROW, row);
intent.putExtra(Picto.JSON_ATTTRS.COLUMN, col);
} else {
intent.putExtra(Picto.JSON_ATTTRS.FREE_ROW, row);
intent.putExtra(Picto.JSON_ATTTRS.FREE_COLUMN, col);
}
if(bitmap!=null) {
Point size= GUITools.getScreenSize(activity);
float bWidth = bitmap.getWidth();
float bHeight = bitmap.getHeight();
float factorX=size.x*0.7f/bWidth;
float factorY=size.y*0.7f/bHeight;
float factor= factorY>factorX ? factorX : factorY;
bWidth=bWidth*factor;
bHeight=bHeight*factor;
Bitmap rescaled = Bitmap.createScaledBitmap(bitmap,(int) bWidth, (int) bHeight, true);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
rescaled.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
intent.putExtra(EditPictoActivity.IMAGE_PICTO, byteArray);
}
intent.putExtra("tipo",true);
activity.startActivityForResult(intent,EditPictoActivity.EDIT_PICTO_REQUEST);
}
/**Function for build a radial menu
*
* @param is_picto_big
......@@ -245,21 +288,29 @@ public class PictoMenu {
}
public String getName() { return "edit"; }
public String getLabel() { return null; }
public int getIcon() { return R.drawable.edit_picture; }
public int getIcon() { return R.drawable.edit; }
private List<RadialMenuWidget.RadialMenuEntry> children;
public List<RadialMenuWidget.RadialMenuEntry> getChildren() { return children; }
public void menuActiviated()
{
ll.getChildAt(1).setX(ll.getChildAt(1).getX() + 30);
children = new ArrayList<>(Arrays.asList(new PickFromCamera(p),new PickFromGallery(p)));
ll.setVisibility(View.GONE);
ll.removeAllViewsInLayout();
try {
setPicto(p.get_row(),p.get_column(),p.get_category(),p.get_translation(),p.get_bitmap(PCBcontext.getContext()));
} catch (IOException e) {
e.printStackTrace();
}
//ll.getChildAt(1).setX(ll.getChildAt(1).getX() + 30);
//children = new ArrayList<>(Arrays.asList(new PickFromCamera(p),new PickFromGallery(p)));
}
public void menuDisabled(){
ll.getChildAt(1).setX(ll.getChildAt(1).getX() - 30);
//ll.getChildAt(1).setX(ll.getChildAt(1).getX() - 30);
}
}
public class PickFromCamera implements RadialMenuWidget.RadialMenuEntry
/*public class PickFromCamera implements RadialMenuWidget.RadialMenuEntry
{
Picto p;
public PickFromCamera(Picto picto){
......@@ -296,7 +347,7 @@ public class PictoMenu {
addPicto(p.get_row(),p.get_column(),p.get_category(),p.get_translation(),1);
}
public void menuDisabled(){}
}
}*/
public class newPickFromCamera implements RadialMenuWidget.RadialMenuEntry
{
......
......@@ -1127,8 +1127,6 @@ protected void showOnlyTape(boolean onlyTape) {
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
int cat = getIntent().getIntExtra("cat", -1);
Bitmap imagen = null;
switch(requestCode) {
case CAMERA_PIC_REQUEST: //Captura de foto
......@@ -1151,14 +1149,19 @@ protected void showOnlyTape(boolean onlyTape) {
break;
case EditPictoActivity.EDIT_PICTO_REQUEST:
if (resultCode == RESULT_OK) {
int row = getIntent().getIntExtra(Picto.JSON_ATTTRS.ROW, -1);
int col = getIntent().getIntExtra(Picto.JSON_ATTTRS.COLUMN, -1);
int freeRow = getIntent().getIntExtra(Picto.JSON_ATTTRS.FREE_ROW, -1);
int freeColumn = getIntent().getIntExtra(Picto.JSON_ATTTRS.FREE_COLUMN, -1);
boolean edit = data.getBooleanExtra("tipo",false);
int row = edit ? data.getExtras().getInt(Picto.JSON_ATTTRS.ROW) : getIntent().getIntExtra(Picto.JSON_ATTTRS.ROW, -1);
int col = edit ? data.getExtras().getInt(Picto.JSON_ATTTRS.COLUMN) : getIntent().getIntExtra(Picto.JSON_ATTTRS.COLUMN, -1);
int freeRow = edit ? data.getExtras().getInt(Picto.JSON_ATTTRS.FREE_ROW) : getIntent().getIntExtra(Picto.JSON_ATTTRS.FREE_ROW, -1);
int freeColumn = edit ? data.getExtras().getInt(Picto.JSON_ATTTRS.FREE_COLUMN) : getIntent().getIntExtra(Picto.JSON_ATTTRS.FREE_COLUMN, -1);
int cat = edit ? data.getIntExtra(Picto.JSON_ATTTRS.CATEGORY, -1) : getIntent().getIntExtra(Picto.JSON_ATTTRS.CATEGORY, -1);
String path = data.getExtras().getString(EditPictoActivity.PATH);
String legend = data.getExtras().getString(Picto.JSON_ATTTRS.EXPRESSION);
chooseTextAndSavePicto(path, row, col, freeRow, freeColumn, cat, legend);
refresh();
}
break;
}
......
......@@ -31,7 +31,7 @@ import com.yottacode.pictogram.tabletlibrary.gui.communicator.cropper.util.Paint
*
* Class to see it on the image to crop
*/
public class CropImageView extends ImageView {
public class CropImageView extends android.support.v7.widget.AppCompatImageView {
......
......@@ -22,7 +22,7 @@ public class PaintUtil {
final Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(resources.getDimension(R.dimen.border_thickness));
paint.setColor(resources.getColor(R.color.border));
paint.setColor(resources.getColor(R.color.VerdeApp));
return paint;
}
......@@ -35,7 +35,7 @@ public class PaintUtil {
final Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(resources.getDimension(R.dimen.guideline_thickness));
paint.setColor(resources.getColor(R.color.guideline));
paint.setColor(resources.getColor(R.color.VerdeApp));
return paint;
}
......@@ -62,7 +62,7 @@ public class PaintUtil {
final Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(resources.getDimension(R.dimen.corner_thickness));
paint.setColor(resources.getColor(R.color.corner));
paint.setColor(resources.getColor(R.color.VerdeApp));
return paint;
}
......
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- main color -->
<item
android:bottom="2dp"
android:left="2dp"
android:right="2dp">
<shape>
<solid android:color="#FFFFFF" />
</shape>
</item>
<item>
<selector >
<item android:state_enabled="true"
android:state_focused="true">
<shape>
<stroke
android:width="2dp"
android:color="@color/VerdeApp"/>
</shape>
</item>
<item android:state_enabled="true">
<shape>
<stroke
android:width="2dp"
android:color="#ffffffff"/>
</shape>
</item>
</selector>
</item>
<!-- draw another block to cut-off the left and right bars -->
<item android:bottom="5.0dp">
<shape>
<solid android:color="#ffffff" />
</shape>
</item>
</layer-list>
......@@ -37,7 +37,6 @@
<string name="session_eval_notevuated">not evaluated</string>
<string name="session_eval_discarded">discarded</string>
<string name="crop">Crop</string>
<string name="titleCropper">Edit Picto</string>
<string name="cancel">Cancel</string>
<string name="legendText">Legend</string>
......@@ -45,6 +44,8 @@
<!-- Cropper -->
<string name="crop_TextRequired">Por favor, introduzca una leyenda para el pictograma</string>
<string name="uploadingImage">Subiendo imagen al servidor</string>
<string name="titleCropperEdit">Edit Picto</string>
<string name="titleCropperNew">New Picto</string>
</resources>
......@@ -37,14 +37,14 @@
<string name="session_eval_notevuated">no evaluado</string>
<string name="session_eval_discarded">inválido</string>
<string name="crop">Recortar</string>
<string name="titleCropper">Nuevo Pictograma</string>
<string name="crop_TextRequired">Por favor, introduzca una leyenda para el pictograma</string>
<!-- Cropper -->
<string name="legendText">Leyenda:</string>
<string name="uploadingImage">Subiendo imagen al servidor</string>
<string name="cancel">Cancelar</string>
<string name="titleCropperEdit">Editar Pictograma</string>
<string name="titleCropperNew">Nuevo Pictograma</string>
</resources>
......@@ -42,8 +42,9 @@
<string name="legendText">Leyenda:</string>
<string name="crop">Recortar</string>
<string name="titleCropper">Nuevo Pictograma</string>
<string name="titleCropperNew">Nuevo Pictograma</string>
<string name="titleCropperEdit">Editar Pictograma</string>
<string name="crop_TextRequired">Por favor, introduzca una leyenda para el pictograma</string>
<string name="uploadingImage">Subiendo imagen al servidor</string>
<string name="cancel">Cancel</string>
</resources>
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":tabletlibrary" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" version="4">
<module external.linked.project.id=":tabletlibrary" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
......
......@@ -7,20 +7,27 @@
cd /vagrant/
echo "--Descargando coleccion de pictogramas"
wget http://dev.yottacode.com/symbolstx.tgz.gpg
wget http://dev.yottacode.com/upload.tgz.gpg
wget https://dev.pictogramweb.com/symbolstx.tgz.gpg
wget https://dev.pictogramweb.com/upload.tgz.gpg
wget https://dev.pictogramweb.com/arasaac.tgz.gpg
echo "--Desencriptando coleccion"
echo r\"YjtnB+a4$.M*nJ | gpg --batch --no-tty --yes --passphrase-fd 0 symbolstx.tgz.gpg
echo r\"YjtnB+a4$.M*nJ | gpg --batch --no-tty --yes --passphrase-fd 0 upload.tgz.gpg
echo r\"YjtnB+a4$.M*nJ | gpg --batch --no-tty --yes --passphrase-fd 0 arasaac.tgz.gpg
echo "--Descomprimiendo coleccion"
tar zxvf /vagrant/symbolstx.tgz
tar zxvf /vagrant/upload.tgz
tar zxvf /vagrant/arasaac.tgz
echo "--Renombrado y borrado de archivos"
rm upload.tgz
rm upload.tgz.gpg
rm symbolstx.tgz
rm symbolstx.tgz.gpg
mv symbolstx_96x82 symbolstx
rm arasaac.tgz
rm arasaac.tgz.gpg
This diff could not be displayed because it is too large.
......@@ -55,9 +55,8 @@ INSERT INTO `meta_instruction` (`id` ,`name` ,`objective` ,`id_met`, `lang`) VA
INSERT INTO `source` (`id`, `name`, `description`) VALUES
(1, 'SymbolStix', 'n2y SymbolStix pictograms collection'),
(2, 'Custom', 'Uploaded pictograms by a given user');
;
(2, 'Custom', 'Uploaded pictograms by a given user'),
(3, 'Arasaac', 'Arasaac pictograms collection');
--
-- Volcado de datos para la tabla `picto`
......
......@@ -372,6 +372,8 @@ CREATE TABLE IF NOT EXISTS `supervisor` (
`password` varchar(60) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'Encrypted password using the BCrypt algorithm',
`id_off` int(11) DEFAULT NULL,
`active` boolean DEFAULT FALSE,
`arasaac_license` boolean DEFAULT FALSE,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
KEY `id_off` (`id_off`)
......
......@@ -24,6 +24,15 @@
state: import
target: "{{ server_path }}/{{ database_files_relative_path }}/symbolstix.sql"
- name: Imports arasaac pictos
mysql_db:
login_user: "{{ database_user }}"
login_password: "{{ database_user_passwd }}"
name: "{{ database_name }}"
state: import
target: "{{ server_path }}/{{ database_files_relative_path }}/arasaac.sql"
- name: Imports application essential data
mysql_db:
login_user: "{{ database_user }}"
......
......@@ -13,6 +13,13 @@ Changes to be performed manually in servers to upgrade
## Database
(ToDo in dev)
- add arasaac to source table
`INSERT INTO `source` (`id`, `name`, `description`) VALUES (3, 'Arasaac', 'Arasaac pictograms collection');`
- alter table supervisor add arasaac license:
`ALTER TABLE supervisor ADD COLUMN arasaac_license BOOLEAN DEFAULT FALSE;`
(already done in dev)
- load pictocat_tree_populate.sql
......
......@@ -372,6 +372,70 @@ module.exports = {
},
/**
* Return all pictos from Arasaac using the language of the specified supervisor.
* @param {request} req {} (with supervisorId as url parameters)
* @param {response} res
* [
* {
* expressions: [
* // There should be just one expression per picto
* // with the language being used by the supervisor
* {
* id: 1234,
* lang: 'es-es',
* text: 'nacimiento',
* picto: 23
* }
* ],
* source: 1,
* owner: null,
* id: 23,
* uri: 'picto/uri.jpg',
* category: 41
* }
* ]
*/
fromArasaac: function (req, res) {
var l = [];
var fs = require('fs');
Supervisor.findOne({ id: req.params.id }).then(function (supervisor) {
if (supervisor) {
Picto.find({ source: 3})
.paginate({page: req.params.page, limit:req.params.limit})
.populate('expressions', { lang: supervisor.lang })
.then(function (pictos) {
async.eachSeries(pictos, function(picto, next_cb) {
// check picto has expressions associated in student language
if (picto.expressions.length == 0 || picto.expressions[0].text.length == 0)
return next_cb();
// check picto image is available
picto.imageFileExists((found) => {
if (found) {
l.push(picto);
next_cb();
}
else
next_cb();
});
},
function (err) { // loop has end
if (err) throw err;
sails.log.debug(pictos.length + " pictos sent from Arasaac in language " + supervisor.lang);
return res.ok(l);
}); // end async.eachSeries
})
.catch(() => res.badRequest());
} else {
return res.badRequest();
}
})
.catch(() => res.serverError());
},
/**
* Add a tag to an existing picto. This tag is associated to the supervisor.
* @param {request} req
* {
......
......@@ -200,6 +200,32 @@ module.exports = {
},
/**
* Acept Arasaac License
* @param {request} req
* {
* "token": "12398123aas78sf798as7d987234" // Encryted code with supervisor ID, siging role and id_off
* }
*/
accept_arasaac: function (req, res) {
var params = req.params.all();
Supervisor.findOne(params.id)
.then(function (supervisor) {
if (!supervisor)
throw new Error("Error when looking for user");
supervisor.arasaacLicense = true;
delete supervisor.password;
supervisor.save();
res.ok();
})
.catch(function (err) {
return res.serverError(err.message ? err.message : 'Supervisor not found');
});
},
/**
* Gets a supervisor by his email
* @param {request} req {} (width email as url parameter)
* @param {response} res
......@@ -261,7 +287,7 @@ module.exports = {
create: function (req, res) {
var params = req.params.all();
var supervisor;
// Send email confirmation
function sendConfirmationMail(cb) {
......@@ -318,7 +344,7 @@ module.exports = {
return res.serverError("Supervisor created but returned null");
supervisor = sup;
if (params.role === 'therapist_office' || params.role === 'tutor_office') {
sendConfirmationMail((err) => {
if (err) throw err;
......
......@@ -84,6 +84,10 @@ module.exports = {
active: {
type: 'boolean'
},
arasaacLicense: {
type: 'boolean',
columnName: 'arasaac_license'
},
office: {
columnName: 'id_off',
type: 'integer',
......
......@@ -111,6 +111,7 @@
"enlarge": "Enlarge",
"enormous": "Enormous",
"error_adding_picto": "Error adding picto",
"error_arasaac_license": "Error accepting Arasaac license",
"error_creating_session": "Error when creating session",
"error_deleting_picto": "Error deleting picto",
"error_downloading_supervisors": "Error downloading supervisors",
......
......@@ -114,6 +114,7 @@
"expand_navigation": "Desplegar navegación",
"expression": "Expresión",
"error_adding_picto": "Error al añadir el picto",
"error_arasaac_license": "Error al aceptar la licencia de Arasaac",
"error_creating_session": "Error al crear sesión",
"error_deleting_picto": "Error borrando el picto",
"error_downloading_supervisors": "Error al descargar los supervisores",
......
/vagrant/arasaac
\ No newline at end of file
......@@ -242,12 +242,10 @@ dashboardDirectives.directive('popoveraddpicto', function() {
restrict: 'A',
link: function (scope, element, attrs) {
if(element[0].y <= y){
y=element[0].y;
attrs.popoverPlacement="bottom";
}
console.log(element[0].y);
console.log(angular.element( document.querySelector( '#collections' ) ));
if(element[0].y <= y){
y=element[0].y;
attrs.popoverPlacement="bottom";
}
}
}
});
......@@ -29,6 +29,7 @@ dashboardControllers.controller('AddPictoCtrl', function (
$scope.loadingCatPictos = false;
$scope.radioModel = 'Middle';
$scope.onlyOwn = onlyOwn;
$scope.showArasaacLicense = !supervisor.arasaacLicense; //If true, won't show license agreement
/*
* Get data about SymbolStix
......@@ -72,6 +73,49 @@ dashboardControllers.controller('AddPictoCtrl', function (
});
};
$scope.accept_arasaac = function (){
$http.get(config.backend + '/sup/arasaac_license/' + supervisor.id)
.success(function () {
$scope.showArasaacLicense = false;
supervisor.arasaacLicense = true;
$scope.load_arasaac_pictos();
})
.error(function () {
$translate('error_arasaac_license').then(function (translation) {
ngToast.danger({ content: translation });
});
});
};
$scope.load_arasaac_pictos = function () {
$scope.pictos = [];
$scope.page = 1;
if(!$scope.showArasaacLicense){
$scope.loadingCatPictos = true;
var request = "";
//Request page X from all pictos (symbolstx)
request = config.backend + '/sup/' + supervisor.id +
'/pic_fromArasaac/page/'+$scope.page+'/limit/'+$scope.limit;
$http.get(request)
.success(function (data) {
if (data && $scope.source == 'arasaac'){
$scope.pictos = data;
}
$scope.loadingCatPictos = false;
setTimeout(function () { $scope.$apply(); });
})
.error(function () {
$translate('error_loading_pictos').then(function (translation) {
ngToast.danger({ content: translation });
});
$scope.loadingCatPictos = false;
});
}
};
//
// Load pictos owned by the actual supervisor
//
......@@ -288,16 +332,22 @@ dashboardControllers.controller('AddPictoCtrl', function (
$scope.page += 1;
var request = "";
if($scope.breadcrumbs.length == 1) {
if($scope.source == "symbolstx"){
if($scope.breadcrumbs.length == 1) {
//Request page X from all pictos (symbolstx)
request = config.backend + '/sup/' + supervisor.id +
'/pic_fromSymbolStx/page/'+$scope.page+'/limit/'+$scope.limit;
}else{
request = config.backend + '/sup/' + supervisor.id +
'/pic_fromCatSubcat/category/'+$scope.breadcrumbs[$scope.breadcrumbs.length-1].id
+'/page/'+$scope.page+'/limit/'+$scope.limit;
}
}else if($scope.source == "arasaac"){
//Request page X from all pictos (symbolstx)
request = config.backend + '/sup/' + supervisor.id +
'/pic_fromSymbolStx/page/'+$scope.page+'/limit/'+$scope.limit;
}else{
request = config.backend + '/sup/' + supervisor.id +
'/pic_fromCatSubcat/category/'+$scope.breadcrumbs[$scope.breadcrumbs.length-1].id
+'/page/'+$scope.page+'/limit/'+$scope.limit;
'/pic_fromArasaac/page/'+$scope.page+'/limit/'+$scope.limit;
}
$http.get(request)
.success(function (data) {
$scope.pictos = $scope.pictos.concat(data);
......@@ -324,17 +374,19 @@ dashboardControllers.controller('AddPictoCtrl', function (
}else if(length == 0){ // If there is no word, reset pictos
if ($scope.onlyOwn || $scope.source == "ownpictos"){
$scope.load_own_pictos();
}else{
}else if($scope.source == "symbolstx"){
$scope.open_category_from_bc(0);
}else if($scope.source == "arasaac"){
$scope.load_arasaac_pictos();
}
}else{
var request = "";
var source = 1;
var source = 1; //symbolstx
$scope.closeAlert();
$scope.loadingCatPictos = true;
//category to look in
var category;
var category = 0; //All pictos
if (!$scope.onlyOwn){
category = $scope.breadcrumbs[$scope.breadcrumbs.length-1].id;
if(category == 999){
......@@ -344,7 +396,8 @@ dashboardControllers.controller('AddPictoCtrl', function (
if($scope.source == "ownpictos"){
source = 2;
category = 0;
}else if($scope.source == "arasaac"){
source = 3;
}
request = config.backend + '/sup/' + supervisor.id +
'/pic_fromSearch/'+$scope.srch_term_picto+'/category/'+category+
......@@ -352,7 +405,7 @@ dashboardControllers.controller('AddPictoCtrl', function (
// Add Search to breadcrumbs
if (!$scope.onlyOwn){
if($scope.breadcrumbs[$scope.breadcrumbs.length-1].id != 999){
if($scope.breadcrumbs[$scope.breadcrumbs.length-1].id != 999 && $scope.source == "symbolstx"){
$scope.breadcrumbs.push({
id: 999,
exp: "filter",
......
......@@ -330,7 +330,6 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
new_id_pic: pictoId
})
.success(function (studentPicto) {
console.log(JSON.stringify(studentPicto));
$scope.loadPictos();
// notify
......@@ -352,7 +351,6 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
// Adds a new pictogram
//
$scope.open_add = function (col, row) {
console.log(col + " " +row);
var modalInstance = $modal.open({
animation: true,
templateUrl: 'modules/student/views/addpicto.html',
......@@ -389,7 +387,6 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
}
})
.success(function (studentPicto) {
console.log(studentPicto);
placePicto(studentPicto);
io.socket.post('/stu/vocabulary', {
......
......@@ -117,14 +117,14 @@ dashboardControllers.controller('StudentReportsCtrl', function StudentReportsCtr
"broken":0, "null":0
};
$scope.method_chart_dates = []; // [2010-02....]
$scope.error_rate_rate = []; // [33.3, ...]
$scope.average_time_trie = []; // [3, 4,...] seconds
$scope.average_time_pictos = [];
$scope.vocab_size = [];
$scope.method_chart_dates=[[]];
$scope.error_rate_rate = [[]];
$scope.average_time_trie = [[]];
$scope.average_time_pictos = [[]];
$scope.vocab_size = [[]];
$scope.vocab_size_aux = [];
$scope.phrase_average_time= [];
$scope.phrase_average_size = [];
$scope.phrase_average_time = [[]];
$scope.phrase_average_size = [[]];
if(selected_method.class === "method-opt"){
//check the selected method
......@@ -139,29 +139,13 @@ dashboardControllers.controller('StudentReportsCtrl', function StudentReportsCtr
}
//There is a method selected
//Get the selected method/s instructions by date
$scope.method_chart_dates=[[]];
$scope.error_rate_rate = [[]];
$scope.average_time_trie = [[]];
$scope.average_time_pictos = [[]];
$scope.vocab_size = [[]];
$scope.phrase_average_time = [[]];
$scope.phrase_average_size = [[]];
for(var i=0; i < $scope.statistic_methods.length; i++){
for(var j=0; j < $scope.statistic_methods[i].instructions.length; j++){
if(new Date($scope.statistic_methods[i].instructions[j].begin).getTime() > $scope.reportDateSince.getTime()
&& new Date($scope.statistic_methods[i].instructions[j].begin).getTime() < $scope.reportDateTo.getTime()){
//llamar a la funcion estadisticas con esta instruccion
var statistics = statistics_instruction(j, i);
$scope.error_rate_rate[0].push(statistics[7]);
$scope.average_time_trie[0].push(statistics[8]);
$scope.average_time_pictos[0].push(statistics[9]);
$scope.vocab_size[0].push(statistics[10]);
$scope.phrase_average_time[0].push(statistics[11]);
$scope.phrase_average_size[0].push(statistics[12]);
$scope.method_chart_dates[0].push(moment($scope.statistic_methods[i].instructions[j].begin).format("YYYY-MM-DD"));
// $scope.error_rate_rate[0].push(statistics_instruction(j, i)[2].error_rate);
// $scope.error_rate_dates[0].push(moment($scope.statistic_methods[i].instructions[j].begin).format("YYYY-MM-DD"));
}
}
}
......@@ -184,14 +168,6 @@ dashboardControllers.controller('StudentReportsCtrl', function StudentReportsCtr
if(new Date($scope.statistic_methods[0].instructions[j].begin).getTime() > $scope.reportDateSince.getTime()
&& new Date($scope.statistic_methods[0].instructions[j].begin).getTime() < $scope.reportDateTo.getTime()){
var statistics = statistics_instruction(j, 0);
$scope.error_rate_rate.push(statistics[1]);
$scope.method_chart_dates.push(statistics[0]);
$scope.average_time_trie.push(statistics[2]);
$scope.average_time_pictos.push(statistics[3]);
$scope.vocab_size.push(statistics[4]);
$scope.phrase_average_time.push(statistics[5]);
$scope.phrase_average_size.push(statistics[6]);
}
}
}
......@@ -359,24 +335,8 @@ dashboardControllers.controller('StudentReportsCtrl', function StudentReportsCtr
* Instruction selected
* method_pos is the position of the method in $scope.statistic_methods
* instruction_pos is the position of the instruction in $scope.statistic_methods
* return instruction_statistic [
[tries dates],
[tries error rate],
[tries average time],
[average_time_between_pictos_ws],
[vocab_size_ws],
[phrase_average_build_time],
[phrase_average_size],
[instruction error_rate],
[instruction tries average time],
[instruction average_time_between_pictos],
[instruction_vocab_size],
[instruction_phrase_average_build_time],
[instruction_phrase_average_size]
]
*/
function statistics_instruction(instruction_pos, method_pos){
var instruction_statistic = [[],[], [],[],[],[],[], 0, 0, 0, 0,0,0];
var working_sessions=[];
//Get the selected instruction's working sessions by date
......@@ -389,9 +349,6 @@ dashboardControllers.controller('StudentReportsCtrl', function StudentReportsCtr
}
}
var instruction_error_rate = 0;
var instruction_tries_average_time = 0;
var instruction_pictos_average_time = 0;
var instruction_phrase_average_size = 0;
var instruction_phrase_average_build_time = 0;
for(var i=0; i < working_sessions.length; i++){
......@@ -438,7 +395,6 @@ dashboardControllers.controller('StudentReportsCtrl', function StudentReportsCtr
if(working_sessions[i].tries[j].actions.length > 0){
var average_time_pictos_action = 0;
var phrase_average_size_action = 0;
var before = moment(new Date(working_sessions[i].tries[j].actions[0].timestamp),"DD/MM/YYYY HH:mm:ss");
for(var k = 1; k < working_sessions[i].tries[j].actions.length; k++){
......@@ -468,42 +424,27 @@ dashboardControllers.controller('StudentReportsCtrl', function StudentReportsCtr
miliseconds = moment.duration(dif).asMilliseconds();
phrase_average_build_time += miliseconds;
}
phrase_average_size += count_pictos;
}
}
average_time_pictos_ws += average_time_pictos_action / working_sessions[i].tries[j].actions.length;
}
}
$scope.tries_count["total"]+=working_sessions[i].tries.length;
error_rate = success / working_sessions[i].tries.length;
instruction_error_rate += error_rate;
tries_average_time = tries_average_time / working_sessions[i].tries.length; //average time per trie per ws
instruction_tries_average_time += tries_average_time;
average_time_pictos_ws = average_time_pictos_ws / working_sessions[i].tries.length;
instruction_pictos_average_time += average_time_pictos_ws;
phrase_average_build_time = phrase_average_build_time / working_sessions[i].tries.length; //milliseconds
instruction_phrase_average_build_time += phrase_average_build_time; //milliseconds
phrase_average_size = phrase_average_size / working_sessions[i].tries.length;
instruction_phrase_average_size += phrase_average_size;
instruction_statistic[0].push(moment(working_sessions[i].begin).format("YYYY-MM-DD")); //https://github.com/moment/moment/issues/1407
instruction_statistic[1].push(round((1-error_rate) * 100, 2));
instruction_statistic[2].push(round(moment.duration(tries_average_time).asSeconds(),2));
instruction_statistic[3].push(round(moment.duration(average_time_pictos_ws).asSeconds(), 2));
instruction_statistic[4].push($scope.vocab_size_aux.length);
instruction_statistic[5].push(round(moment.duration(phrase_average_build_time).asSeconds(),2));
instruction_statistic[6].push(phrase_average_size);
phrase_average_build_time = phrase_average_build_time / success; //milliseconds
phrase_average_size = phrase_average_size / success;
$scope.method_chart_dates[0].push(moment(working_sessions[i].begin).format("YYYY-MM-DD")); //https://github.com/moment/moment/issues/1407
$scope.error_rate_rate[0].push(round((1-error_rate) * 100, 2));
$scope.average_time_trie[0].push(round(moment.duration(tries_average_time).asSeconds(),2));
$scope.average_time_pictos[0].push(round(moment.duration(average_time_pictos_ws).asSeconds(), 2));
$scope.vocab_size[0].push($scope.vocab_size_aux.length);
$scope.phrase_average_time[0].push(round(moment.duration(phrase_average_build_time).asSeconds(),2));
$scope.phrase_average_size[0].push(phrase_average_size);
}
instruction_statistic[7] = round(((1 - instruction_error_rate) / working_sessions.length) * 100, 2);
instruction_statistic[8] = round(moment.duration(instruction_tries_average_time / working_sessions.length ).asSeconds() , 2);
instruction_statistic[9] = round(moment.duration(instruction_pictos_average_time / working_sessions.length ).asSeconds(), 2);
instruction_statistic[10] = $scope.vocab_size_aux.length;
instruction_statistic[11] = round(moment.duration(instruction_phrase_average_build_time / working_sessions.length ).asSeconds(), 2);
instruction_statistic[12] = round(instruction_phrase_average_size / working_sessions.length, 2);
return instruction_statistic;
}
function round(number, places) {
......
......@@ -21,6 +21,9 @@
<button class="btn btn-default" btn-radio="'symbolstx'" ng-model="source" ng-click="open_category_from_bc('0')">
<span class="glyphicon glyphicon-th"></span> SymbolStix
</button>
<button class="btn btn-default" btn-radio="'arasaac'" ng-model="source" ng-click="load_arasaac_pictos()">
<i class="fa fa-th" aria-hidden="true"></i> Arasaac
</button>
<button class="btn btn-default" btn-radio="'ownpictos'" ng-model="source" ng-click="load_own_pictos()">
<span class="glyphicon glyphicon-picture"></span> {{ 'own_pictos' | translate }}
</button>
......@@ -72,6 +75,13 @@
<!-- Collections row -->
<div class="row">
<div id="arasaac_agreement" class="col-md-12" ng-show="showArasaacLicense && source == 'arasaac'">
<h2><small>
Los símbolos pictográficos utilizados en esta sección son propiedad de <b>CATEDU</b> (<a href="http://arasaac.org/">Arasaac</a>) bajo licencia Creative Commons y han sido creados por Sergio Palao.
<br>Para usarlos deberá aceptar la licencia de uso haciendo clic sobre el botón importar.</small>
</h2>
<button class="btn btn-primary" ng-click="accept_arasaac()">Importar</button>
</div>
<!-- Collections -->
<div id="collections" class="col-md-12 category-collection"
......@@ -105,6 +115,9 @@
</div><!-- /modal-body -->
<div class="modal-footer">
<div id="arasaac_license" ng-show="source == 'arasaac'">
<p class="small">Los símbolos pictográficos utilizados son propiedad de CATEDU (<a href="http://arasaac.org/">Arasaac</a>) bajo licencia Creative Commons y han sido creados por Sergio Palao</p>
</div>
<button class="btn btn-success pull-left" ng-show="source == 'ownpictos'" ngf-select ng-model="picFile" accept="image/*" ngf-change="addOwnPicto()">
<i class="fa fa-folder-open" aria-hidden="true"></i> {{ 'new_img' | translate }}
</button>
......
......@@ -33,6 +33,7 @@ dashboardControllers.controller('SupervisorCtrl', function SupervisorCtrl(
$scope.user.lang = user.lang;
$scope.user.isSupAdmin = user.isSupAdmin;
$scope.user.isTutor = user.isTutor;
$scope.user.arasaacLicense = user.arasaacLicense;
// Link to setup
$scope.setup = function(){
......
......@@ -75,6 +75,7 @@ module.exports.policies = {
categories: ['tokenAuth'],
fromcategory: ['tokenAuth'],
fromSymbolStx: ['tokenAuth'],
fromArasaac: ['tokenAuth'],
fromCatSubcat: ['tokenAuth'],
fromSearch: ['tokenAuth']
},
......@@ -134,6 +135,7 @@ module.exports.policies = {
change_password: true,
request_change_password: true,
activate: true,
accept_arasaac: ['tokenAuth'],
upload: ['tokenAuth'],
subscribe: ['tokenAuth'],
unsubscribe: ['tokenAuth'],
......
......@@ -107,10 +107,12 @@ module.exports.routes = {
'GET /sup/:id/pic_categories/:id_cat': 'PictoController.categories',
'GET /sup/:id/pic_fromcategory/:id_cat': 'PictoController.fromcategory',
'GET /sup/:id/pic_fromSymbolStx/page/:page/limit/:limit': 'PictoController.fromSymbolStx',
'GET /sup/:id/pic_fromArasaac/page/:page/limit/:limit': 'PictoController.fromArasaac',
'GET /sup/:id/pic_fromCatSubcat/category/:id_cat/page/:page/limit/:limit': 'PictoController.fromCatSubcat',
'GET /sup/:id/pic_fromSearch/:text/category/:id_cat/source/:source': 'PictoController.fromSearch',
'GET /sup/email/:email': 'SupervisorController.getByEmail',
'GET /sup/changepass/:email': 'SupervisorController.request_change_password',
'GET /sup/arasaac_license/:id': 'SupervisorController.accept_arasaac',
'PUT /sup/changepass': 'SupervisorController.change_password',
'PUT /sup/:id': 'SupervisorController.update',
'POST /sup': 'SupervisorController.create',
......
......@@ -499,7 +499,7 @@ function toSqlDate(date) {
('00' + date.getDate()).slice(-2) + ' ' +
('00' + date.getHours()).slice(-2) + ':' +
('00' + date.getMinutes()).slice(-2) + ':' +
('00' + date.getSeconds()).slice(-2) + "." +
('00' + date.getSeconds()).slice(-2) + '.' +
('00' + date.getMilliseconds()).slice(-3);
return date;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment