From ae849dc38cbe96fc4c7ae6469c29b3da4d94ae55 Mon Sep 17 00:00:00 2001 From: Joseph Atkins-Turkish Date: Mon, 25 Jul 2016 10:20:34 -0700 Subject: [PATCH 01/17] Prevent incorrect button presses on project settings form submission. --- ide/static/ide/js/KVtable.js | 7 ++++++- ide/templates/ide/project/settings.html | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ide/static/ide/js/KVtable.js b/ide/static/ide/js/KVtable.js index 3ec12d2d..7897e64d 100644 --- a/ide/static/ide/js/KVtable.js +++ b/ide/static/ide/js/KVtable.js @@ -52,7 +52,12 @@ CloudPebble.KVTable = function(table_elm, options) { .addClass('kv-value') .attr('type', opts.value_type) .attr('placeholder', key ? null : opts.value_placeholder)), - $('').append($(' + {% trans "A unique identifier for the app. Takes the format xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx, where x is any hexadecimal digit and y is one of 8, 9, A, or B" %} @@ -200,8 +200,8 @@
- - + +
From 89dc9d18f657903dfb5009434edac9d78a63efc1 Mon Sep 17 00:00:00 2001 From: Katharine Berry Date: Tue, 30 Aug 2016 10:38:03 -0700 Subject: [PATCH 02/17] Bump min verison to 4.0. --- bin/post_compile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/post_compile b/bin/post_compile index ba99e9ca..5b44c74c 100644 --- a/bin/post_compile +++ b/bin/post_compile @@ -9,7 +9,7 @@ echo "Downloading SDK 2" curl -o /tmp/pebblesdk2.tar.gz -L https://s3.amazonaws.com/assets.getpebble.com/sdk3/sdk-core/sdk-core-2.9.tar.bz2 echo "Downloading SDK 3" -curl -o /tmp/pebblesdk3.tar.gz -L https://s3.amazonaws.com/assets.getpebble.com/sdk3/beta/sdk-core-4.0-rc20.tar.bz2 +curl -o /tmp/pebblesdk3.tar.gz -L https://s3.amazonaws.com/assets.getpebble.com/sdk3/release/sdk-core-4.0.tar.bz2 echo "Downloading the toolchain" curl -o /tmp/arm-cs-tools.tar https://cloudpebble-vagrant.s3.amazonaws.com/arm-cs-tools-stripped.tar From 474b16b52a2e547ab980723b5e543fa367d84fcf Mon Sep 17 00:00:00 2001 From: Joseph Atkins-Turkish Date: Tue, 30 Aug 2016 12:51:25 -0700 Subject: [PATCH 03/17] Fix building native projects with old-style JS (#335) * Only replace `{{pkjs_entry_point}}` when `app_modern_multi_js`. * re-chain replaces * Don't give json to workers. --- ide/utils/sdk/sdk_scripts.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ide/utils/sdk/sdk_scripts.py b/ide/utils/sdk/sdk_scripts.py index 83c0cf9f..83254f5c 100644 --- a/ide/utils/sdk/sdk_scripts.py +++ b/ide/utils/sdk/sdk_scripts.py @@ -292,15 +292,14 @@ def build(ctx): if build_worker: worker_elf = '{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR) binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf}) - ctx.pbl_worker(source=ctx.path.ant_glob(['worker_src/c/**/*.c', 'src/js/**/*.json']), target=worker_elf) + ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/c/**/*.c'), target=worker_elf) else: binaries.append({'platform': p, 'app_elf': app_elf}) ctx.set_group('bundle') ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob(['src/pkjs/**/*.js', 'src/pkjs/**/*.json']), js_entry_file='src/pkjs/{{pkjs_entry}}') """ - - return wscript.replace('{{jshint}}', 'True' if jshint and not for_export else 'False').replace('{{pkjs_entry}}', project.pkjs_entry_point) + return wscript.replace('{{jshint}}', 'True' if jshint and not for_export else 'False').replace('{{pkjs_entry}}', project.pkjs_entry_point or '') def generate_wscript_file(project, for_export=False): From 77afac6915b668f7d56dfe11d35fae3aae5fc77b Mon Sep 17 00:00:00 2001 From: Joseph Atkins-Turkish Date: Tue, 30 Aug 2016 13:53:47 -0700 Subject: [PATCH 04/17] Allow running 4.0 apps on applite 3.12.2+ --- ide/static/ide/js/compile.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ide/static/ide/js/compile.js b/ide/static/ide/js/compile.js index 8e03e677..93a7bfcf 100644 --- a/ide/static/ide/js/compile.js +++ b/ide/static/ide/js/compile.js @@ -1,6 +1,7 @@ CloudPebble.Compile = (function() { var MINIMUM_SDK2_VERSION = "v2.9"; var MINIMUM_INSTALL_VERSION = "v4.0"; + var MINIMUM_APLITE_VERSION = "v3.12.2"; var COMPILE_SUCCESS_STATES = { 1: {english: gettext("Pending"), cls: "info", label: 'info'}, @@ -551,7 +552,14 @@ CloudPebble.Compile = (function() { console.log(version_string); // Make sure that we have the required version - but also assume that anyone who has the string 'test' // in their firmware version number (e.g. me) knows what they're doing. - var min_version = CloudPebble.ProjectInfo.sdk_version == '2'? MINIMUM_SDK2_VERSION : MINIMUM_INSTALL_VERSION; + var min_version; + if (CloudPebble.ProjectInfo.sdk_version == '2') { + min_version = MINIMUM_SDK2_VERSION; + } else if (SharedPebble.getPlatformName() == 'aplite') { + min_version = MINIMUM_APLITE_VERSION; + } else { + min_version = MINIMUM_INSTALL_VERSION; + } if(/test/.test(version_string) || compare_version_strings(version_string, min_version) >= 0) { var platform = Pebble.version_to_platform(version_info); var sizes = { From fc0eac91ba7532bf1a84394711552bb75f61482c Mon Sep 17 00:00:00 2001 From: Joseph Atkins-Turkish Date: Tue, 30 Aug 2016 15:09:19 -0700 Subject: [PATCH 05/17] Fix run button widths. --- ide/static/ide/css/ide.css | 18 ++++++++++++------ ide/templates/ide/project/compile.html | 8 ++++---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/ide/static/ide/css/ide.css b/ide/static/ide/css/ide.css index d534f89f..c5017e42 100644 --- a/ide/static/ide/css/ide.css +++ b/ide/static/ide/css/ide.css @@ -527,16 +527,22 @@ table.kv-table .kv-remove { margin-left: 110px; } -.compilation-pane #run-on-phone .btn, -.compilation-pane #run-on-qemu .btn, -.compilation-pane .build-buttons .btn { +.compilation-pane .compilation-buttons.two-buttons .btn { + width: 287px; + margin: 0 4px; +} + +.compilation-pane .compilation-buttons.three-buttons .btn{ + width: 188px; + margin-right: 9px; +} + +.compilation-pane .compilation-buttons.four-buttons .btn{ width: 137px; margin: 0 4px; } -.compilation-pane #run-on-phone .btn:last-of-type, -.compilation-pane #run-on-qemu .btn:last-of-type, -.compilation-pane .build-buttons .btn:last-child { +.compilation-pane .compilation-buttons .btn:last-child { margin-right: 0; } diff --git a/ide/templates/ide/project/compile.html b/ide/templates/ide/project/compile.html index 13479f7a..7d49cd96 100644 --- a/ide/templates/ide/project/compile.html +++ b/ide/templates/ide/project/compile.html @@ -18,7 +18,7 @@
-
+
@@ -26,14 +26,14 @@

-
+

-
+
@@ -57,7 +57,7 @@

{% trans 'Last build' %}


-
+
{% if project.project_type == 'package'%} From 25c4003c69312cebe8ccd15a6054bd71cccde37f Mon Sep 17 00:00:00 2001 From: Joseph Atkins-Turkish Date: Tue, 30 Aug 2016 16:40:45 -0700 Subject: [PATCH 06/17] _Correctly_ check the watch version. --- ide/static/ide/js/compile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ide/static/ide/js/compile.js b/ide/static/ide/js/compile.js index 93a7bfcf..26ab6846 100644 --- a/ide/static/ide/js/compile.js +++ b/ide/static/ide/js/compile.js @@ -553,15 +553,15 @@ CloudPebble.Compile = (function() { // Make sure that we have the required version - but also assume that anyone who has the string 'test' // in their firmware version number (e.g. me) knows what they're doing. var min_version; + var platform = Pebble.version_to_platform(version_info); if (CloudPebble.ProjectInfo.sdk_version == '2') { min_version = MINIMUM_SDK2_VERSION; - } else if (SharedPebble.getPlatformName() == 'aplite') { + } else if (platform == 'aplite') { min_version = MINIMUM_APLITE_VERSION; } else { min_version = MINIMUM_INSTALL_VERSION; } if(/test/.test(version_string) || compare_version_strings(version_string, min_version) >= 0) { - var platform = Pebble.version_to_platform(version_info); var sizes = { aplite: mLastBuild.sizes.aplite, basalt: mLastBuild.sizes.basalt, From 808820b1b28575d5064ea765b388ba8282ad459c Mon Sep 17 00:00:00 2001 From: Joseph Atkins-Turkish Date: Tue, 30 Aug 2016 17:08:22 -0700 Subject: [PATCH 07/17] Support aplite packages. --- ide/static/ide/js/cloudpebble.js | 2 +- ide/static/ide/js/settings.js | 4 ++-- ide/templates/ide/project/settings.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ide/static/ide/js/cloudpebble.js b/ide/static/ide/js/cloudpebble.js index ca0e5cfe..306c0633 100644 --- a/ide/static/ide/js/cloudpebble.js +++ b/ide/static/ide/js/cloudpebble.js @@ -25,7 +25,7 @@ CloudPebble.ProjectProperties = (function() { 'js_only': ['simplyjs', 'pebblejs', 'rocky'], 'is_runnable': ['native', 'pebblejs', 'simplyjs', 'rocky'], 'supports_message_keys': ['native', 'package'], - 'supports_sdk2': ['native', 'simplyjs', 'pebblejs'], + 'supports_aplite': ['native', 'package', 'simplyjs', 'pebblejs'], 'supports_jslint': ['native', 'package', 'pebblejs', 'rocky'] }; var obj = { diff --git a/ide/static/ide/js/settings.js b/ide/static/ide/js/settings.js index b490ee28..42b9e15f 100644 --- a/ide/static/ide/js/settings.js +++ b/ide/static/ide/js/settings.js @@ -22,8 +22,8 @@ CloudPebble.Settings = (function() { if (CloudPebble.ProjectInfo.type == 'package') { pane.find('.not-package').hide(); } - if(!(CloudPebble.ProjectProperties.supports_sdk2)) { - pane.find('.supports-sdk2').hide(); + if(!(CloudPebble.ProjectProperties.supports_aplite)) { + pane.find('.supports-aplite').hide(); } if(!(CloudPebble.ProjectProperties.supports_message_keys)) { pane.find('.supports-message-keys').hide(); diff --git a/ide/templates/ide/project/settings.html b/ide/templates/ide/project/settings.html index f8d9d80c..103f1dd7 100644 --- a/ide/templates/ide/project/settings.html +++ b/ide/templates/ide/project/settings.html @@ -28,7 +28,7 @@
-
+
{# Translators: "Aplite" is a platform name and should be left untranslated. #}
From 88a8937ff1c2589efdbe6967eb5faa1c975a694d Mon Sep 17 00:00:00 2001 From: Katharine Berry Date: Tue, 30 Aug 2016 17:51:09 -0700 Subject: [PATCH 08/17] Increase max length of target_platforms. --- ...eld_resourceidentifier_target_platforms.py | 177 ++++++++++++++++++ ide/models/files.py | 2 +- 2 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 ide/migrations/0051_auto__chg_field_resourceidentifier_target_platforms.py diff --git a/ide/migrations/0051_auto__chg_field_resourceidentifier_target_platforms.py b/ide/migrations/0051_auto__chg_field_resourceidentifier_target_platforms.py new file mode 100644 index 00000000..6d6b6e1d --- /dev/null +++ b/ide/migrations/0051_auto__chg_field_resourceidentifier_target_platforms.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Changing field 'ResourceIdentifier.target_platforms' + db.alter_column(u'ide_resourceidentifier', 'target_platforms', self.gf('django.db.models.fields.CharField')(max_length=100, null=True)) + + def backwards(self, orm): + + # Changing field 'ResourceIdentifier.target_platforms' + db.alter_column(u'ide_resourceidentifier', 'target_platforms', self.gf('django.db.models.fields.CharField')(max_length=30, null=True)) + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ide.buildresult': { + 'Meta': {'object_name': 'BuildResult'}, + 'finished': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'builds'", 'to': "orm['ide.Project']"}), + 'started': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + 'uuid': ('django.db.models.fields.CharField', [], {'default': "'db7a8764-aaf8-453b-ba1a-a7a0da137336'", 'max_length': '36'}) + }, + 'ide.buildsize': { + 'Meta': {'object_name': 'BuildSize'}, + 'binary_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sizes'", 'to': "orm['ide.BuildResult']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'platform': ('django.db.models.fields.CharField', [], {'max_length': '20'}), + 'resource_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'total_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'worker_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ide.dependency': { + 'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'Dependency'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependencies'", 'to': "orm['ide.Project']"}), + 'version': ('django.db.models.fields.CharField', [], {'max_length': '2000'}) + }, + 'ide.project': { + 'Meta': {'object_name': 'Project'}, + 'app_capabilities': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'app_company_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'app_is_hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'app_is_shown_on_communication': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'app_is_watchface': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'app_jshint': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'app_keys': ('django.db.models.fields.TextField', [], {'default': "'{}'"}), + 'app_keywords': ('django.db.models.fields.TextField', [], {'default': "'[]'"}), + 'app_long_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'app_modern_multi_js': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'app_platforms': ('django.db.models.fields.TextField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'app_short_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'app_uuid': ('django.db.models.fields.CharField', [], {'default': "'72886d2e-9a66-47fc-a852-4044128bacbe'", 'max_length': '36', 'null': 'True', 'blank': 'True'}), + 'app_version_label': ('django.db.models.fields.CharField', [], {'default': "'1.0'", 'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'github_branch': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'github_hook_build': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'github_hook_uuid': ('django.db.models.fields.CharField', [], {'max_length': '36', 'null': 'True', 'blank': 'True'}), + 'github_last_commit': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'github_last_sync': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'github_repo': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'optimisation': ('django.db.models.fields.CharField', [], {'default': "'s'", 'max_length': '1'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'project_dependencies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ide.Project']", 'symmetrical': 'False'}), + 'project_type': ('django.db.models.fields.CharField', [], {'default': "'native'", 'max_length': '10'}), + 'sdk_version': ('django.db.models.fields.CharField', [], {'default': "'2'", 'max_length': '6'}) + }, + 'ide.resourcefile': { + 'Meta': {'unique_together': "(('project', 'file_name'),)", 'object_name': 'ResourceFile'}, + 'file_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_menu_icon': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'kind': ('django.db.models.fields.CharField', [], {'max_length': '9'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'resources'", 'to': "orm['ide.Project']"}) + }, + 'ide.resourceidentifier': { + 'Meta': {'object_name': 'ResourceIdentifier'}, + 'character_regex': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'compatibility': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'memory_format': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'resource_file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['ide.ResourceFile']"}), + 'resource_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'space_optimisation': ('django.db.models.fields.CharField', [], {'max_length': '7', 'null': 'True', 'blank': 'True'}), + 'storage_format': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'blank': 'True'}), + 'target_platforms': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'tracking': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ide.resourcevariant': { + 'Meta': {'unique_together': "(('resource_file', 'tags'),)", 'object_name': 'ResourceVariant'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_legacy': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'resource_file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'variants'", 'to': "orm['ide.ResourceFile']"}), + 'tags': ('django.db.models.fields.CommaSeparatedIntegerField', [], {'max_length': '50', 'blank': 'True'}) + }, + 'ide.sourcefile': { + 'Meta': {'unique_together': "(('project', 'file_name', 'target'),)", 'object_name': 'SourceFile'}, + 'file_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'folded_lines': ('django.db.models.fields.TextField', [], {'default': "'[]'"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'source_files'", 'to': "orm['ide.Project']"}), + 'target': ('django.db.models.fields.CharField', [], {'default': "'app'", 'max_length': '10'}) + }, + 'ide.templateproject': { + 'Meta': {'object_name': 'TemplateProject', '_ormbases': ['ide.Project']}, + u'project_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ide.Project']", 'unique': 'True', 'primary_key': 'True'}), + 'template_kind': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}) + }, + 'ide.usergithub': { + 'Meta': {'object_name': 'UserGithub'}, + 'avatar': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'nonce': ('django.db.models.fields.CharField', [], {'max_length': '36', 'null': 'True', 'blank': 'True'}), + 'token': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'github'", 'unique': 'True', 'primary_key': 'True', 'to': u"orm['auth.User']"}), + 'username': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}) + }, + 'ide.usersettings': { + 'Meta': {'object_name': 'UserSettings'}, + 'accepted_terms': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'autocomplete': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + 'keybinds': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '20'}), + 'tab_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '2'}), + 'theme': ('django.db.models.fields.CharField', [], {'default': "'cloudpebble'", 'max_length': '50'}), + 'use_spaces': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}), + 'whats_new': ('django.db.models.fields.PositiveIntegerField', [], {'default': '24'}) + } + } + + complete_apps = ['ide'] \ No newline at end of file diff --git a/ide/models/files.py b/ide/models/files.py index b24482b5..dabf0216 100644 --- a/ide/models/files.py +++ b/ide/models/files.py @@ -175,7 +175,7 @@ class ResourceIdentifier(IdeModel): character_regex = models.CharField(max_length=100, blank=True, null=True) tracking = models.IntegerField(blank=True, null=True) compatibility = models.CharField(max_length=10, blank=True, null=True) - target_platforms = models.CharField(max_length=30, null=True, blank=True, default=None) + target_platforms = models.CharField(max_length=100, null=True, blank=True, default=None) MEMORY_FORMATS = ( ('Smallest', _('Smallest')), From db162e0f5039f84e9053cbada2b74de0affe7aad Mon Sep 17 00:00:00 2001 From: Joseph Atkins-Turkish Date: Wed, 31 Aug 2016 10:56:47 -0700 Subject: [PATCH 09/17] Fix and test pebblejs resources. --- ide/tests/test_project_assembly.py | 10 +++++++--- ide/utils/sdk/project_assembly.py | 8 ++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ide/tests/test_project_assembly.py b/ide/tests/test_project_assembly.py index 1c87492f..74258f6b 100644 --- a/ide/tests/test_project_assembly.py +++ b/ide/tests/test_project_assembly.py @@ -118,11 +118,15 @@ def test_native_SDK3_project_with_worker(self): def test_pebblejs(self): """ Check that an pebblejs project looks right """ with self.get_tree(type='pebblejs'): - pass - # We can't really expect anything specific from pebblejs because, in theory, it can change under our feet. - # But we can check things which will always be there: a doc.html and an appinfo.js + self.add_resource('image.png') + self.add_file('blah.js') + # We can't really expect an exact tree layout from pebblejs because, in theory, it can change under our feet. + # But we can check things which will always be there self.assertTrue(self.tree['appinfo.json']) self.assertTrue(self.tree['doc.html']) + self.assertTrue(self.tree['resources']['images']['image.png']) + self.assertTrue(self.tree['src']['js']['app.js']) + self.assertTrue(self.tree['src']['js']['blah.js']) def test_package(self): diff --git a/ide/utils/sdk/project_assembly.py b/ide/utils/sdk/project_assembly.py index 6634c359..c48c23ff 100644 --- a/ide/utils/sdk/project_assembly.py +++ b/ide/utils/sdk/project_assembly.py @@ -53,12 +53,12 @@ def assemble_resource_directories(project, base_dir): os.makedirs(os.path.join(resource_path, 'data')) -def assemble_resources(resource_path, resources, type_restrictions=None): +def assemble_resources(base_dir, resource_path, resources, type_restrictions=None): """ Copy all the project's resources to a path, optionally filtering by type. """ for f in resources: if type_restrictions and f.kind not in type_restrictions: continue - target_dir = os.path.abspath(os.path.join(resource_path, ResourceFile.DIR_MAP[f.kind])) + target_dir = os.path.abspath(os.path.join(base_dir, resource_path, ResourceFile.DIR_MAP[f.kind])) f.copy_all_variants_to_dir(target_dir) @@ -71,7 +71,7 @@ def assemble_project(project, base_dir, build_result=None): assemble_source_files(project, base_dir) if project.project_type != 'rocky': assemble_resource_directories(project, base_dir) - assemble_resources(os.path.join(base_dir, project.resources_path), resources) + assemble_resources(base_dir, project.resources_path, resources) with open(os.path.join(base_dir, 'wscript'), 'w') as wscript: wscript.write(generate_wscript_file(project)) with open(os.path.join(base_dir, 'pebble-jshintrc'), 'w') as jshint: @@ -84,7 +84,7 @@ def assemble_project(project, base_dir, build_result=None): assemble_resource_directories(project, base_dir) shutil.rmtree(base_dir) shutil.copytree(settings.PEBBLEJS_ROOT, base_dir) - assemble_resources(project.resources_path, resources, type_restrictions=('png', 'bitmap')) + assemble_resources(base_dir, project.resources_path, resources, type_restrictions=('png', 'bitmap')) assemble_source_files(project, base_dir) # All projects have a manifest From e54fa8e25ec8448d1b68fa040a52cfcd86a30578 Mon Sep 17 00:00:00 2001 From: Joseph Atkins-Turkish Date: Tue, 16 Aug 2016 17:46:28 -0700 Subject: [PATCH 10/17] initial progress on publishedMedia --- ide/static/ide/css/ide.css | 12 +- ide/static/ide/js/cloudpebble.js | 1 + ide/static/ide/js/dependencies.js | 2 +- ide/static/ide/js/published_media.js | 152 ++++++++++++++++++ ide/static/ide/js/resources.js | 7 +- ide/static/ide/js/sidebar.js | 1 + ide/templates/ide/project.html | 3 + .../ide/project/published_media.html | 62 +++++++ ide/templates/ide/project/resource.html | 8 +- 9 files changed, 239 insertions(+), 9 deletions(-) create mode 100644 ide/static/ide/js/published_media.js create mode 100644 ide/templates/ide/project/published_media.html diff --git a/ide/static/ide/css/ide.css b/ide/static/ide/css/ide.css index c5017e42..bc009eea 100644 --- a/ide/static/ide/css/ide.css +++ b/ide/static/ide/css/ide.css @@ -647,7 +647,7 @@ table.build-results tr.pending .build-state { clear: both; } -.resource-pane input:not([type=checkbox]):not([type=submit]) { +.resource-pane input:not([type=checkbox]):not([type=submit]):not([type=number]) { width: 435px; } @@ -682,6 +682,14 @@ table.build-results tr.pending .build-state { width: 188px; } +/* Published media pane */ + +/*.media-pane .well {*/ + /*margin: 30px;*/ + /*padding-left: 60px;*/ + /*padding-right: 60px;*/ + /*width: 590px;*/ +/*}*/ /* Dependancies pane */ @@ -1194,7 +1202,7 @@ button#add-filter { display: table; } -.edit-resource-target-platforms-enabled:not(:checked) ~ .edit-resource-targets { +.form-section-toggle:not(:checked) ~ .form-toggleable-section { display: none; } diff --git a/ide/static/ide/js/cloudpebble.js b/ide/static/ide/js/cloudpebble.js index 306c0633..613810ff 100644 --- a/ide/static/ide/js/cloudpebble.js +++ b/ide/static/ide/js/cloudpebble.js @@ -61,6 +61,7 @@ CloudPebble.Init = function() { CloudPebble.Compile.Init(); CloudPebble.Editor.Init(); CloudPebble.Resources.Init(); + CloudPebble.PublishedMedia.Init(); CloudPebble.Sidebar.Init(); CloudPebble.Settings.Init(); CloudPebble.GitHub.Init(); diff --git a/ide/static/ide/js/dependencies.js b/ide/static/ide/js/dependencies.js index 5eedfa3a..fd500f8f 100644 --- a/ide/static/ide/js/dependencies.js +++ b/ide/static/ide/js/dependencies.js @@ -551,7 +551,7 @@ CloudPebble.Dependencies = (function() { } /** This sets up the list of headers */ - function setup_headers_pane(pane, alerts) { + function setup_headers_pane(pane) { // Select an entire header when it is clicked. pane.on('click', 'tbody a', function() { select_element(this); diff --git a/ide/static/ide/js/published_media.js b/ide/static/ide/js/published_media.js new file mode 100644 index 00000000..942d3179 --- /dev/null +++ b/ide/static/ide/js/published_media.js @@ -0,0 +1,152 @@ +CloudPebble.PublishedMedia = (function() { + var media_template = null; + var item_template = null; + + function get_default_data() { + return { + name: '', + id: make_new_id() + } + } + + function make_new_id() { + return _.max(media_template.find('.edit-media-id').map(function() {return parseInt(this.value, 10)})) + 1; + } + + function get_form_data() { + return media_template.find('.media-item').map(function() { + var item = $(this); + var glance = item.find('.edit-media-glance').val(); + var has_timeline = item.find('.edit-media-timeline').prop('checked'); + var data = { + name: item.find('.edit-media-name').val(), + id: parseInt(item.find('.edit-media-id').val(), 10) + }; + if (glance) data.glance = glance; + if (has_timeline) { + data.timeline = { + tiny: item.find('.edit-media-timeline-tiny').val(), + small: item.find('.edit-media-timeline-small').val(), + large: item.find('.edit-media-timeline-large').val() + } + } + return data; + }).toArray(); + } + + /** This singleton manages the error box and loading indicator. */ + var alerts = new (function Alerts() { + var pane; + this.show_error = function show_error(error) { + pane.find('.alert-error').removeClass('hide').text(error); + }; + this.hide_error = function hide_error() { + pane.find('.alert-error').addClass('hide'); + }; + this.init = function(set_pane) { + pane = set_pane; + } + }); + + function get_eligable_identifiers() { + return _.chain(CloudPebble.Resources.GetResources()).filter(function(item) { + return /^(png|pbi|bitmap|raw)/.test(item.kind); + }).pluck('identifiers').flatten().uniq().value(); + } + + function make_new_media_item() { + var item_form = media_template.find('form'); + var new_item = item_template.clone().appendTo(item_form); + set_form_options(new_item); + set_media_item_data(new_item, publishedMedia.get_default_data()); + return new_item; + } + + function set_media_item_data(element, data) { + element.find('.edit-media-name').val(data.name); + element.find('.edit-media-id').val(data.id); + element.find('.edit-media-glance').val(data.glance || ''); + element.find('.edit-media-timeline').prop('checked', !!data.timeline); + if (data.timeline) { + element.find('.edit-media-timeline-tiny').val(data.timeline.tiny); + element.find('.edit-media-timeline-small').val(data.timeline.small); + element.find('.edit-media-timeline-large').val(data.timeline.large); + } + else { + // Default to the first option if the there is no specified timeline data. + element.find('.edit-media-timeline-options option').prop('selected', false); + element.find('.edit-media-timeline-options select').find('option:first').prop('selected', true); + } + } + + function set_form_options(parent) { + var identifiers = get_eligable_identifiers(); + parent.find(".media-resource-selector").each(function() { + var select = $(this).empty(); + var value = select.val(); + if (select.hasClass('media-optional-selector')) { + select.append($('

+ {% if project.project_type == 'package' or project.project_type == 'native' %}