diff --git a/.eslintrc.js b/.eslintrc.js
index 4327cd6..f2c6764 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -12,6 +12,7 @@ module.exports = {
rules: {
},
globals: {
- "RecordRTC": true
+ "RecordRTC": true,
+ "Twilio": true
}
};
diff --git a/app/components/audio-recorder/styles.styl b/app/components/audio-recorder/styles.styl
index 701aefd..3864143 100644
--- a/app/components/audio-recorder/styles.styl
+++ b/app/components/audio-recorder/styles.styl
@@ -14,7 +14,10 @@
.btn:hover
background: rgba(off-white, 1)
-.btn:active
- background: hot-pink
- opacity: 1
+.record-button
+ color: slate
+
+.record-button:active
color: off-white
+ background: rgba(red, 0.6)
+ opacity: 1
diff --git a/app/components/audio-recorder/template.hbs b/app/components/audio-recorder/template.hbs
index f833fc2..dbe9b2f 100644
--- a/app/components/audio-recorder/template.hbs
+++ b/app/components/audio-recorder/template.hbs
@@ -1,9 +1,10 @@
{{ui/icon-button
+ class='record-button'
loading=saving
disabled=saving
mouseDown=(action 'startRecording')
mouseUp=(action 'stopRecording')
- leftIcon="microphone"}}
+ leftIcon="circle"}}
{{#if hasAudio}}
{{ui/icon-button
diff --git a/app/components/communication/video-chat/component.js b/app/components/communication/video-chat/component.js
index 085a101..9a39ebe 100644
--- a/app/components/communication/video-chat/component.js
+++ b/app/components/communication/video-chat/component.js
@@ -4,7 +4,7 @@ const Video = Twilio.Video;
export default Ember.Component.extend({
startVideo() {
- const { token, identity } = this.get("twilioData");
+ const { token } = this.get("twilioData");
Video.connect(token, {name: "my-room"})
.then(room => {
@@ -15,8 +15,8 @@ export default Ember.Component.extend({
room.on('participantConnected', ::this.participantConnected);
room.on('participantDisconnected', ::this.participantDisconnected);
- room.once('disconnected', error => room.participants.forEach(::this.participantDisconnected));
- }, e => console.log(e));
+ room.once('disconnected', () => room.participants.forEach(::this.participantDisconnected));
+ });
},
attachTracks(tracks, container) {
diff --git a/app/components/conversation-group/component.js b/app/components/conversation-group/component.js
index 473ed4e..85d7520 100644
--- a/app/components/conversation-group/component.js
+++ b/app/components/conversation-group/component.js
@@ -1,7 +1,6 @@
import Ember from 'ember';
-import computed from 'ember-computed-decorators';
-const { isPresent, computed: { alias, sort, gt } } = Ember;
+const { computed: { alias, sort, gt } } = Ember;
export default Ember.Component.extend({
sortAsc: ["position:asc"],
diff --git a/app/components/conversation-group/styles.styl b/app/components/conversation-group/styles.styl
index eca0332..05ae7b8 100644
--- a/app/components/conversation-group/styles.styl
+++ b/app/components/conversation-group/styles.styl
@@ -1,6 +1,9 @@
&
margin-top: 3em
+.conversation-container
+ padding: 0 2em
+
.create-conversation
width: 100%
padding: 1em
diff --git a/app/components/flash-card-group/component.js b/app/components/flash-card-group/component.js
index d5aebf0..f9d7897 100644
--- a/app/components/flash-card-group/component.js
+++ b/app/components/flash-card-group/component.js
@@ -1,11 +1,10 @@
import Ember from 'ember';
-import computed from 'ember-computed-decorators';
-const { isPresent, computed: { alias, sort, gt } } = Ember;
+const { computed: { alias, sort, gt } } = Ember;
export default Ember.Component.extend({
classNames: ['card-1'],
-
+
sortAsc: ["position:asc"],
sortedFlashCards: sort('model.activeFlashCards', 'sortAsc'),
flashCardCount: alias("sortedFlashCards.length"),
diff --git a/app/components/flash-card/component.js b/app/components/flash-card/component.js
index abcd94f..4fe660c 100644
--- a/app/components/flash-card/component.js
+++ b/app/components/flash-card/component.js
@@ -1,6 +1,5 @@
import Ember from 'ember';
import _ from 'lodash';
-import computed from 'ember-computed-decorators';
const TONE_REGEX = /([aeiouAEIOU][1234])/g;
@@ -56,10 +55,6 @@ const TONE_MAPPING = {
"U4": "Ù"
};
-const {
- computed: { notEmpty }
-} = Ember;
-
export default Ember.Component.extend({
classNames: ['card-2', 'stretch'],
@@ -69,7 +64,7 @@ export default Ember.Component.extend({
},
actions: {
- processChange(str) {
+ processChange(model, str) {
const editor = this.$(".pinyinEditor")[0];
let cursorPosition = editor.selectionStart;
let newStr = str;
@@ -80,16 +75,16 @@ export default Ember.Component.extend({
cursorPosition = cursorPosition - matches.length;
}
- this.set("model.pinyin", newStr);
+ model.set("text", newStr);
- this.get("saveModel")(this.get("model"));
+ this.get("saveModel")(model);
Ember.run.scheduleOnce('afterRender', this, this.setSelection, editor, cursorPosition, cursorPosition);
},
- handleUpdate(key, str) {
- this.get("model").set(key, str);
- this.get("saveModel")(this.get("model"));
+ handleUpdate(model, str) {
+ model.set('text', str);
+ this.get("saveModel")(model);
}
}
});
diff --git a/app/components/flash-card/styles.styl b/app/components/flash-card/styles.styl
index 91e868b..02091e0 100644
--- a/app/components/flash-card/styles.styl
+++ b/app/components/flash-card/styles.styl
@@ -4,6 +4,8 @@
min-width: 18em
width: 18em
margin: 0.5em
+ border-bottom-left-radius: 10px
+ border-bottom-right-radius: 10px
.inputContainer
margin-left: 1em
@@ -20,8 +22,6 @@ textarea
background: rgba(white, 0.75)
.fieldsContainer
- // margin: 0.5em
-
+below(700px)
flex-direction: column
diff --git a/app/components/flash-card/template.hbs b/app/components/flash-card/template.hbs
index 322488f..ae305cf 100644
--- a/app/components/flash-card/template.hbs
+++ b/app/components/flash-card/template.hbs
@@ -15,9 +15,9 @@
- {{one-way-textarea model.chinese
+ {{one-way-textarea model.chinese.text
placeholder='汉语...'
- update=(action "handleUpdate" "chinese")
+ update=(action "handleUpdate" model.chinese)
autocomplete="off"
autocorrect="off"
autocapitalize="off"
@@ -25,10 +25,10 @@
- {{one-way-textarea model.pinyin
+ {{one-way-textarea model.pinyin.text
placeholder='Pinyin...'
class="pinyinEditor"
- update=(action 'processChange')
+ update=(action 'processChange' model.pinyin)
autocomplete="off"
autocorrect="off"
autocapitalize="off"
@@ -36,9 +36,9 @@
- {{one-way-textarea model.english
+ {{one-way-textarea model.english.text
placeholder='English...'
- update=(action "handleUpdate" "english")
+ update=(action "handleUpdate" model.english)
autocomplete="off"
autocorrect="off"
autocapitalize="off"
@@ -47,7 +47,7 @@
- {{audio-recorder
+ {{audio-recorder
model=model
created=(action onAudioCreated model)}}
diff --git a/app/index.html b/app/index.html
index e2b628a..4c5f01a 100644
--- a/app/index.html
+++ b/app/index.html
@@ -12,11 +12,10 @@
-
-
-
+
+
{{content-for "head-footer"}}
diff --git a/app/models/conversation.js b/app/models/conversation.js
index 0a3f425..afff6c7 100644
--- a/app/models/conversation.js
+++ b/app/models/conversation.js
@@ -1,7 +1,7 @@
import DS from 'ember-data';
-import computed from 'ember-computed-decorators';
+import Ember from 'ember';
-const { empty, filterBy } = Ember.computed;
+const { filterBy, empty } = Ember.computed;
export default DS.Model.extend({
title: DS.attr('string'),
diff --git a/app/models/flash-card.js b/app/models/flash-card.js
index 7b0463d..58ad7df 100644
--- a/app/models/flash-card.js
+++ b/app/models/flash-card.js
@@ -1,9 +1,10 @@
import DS from 'ember-data';
export default DS.Model.extend({
- pinyin: DS.attr('string'),
- chinese: DS.attr('string'),
- english: DS.attr('string'),
+ pinyin: DS.belongsTo('translation', {inverse: null}),
+ chinese: DS.belongsTo('translation', {inverse: null}),
+ english: DS.belongsTo('translation', {inverse: null}),
+
audioUrl: DS.attr('string'),
ts: DS.attr('number'),
position: DS.attr('number', {defaultValue: 1}),
diff --git a/app/models/translation.js b/app/models/translation.js
new file mode 100644
index 0000000..6729906
--- /dev/null
+++ b/app/models/translation.js
@@ -0,0 +1,7 @@
+import DS from 'ember-data';
+
+export default DS.Model.extend({
+ text: DS.attr('string'),
+ lang: DS.attr('string'),
+ flashCard: DS.belongsTo('flash-card', {inverse: null})
+});
diff --git a/app/routes/lesson.js b/app/routes/lesson.js
index 6aff8b2..df32d4c 100644
--- a/app/routes/lesson.js
+++ b/app/routes/lesson.js
@@ -1,8 +1,6 @@
import Ember from 'ember';
import firebase from 'firebase';
import { v4 as uuid } from 'uuid';
-import moment from 'moment';
-import _ from 'lodash';
export default Ember.Route.extend({
setupController(controller, model) {
@@ -21,14 +19,27 @@ export default Ember.Route.extend({
const record = await this.store.findRecord('lesson', params.id)
.catch(() => {
- const lesson = this.store.createRecord('lesson', {id:params.id, date:new Date()}),
- conversation = this.store.createRecord('conversation', {lesson}),
- flashCard = this.store.createRecord('flash-card', {conversation});
+
+ const chinese = this.store.createRecord('translation', { flashCard, lang: 'chinese' });
+ const pinyin = this.store.createRecord('translation', { flashCard, lang: 'pinyin' });
+ const english = this.store.createRecord('translation', { flashCard, lang: 'english' });
+
+ const lesson = this.store.createRecord('lesson', {id:params.id, date:new Date()});
+ const conversation = this.store.createRecord('conversation', {lesson});
+
+ const flashCard = this.store
+ .createRecord('flash-card', {
+ conversation,
+ chinese,
+ pinyin,
+ english
+ });
return lesson.save()
- .then(lesson => conversation.save())
- .then(conversation => flashCard.save())
- .then(flashCard => lesson);
+ .then(() => conversation.save())
+ .then(() => flashCard.save())
+ .then(() => Ember.RSVP.all([chinese.save(), pinyin.save(), english.save()]))
+ .then(() => lesson);
});
return {
@@ -70,11 +81,21 @@ export default Ember.Route.extend({
const conversation = this.store
.createRecord('conversation', { lesson, position: newPosition });
+ const chinese = this.store.createRecord('translation', { flashCard, lang: 'chinese' });
+ const pinyin = this.store.createRecord('translation', { flashCard, lang: 'pinyin' });
+ const english = this.store.createRecord('translation', { flashCard, lang: 'english' });
+
const flashCard = this.store
- .createRecord('flash-card', { conversation });
+ .createRecord('flash-card', {
+ conversation,
+ chinese,
+ pinyin,
+ english
+ });
await conversation.save();
await flashCard.save();
+ await Ember.RSVP.all([chinese.save(), pinyin.save(), english.save()]);
await lesson.save();
},
@@ -97,17 +118,30 @@ export default Ember.Route.extend({
},
saveModel(model) {
- model.save();
+ if(model.then !== undefined) {
+ model.then(res => res.save());
+ } else {
+ model.save();
+ }
},
async destroyFlashCard(conversation, flashCard) {
flashCard.deleteRecord();
+ const chinese = await flashCard.get('chinese');
+ const pinyin = await flashCard.get('pinyin');
+ const english = await flashCard.get('english');
+
+ chinese.deleteRecord();
+ pinyin.deleteRecord();
+ english.deleteRecord();
+
if(conversation.get("isEmpty")) {
conversation.deleteRecord();
}
await flashCard.save();
+ await Ember.RSVP.all([chinese.save(), pinyin.save(), english.save()]);
await conversation.save();
},
@@ -144,10 +178,21 @@ export default Ember.Route.extend({
newPosition = 1;
}
+ const chinese = this.store.createRecord('translation', { flashCard, lang: 'chinese' });
+ const pinyin = this.store.createRecord('translation', { flashCard, lang: 'pinyin' });
+ const english = this.store.createRecord('translation', { flashCard, lang: 'english' });
+
const flashCard = this.store
- .createRecord('flash-card', { conversation, position: newPosition });
+ .createRecord('flash-card', {
+ conversation,
+ position: newPosition,
+ chinese,
+ pinyin,
+ english
+ });
await flashCard.save();
+ await Ember.RSVP.all([chinese.save(), pinyin.save(), english.save()]);
await conversation.save();
}
}
diff --git a/tests/.eslintrc.js b/tests/.eslintrc.js
index fbf2555..8fea8da 100644
--- a/tests/.eslintrc.js
+++ b/tests/.eslintrc.js
@@ -1,5 +1,9 @@
module.exports = {
env: {
embertest: true
+ },
+ globals: {
+ "RecordRTC": true,
+ "Twilio": true
}
};
diff --git a/tests/integration/components/communication/video-chat/component-test.js b/tests/integration/components/communication/video-chat/component-test.js
deleted file mode 100644
index cd0028e..0000000
--- a/tests/integration/components/communication/video-chat/component-test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { moduleForComponent, test } from 'ember-qunit';
-import hbs from 'htmlbars-inline-precompile';
-
-moduleForComponent('communication/video-chat', 'Integration | Component | communication/video chat', {
- integration: true
-});
-
-test('it renders', function(assert) {
-
- // Set any properties with this.set('myProperty', 'value');
- // Handle any actions with this.on('myAction', function(val) { ... });
-
- this.render(hbs`{{communication/video-chat}}`);
-
- assert.equal(this.$().text().trim(), '');
-
- // Template block usage:
- this.render(hbs`
- {{#communication/video-chat}}
- template block text
- {{/communication/video-chat}}
- `);
-
- assert.equal(this.$().text().trim(), 'template block text');
-});
diff --git a/tests/integration/components/conversation-group/component-test.js b/tests/integration/components/conversation-group/component-test.js
deleted file mode 100644
index 54fd555..0000000
--- a/tests/integration/components/conversation-group/component-test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { moduleForComponent, test } from 'ember-qunit';
-import hbs from 'htmlbars-inline-precompile';
-
-moduleForComponent('conversation-group', 'Integration | Component | conversation group', {
- integration: true
-});
-
-test('it renders', function(assert) {
-
- // Set any properties with this.set('myProperty', 'value');
- // Handle any actions with this.on('myAction', function(val) { ... });
-
- this.render(hbs`{{conversation-group}}`);
-
- assert.equal(this.$().text().trim(), '');
-
- // Template block usage:
- this.render(hbs`
- {{#conversation-group}}
- template block text
- {{/conversation-group}}
- `);
-
- assert.equal(this.$().text().trim(), 'template block text');
-});
diff --git a/tests/integration/components/flash-card-group/component-test.js b/tests/integration/components/flash-card-group/component-test.js
deleted file mode 100644
index ce1651e..0000000
--- a/tests/integration/components/flash-card-group/component-test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { moduleForComponent, test } from 'ember-qunit';
-import hbs from 'htmlbars-inline-precompile';
-
-moduleForComponent('flash-card-group', 'Integration | Component | flash card group', {
- integration: true
-});
-
-test('it renders', function(assert) {
-
- // Set any properties with this.set('myProperty', 'value');
- // Handle any actions with this.on('myAction', function(val) { ... });
-
- this.render(hbs`{{flash-card-group}}`);
-
- assert.equal(this.$().text().trim(), '');
-
- // Template block usage:
- this.render(hbs`
- {{#flash-card-group}}
- template block text
- {{/flash-card-group}}
- `);
-
- assert.equal(this.$().text().trim(), 'template block text');
-});
diff --git a/tests/integration/components/flash-card/component-test.js b/tests/integration/components/flash-card/component-test.js
deleted file mode 100644
index ba170b3..0000000
--- a/tests/integration/components/flash-card/component-test.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { moduleForComponent, test } from 'ember-qunit';
-import hbs from 'htmlbars-inline-precompile';
-
-moduleForComponent('flash-card', 'Integration | Component | flash card', {
- integration: true
-});
-
-test('The index shows in reverse', function(assert) {
- this.render(hbs`{{flash-card total=10 index=0}}`);
- assert.equal(this.$('.index').text().trim(), '10.');
-});
diff --git a/tests/unit/controllers/lesson-test.js b/tests/unit/controllers/lesson-test.js
deleted file mode 100644
index 00f3651..0000000
--- a/tests/unit/controllers/lesson-test.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { moduleFor, test } from 'ember-qunit';
-
-moduleFor('controller:lesson', 'Unit | Controller | lesson', {
- // Specify the other units that are required for this test.
- // needs: ['controller:foo']
-});
-
-// Replace this with your real tests.
-test('it exists', function(assert) {
- let controller = this.subject();
- assert.ok(controller);
-});
diff --git a/tests/unit/models/flash-card-test.js b/tests/unit/models/flash-card-test.js
index fa7f6c6..bd8042c 100644
--- a/tests/unit/models/flash-card-test.js
+++ b/tests/unit/models/flash-card-test.js
@@ -2,7 +2,7 @@ import { moduleForModel, test } from 'ember-qunit';
moduleForModel('flash-card', 'Unit | Model | flash card', {
// Specify the other units that are required for this test.
- needs: ['model:lesson']
+ needs: ['model:conversation', 'model:translation']
});
test('it exists', function(assert) {
diff --git a/tests/unit/models/lesson-test.js b/tests/unit/models/lesson-test.js
index 03560fa..8b89994 100644
--- a/tests/unit/models/lesson-test.js
+++ b/tests/unit/models/lesson-test.js
@@ -2,7 +2,7 @@ import { moduleForModel, test } from 'ember-qunit';
moduleForModel('lesson', 'Unit | Model | lesson', {
// Specify the other units that are required for this test.
- needs: ['model:flash-card']
+ needs: ['model:conversation']
});
test('it exists', function(assert) {
diff --git a/tests/unit/models/translation-test.js b/tests/unit/models/translation-test.js
new file mode 100644
index 0000000..d679895
--- /dev/null
+++ b/tests/unit/models/translation-test.js
@@ -0,0 +1,12 @@
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('translation', 'Unit | Model | translation', {
+ // Specify the other units that are required for this test.
+ needs: ['model:flash-card']
+});
+
+test('it exists', function(assert) {
+ let model = this.subject();
+ // let store = this.store();
+ assert.ok(!!model);
+});