From c9f8566007d259df741b3027bed618855e9048b3 Mon Sep 17 00:00:00 2001 From: Thomas Hunsaker Date: Fri, 21 Aug 2015 20:05:14 +0000 Subject: [PATCH 1/9] Added Spanish translation closes #53 --- appinfo.json | 15 ++++ locale_english.json | 24 ++++++ locale_spanish.json | 24 ++++++ resources/locale_english.bin | Bin 0 -> 533 bytes resources/locale_french.bin | 0 resources/locale_german.bin | 0 resources/locale_spanish.bin | Bin 0 -> 580 bytes src/checkin.c | 6 +- src/checkin_menu.c | 7 +- src/common.h | 5 +- src/hash.h | 59 ++++++++++++++ src/localize.c | 73 +++++++++++++++++ src/localize.h | 9 +++ src/main.c | 150 ++++++++++++++++++----------------- src/share_menu.c | 39 ++++----- 15 files changed, 310 insertions(+), 101 deletions(-) create mode 100644 locale_english.json create mode 100644 locale_spanish.json create mode 100644 resources/locale_english.bin create mode 100644 resources/locale_french.bin create mode 100644 resources/locale_german.bin create mode 100644 resources/locale_spanish.bin create mode 100644 src/hash.h create mode 100644 src/localize.c create mode 100644 src/localize.h diff --git a/appinfo.json b/appinfo.json index fde3eeb..9ca1bec 100644 --- a/appinfo.json +++ b/appinfo.json @@ -50,6 +50,21 @@ "file": "images/check_white.png", "name": "IMAGE_CHECK_ON", "type": "bitmap" + }, + { + "file": "images/honey_spoon_white.png", + "name": "IMAGE_SPOON_WHITE", + "type": "png" + }, + { + "type": "raw", + "name": "LOCALE_ENGLISH", + "file": "locale_english.bin" + }, + { + "type": "raw", + "name": "LOCALE_SPANISH", + "file": "locale_spanish.bin" } ] }, diff --git a/locale_english.json b/locale_english.json new file mode 100644 index 0000000..0c8dff7 --- /dev/null +++ b/locale_english.json @@ -0,0 +1,24 @@ +{ + "1039756945": "Cannot determine current location. :(", + "1192109149": "Error:\\n No connection to phone", + "1382248430": "Timeout :(", + "1422384485": "Share To...", + "1570984832": "Something went wrong :(", + "1662980952": "Twitter", + "1679635707": "Last Check-In", + "1720914531": "Powered by Foursquare", + "1759176004": "Checked In!", + "1805978247": "at sometime...", + "187547209": "Connected to Foursquare!", + "1918266236": "Refreshing...", + "1986659266": "Checking in...", + "2120535917": "Loading...", + "236430616": "Share", + "278919766": "Connect to Foursquare on Phone", + "434695317": "Private Checkin", + "495054875": "Powered", + "590466778": "Checkin", + "654506729": "Venue Name", + "680250322": "Foursquare", + "785287647": "Facebook" +} \ No newline at end of file diff --git a/locale_spanish.json b/locale_spanish.json new file mode 100644 index 0000000..ae6a21f --- /dev/null +++ b/locale_spanish.json @@ -0,0 +1,24 @@ +{ + "1039756945": "No pude localizar :(", + "1192109149": "Error:\\n No pudo connectar al móvil", + "1382248430": "Se falló :(", + "1422384485": "Compartir a...", + "1570984832": "Error cargando los lugares :(", + "1662980952": "Twitter", + "1679635707": "Tu último check-in", + "1720914531": "Impulsado por Foursquare", + "1759176004": "¡Éxito, estás aquí!", + "1805978247": "en algún momento", + "187547209": "Conectado a Foursquare", + "1918266236": "Actualizando...", + "1986659266": "Haciendo check-in...", + "2120535917": "Cargando...", + "236430616": "Compartir", + "278919766": "Conecte a Foursquare en tu móvil", + "434695317": "Check-in Privado", + "495054875": "Impulsado", + "590466778": "Checki-n", + "654506729": "Nombre del Lugar", + "680250322": "Foursquare", + "785287647": "Facebook" +} \ No newline at end of file diff --git a/resources/locale_english.bin b/resources/locale_english.bin new file mode 100644 index 0000000000000000000000000000000000000000..f38570fe30814b6bd15583ff81548a9b3f537da8 GIT binary patch literal 533 zcmY+ByGva`5XJ`s5~JLR0i%dGVn}Q}AXo{hd~rcU^m4J#V%;-(POfK0_wMl`NQjk) zm56nU;J;yElOmvCDTq}df{1OjamNR0wY$Il=JCz60>F>yUvq8YoR*AylJX+fh&|Sv zgzI20Y`)vCybu4zV^t+-Mo|>O4*&o9Ip86~EFNR>!83#M&Clkp=a|+*e`^R1((A?QYprFoGG z*p}Ue)&L&u;{4i+j)Bg8m(=C`Xs{&e{NkqWi<&4C=Y$g`Bgl^9?~2C7#9?`=x)M93 ls1#Nux!3vM4s^x^Rhg=P7=B-oVZBmzN~dVSQB`-Z;dgcEqE7$- literal 0 HcmV?d00001 diff --git a/resources/locale_french.bin b/resources/locale_french.bin new file mode 100644 index 0000000..e69de29 diff --git a/resources/locale_german.bin b/resources/locale_german.bin new file mode 100644 index 0000000..e69de29 diff --git a/resources/locale_spanish.bin b/resources/locale_spanish.bin new file mode 100644 index 0000000000000000000000000000000000000000..7136ad4df5478450a9e39de9e2523ce70b297a45 GIT binary patch literal 580 zcmY*WO-PhM7#`|UYP#8vD`CB5(jM9cq0>T#s7xUwbP*4F80VYaop!#Nb-tM`BBD+q zokBc^h(}M}_Rzua&_OWhC`2bgLBgwg>3!GVP6N-+JMa5EHyL9e$CsvW>p*Z< z;U==6Z2~$}xRVJKbL?~5a;+Ox(g4?$v}qu=u{7SYuV(-84P-_w)I%iED7aSdxFg%b z?so50B%fBLsO6P`S57r}WLb8(r?ZU+8`rt>%CTE}pZW+HiR(cpq*=T8xZAolWBkEHVWh(;zG_?TVtYozTAtzX%bM!X3lLYfBz_T z(SIl50jEfI4lX>Put#k?<0M2 #define NUM_MENU_SECTIONS 1 #define NUM_MENU_ITEMS 3 @@ -68,10 +69,10 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI default: switch (cell_index->row) { case 0: - menu_cell_basic_draw(ctx, cell_layer, "Checkin", NULL, NULL); + menu_cell_basic_draw(ctx, cell_layer, _("Checkin"), NULL, NULL); break; case 1: - menu_cell_basic_draw(ctx, cell_layer, "Share", NULL, NULL); + menu_cell_basic_draw(ctx, cell_layer, _("Share"), NULL, NULL); GRect bounds = layer_get_bounds(cell_layer); char* alligators = ">>"; GFont font = fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD); @@ -84,7 +85,7 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI NULL); break; case 2: - menu_cell_basic_draw(ctx, cell_layer, "Private Checkin", NULL, NULL); + menu_cell_basic_draw(ctx, cell_layer, _("Private Checkin"), NULL, NULL); break; } break; diff --git a/src/common.h b/src/common.h index 182acf4..30cd816 100644 --- a/src/common.h +++ b/src/common.h @@ -3,6 +3,7 @@ #pragma once #include +#include typedef struct { char id[25]; @@ -38,7 +39,3 @@ enum { #else #define STATUS_BAR_OFFSET 12 #endif - -#define DIALOG_MESSAGE_NOT_CONNECTED "Connect to Foursquare on Phone" -#define DIALOG_MESSAGE_NO_PHONE "Error:\n No connection to phone" -#define DIALOG_MESSAGE_NO_LOCATION "No Location" \ No newline at end of file diff --git a/src/hash.h b/src/hash.h new file mode 100644 index 0000000..75aea5b --- /dev/null +++ b/src/hash.h @@ -0,0 +1,59 @@ +#pragma once + +#include +#include +#include +#include + +#ifndef MIN + #define MIN(a, b) ((a) < (b)) ? (a) : (b) +#endif + +// Required for inlining static with -Os during pre-processor +#define FORCE_INLINE __attribute__((always_inline)) inline + +// Supports strings up to 128 long by using 8 16-byte chunks +#define HASH_DJB2_128(s, len) \ + (\ + (hash_djb2(s+112, MIN((len - 112),16), \ + (hash_djb2(s+96, MIN((len - 96),16), \ + (hash_djb2(s+80, MIN((len - 80),16), \ + (hash_djb2(s+64, MIN((len - 64),16), \ + (hash_djb2(s+48, MIN((len - 48),16), \ + (hash_djb2(s+32, MIN((len - 32),16), \ + (hash_djb2(s+16, MIN((len - 16),16), \ + (hash_djb2(s,MIN(len,16),5381)))))))))))))))) \ + ) + +#define HASH_DJB2_NX(s) (HASH_DJB2_128(s, (int32_t)strlen(s)) & 0x7FFFFFFF) +#define HASH_DJB2(s) HASH_DJB2_NX(s) + +// GCC preprocessor will only preprocess this up to 18 characters, so only do 16 +// Based on DJB2 Hash, use 5381 as initial seed +static FORCE_INLINE uint32_t hash_djb2( + const char* bytes, const int32_t length, const uint32_t oldhash) { + uint32_t hash = oldhash; + + if (length <= 0) return hash; + + // Manually unrolled with scope 1 to be compatible with Os + if(length > 0) hash = ((hash << 5) + hash) + bytes[0]; + if(length > 1) hash = ((hash << 5) + hash) + bytes[1]; + if(length > 2) hash = ((hash << 5) + hash) + bytes[2]; + if(length > 3) hash = ((hash << 5) + hash) + bytes[3]; + if(length > 4) hash = ((hash << 5) + hash) + bytes[4]; + if(length > 5) hash = ((hash << 5) + hash) + bytes[5]; + if(length > 6) hash = ((hash << 5) + hash) + bytes[6]; + if(length > 7) hash = ((hash << 5) + hash) + bytes[7]; + if(length > 8) hash = ((hash << 5) + hash) + bytes[8]; + if(length > 9) hash = ((hash << 5) + hash) + bytes[9]; + if(length > 10) hash = ((hash << 5) + hash) + bytes[10]; + if(length > 11) hash = ((hash << 5) + hash) + bytes[11]; + if(length > 12) hash = ((hash << 5) + hash) + bytes[12]; + if(length > 13) hash = ((hash << 5) + hash) + bytes[13]; + if(length > 14) hash = ((hash << 5) + hash) + bytes[14]; + if(length > 15) hash = ((hash << 5) + hash) + bytes[15]; + + return hash; +} + diff --git a/src/localize.c b/src/localize.c new file mode 100644 index 0000000..3e72874 --- /dev/null +++ b/src/localize.c @@ -0,0 +1,73 @@ +#include + +DictionaryIterator s_locale_dict; + + +void locale_init(void) { + //hard-coded for testing + // const char* locale_str = "es"; + + // Detect system locale + const char* locale_str = i18n_get_system_locale(); + ResHandle locale_handle = NULL; + int locale_size = 0; + + if (strncmp(locale_str, "fr", 2) == 0) { + locale_handle = resource_get_handle(RESOURCE_ID_LOCALE_FRENCH); + locale_size = resource_size(locale_handle); + } else if (strncmp(locale_str, "es", 2) == 0) { + locale_handle = resource_get_handle(RESOURCE_ID_LOCALE_SPANISH); + locale_size = resource_size(locale_handle); + } else if (strncmp(locale_str, "de", 2) == 0) { + locale_handle = resource_get_handle(RESOURCE_ID_LOCALE_GERMAN); + locale_size = resource_size(locale_handle); + } + + // Fallback to English for unlocalized languages (0 byte files) + if (locale_size == 0) { + locale_handle = resource_get_handle(RESOURCE_ID_LOCALE_ENGLISH); + locale_size = resource_size(locale_handle); + } + + int resource_offset = 0; + int locale_entries = 0; + resource_offset += resource_load_byte_range(locale_handle, resource_offset, + (uint8_t*)&locale_entries, sizeof(locale_entries)); + + struct locale { + int32_t hashval; + int32_t strlen; + } locale_info; + + int dict_buffer_size = locale_size + 7 * locale_entries; //7 byte header per item + char *dict_buffer = malloc(dict_buffer_size); + dict_write_begin(&s_locale_dict, (uint8_t*)dict_buffer, dict_buffer_size); + + for (int i = 0; i < locale_entries; i++) { + resource_offset += resource_load_byte_range(locale_handle, resource_offset, + (uint8_t*)&locale_info, sizeof(struct locale)); + + struct Tuplet tupl = { + .type = TUPLE_CSTRING, + .key = locale_info.hashval, + .cstring.length = locale_info.strlen}; + + tupl.cstring.data = malloc(tupl.cstring.length); + + resource_offset += resource_load_byte_range(locale_handle, + resource_offset, (uint8_t*)tupl.cstring.data, tupl.cstring.length); + + dict_write_tuplet(&s_locale_dict, &tupl); + } + + dict_write_end(&s_locale_dict); +} + +char *locale_str(int hashval) { + Tuple *tupl = dict_find(&s_locale_dict, hashval); + + if (tupl && tupl->value->cstring) { + return tupl->value->cstring; + } + return "\7"; //return blank character +} diff --git a/src/localize.h b/src/localize.h new file mode 100644 index 0000000..b80e099 --- /dev/null +++ b/src/localize.h @@ -0,0 +1,9 @@ +#pragma once +#include "hash.h" + +#define _(str) locale_str(HASH_DJB2(str)) + +void locale_init(void); + +char *locale_str(int hashval); + diff --git a/src/main.c b/src/main.c index 46f0399..5518e59 100644 --- a/src/main.c +++ b/src/main.c @@ -3,8 +3,8 @@ #include #include "libs/pebble-assist.h" #ifdef PBL_COLOR - #include "libs/dithered_rects.h" - #include "colors.h" +#include "libs/dithered_rects.h" +#include "colors.h" #endif #include "checkin_menu.h" #include "checkin.h" @@ -12,13 +12,14 @@ #include "common.h" #include "config.h" #include "paths.h" +#include #define BOX_HEIGHT 84 #define ROW_HEIGHT 52 #define ANIM_DURATION 100 #define ANIM_DELAY 300 - + #define NUM_MENU_SECTIONS 1 #ifdef PBL_PLATFORM_APLITE #define NUM_MENU_ITEMS 12 @@ -114,8 +115,9 @@ static void getListOfLocations() { if (iter == NULL) { return; } - text_layer_set_text(text_layer_primary, "Refreshing..."); + text_layer_set_text(text_layer_primary, _("Refreshing...")); text_layer_set_text(text_layer_primary_address, ""); + dict_write_tuplet(iter, &refresh_tuple); dict_write_end(iter); app_message_outbox_send(); @@ -125,7 +127,7 @@ static void transition_circle_anim_stopped_handler(Animation *animation, bool fi #ifdef PBL_SDK_2 property_animation_destroy((PropertyAnimation*)s_transition_circle_animation); #endif - + layer_mark_dirty(layer_primary_circle); if(!last_mode) { reverse_menu_animation = false; @@ -169,7 +171,7 @@ static void last_checkin_show() { } // Drop Current Venue - s_drop_current_animation = reverse_last_animation + s_drop_current_animation = reverse_last_animation ? property_animation_create_layer_frame(layer_primary_back, &box_finish, &box_start) : property_animation_create_layer_frame(layer_primary_back, &box_start, &box_finish); if(animation_is_scheduled((Animation*)s_drop_current_animation)) { @@ -204,7 +206,7 @@ static void last_checkin_show() { s_transition_circle_animation = reverse_last_animation ? property_animation_create_layer_frame(layer_primary_circle, &fab_finish, &fab_start) : property_animation_create_layer_frame(layer_primary_circle, &fab_start, &fab_finish); - Animation *anim_slide_circle = + Animation *anim_slide_circle = property_animation_get_animation(s_transition_circle_animation); animation_set_duration(anim_slide_circle, 500); animation_set_handlers((Animation*)s_transition_circle_animation, (AnimationHandlers) { @@ -220,14 +222,14 @@ static void transition_animation() { GRect start = GRect(0, (SCREEN_HEIGHT/2) - STATUS_BAR_OFFSET, SCREEN_WIDTH, (SCREEN_HEIGHT/2) + STATUS_BAR_OFFSET); GRect finish = GRect(0, -10 - ROW_HEIGHT, SCREEN_WIDTH, ROW_HEIGHT + 10); if(reverse_menu_animation) { - s_transition_box_animation = + s_transition_box_animation = property_animation_create_layer_frame(layer_primary_back, &finish, &start); } else { - s_transition_box_animation = + s_transition_box_animation = property_animation_create_layer_frame(layer_primary_back, &start, &finish); } - - anim_slide_box = + + anim_slide_box = property_animation_get_animation(s_transition_box_animation); animation_set_duration(anim_slide_box, 500); layer_mark_dirty(layer_primary_back); @@ -261,16 +263,16 @@ static void transition_animation() { #endif if(reverse_menu_animation) { text_layer_set_text_color(text_layer_primary, GColorBlack); - s_transition_text_1_animation = + s_transition_text_1_animation = property_animation_create_layer_frame(text_layer_get_layer(text_layer_primary), &finish, &start); } else { #ifdef PBL_COLOR text_layer_set_text_color(text_layer_primary, GColorDarkGray); #endif - s_transition_text_1_animation = + s_transition_text_1_animation = property_animation_create_layer_frame(text_layer_get_layer(text_layer_primary), &start, &finish); } - anim_slide_text_1 = + anim_slide_text_1 = property_animation_get_animation(s_transition_text_1_animation); animation_set_duration(anim_slide_text_1, 100); animation_set_handlers(anim_slide_text_1, (AnimationHandlers) { @@ -289,22 +291,22 @@ static void transition_animation() { #endif if(reverse_menu_animation) { text_layer_set_text_color(text_layer_primary_address, GColorBlack); - s_transition_text_2_animation = + s_transition_text_2_animation = property_animation_create_layer_frame(text_layer_get_layer(text_layer_primary_address), &finish, &start); } else { #ifdef PBL_COLOR text_layer_set_text_color(text_layer_primary_address, GColorDarkGray); #endif - s_transition_text_2_animation = + s_transition_text_2_animation = property_animation_create_layer_frame(text_layer_get_layer(text_layer_primary_address), &start, &finish); } - anim_slide_text_2 = + anim_slide_text_2 = property_animation_get_animation(s_transition_text_2_animation); animation_set_handlers(anim_slide_text_2, (AnimationHandlers) { .stopped = anim_stopped_handler }, NULL); animation_set_duration(anim_slide_text_2, 100); - + // TODO: Fix this line, it is crashing // text_layer_set_size(text_layer_primary_address,GSize(102,20)); @@ -317,16 +319,16 @@ static void transition_animation() { #endif if(reverse_menu_animation) { - s_transition_menu_animation = + s_transition_menu_animation = property_animation_create_layer_frame(menu_layer_get_layer(layer_menu_venues), &finish, &start); menu_mode = false; } else { - s_transition_menu_animation = + s_transition_menu_animation = property_animation_create_layer_frame(menu_layer_get_layer(layer_menu_venues), &start, &finish); menu_mode = true; } - - anim_slide_menu = + + anim_slide_menu = property_animation_get_animation(s_transition_menu_animation); animation_set_duration(anim_slide_menu, 100); animation_set_handlers((Animation*)s_transition_menu_animation, (AnimationHandlers) { @@ -335,7 +337,7 @@ static void transition_animation() { animation_set_handlers(anim_slide_menu, (AnimationHandlers) { .stopped = anim_stopped_handler }, NULL); - + #ifdef PBL_SDK_3 Animation *spawn = animation_spawn_create(anim_slide_box, anim_slide_circle, anim_slide_text_1, anim_slide_text_2, anim_slide_menu, NULL); animation_schedule(spawn); @@ -366,10 +368,10 @@ void circle_grow_timer_tick() { } else { grow_circle = false; show_checkin = false; - + circle_radius = DEFAULT_CIRCLE_RADIUS; circle_radius_count = 1; - + app_timer_cancel_safe(circle_grow_timer); checkin_show(); } @@ -391,7 +393,7 @@ static void up_single_click_handler(ClickRecognizerRef recognizer, void *context up_count++; if(up_count == 2) { getListOfLocations(); - + // Return to venue list reverse_last_animation = true; last_checkin_show(); @@ -464,7 +466,7 @@ static void select_long_click_handler(ClickRecognizerRef recognizer, void *conte strncpy(venuename, venues[0].name, sizeof(venuename)); show_checkin = true; grow_circle = true; - + // Start timer to grow circle circle_grow_timer = app_timer_register(100, circle_grow_timer_tick, NULL); checkin_send_request(venueid, venuename, 0, 0, 0, false); @@ -509,7 +511,7 @@ void draw_layer_primary_circle(Layer *cell_layer, GContext *ctx) { #else graphics_context_set_fill_color(ctx, GColorBlack); #endif - + graphics_fill_circle(ctx, GPoint(113,81), circle_radius); } } else if(drop_and_shrink) { @@ -540,14 +542,14 @@ void draw_layer_primary_circle(Layer *cell_layer, GContext *ctx) { #else graphics_context_set_fill_color(ctx, GColorBlack); #endif - + // Circle #ifdef PBL_ROUND graphics_fill_circle(ctx, GPoint(220,SCREEN_HEIGHT/2), DEFAULT_CIRCLE_RADIUS_ROUND); #else graphics_fill_circle(ctx, GPoint(113,81), DEFAULT_CIRCLE_RADIUS); #endif - + // Icon if(is_refreshing) { GRect bitmap_bounds = gbitmap_get_bounds(image_refresh); @@ -597,7 +599,7 @@ static void menu_draw_header_callback(GContext* ctx, const Layer *cell_layer, ui static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuIndex *cell_index, void *data) { #ifdef PBL_PLATFORM_APLITE if(cell_index->row == NUM_MENU_ITEMS - 1) { - menu_cell_basic_draw(ctx, cell_layer, "Foursquare", "Powered", image_cog); + menu_cell_basic_draw(ctx, cell_layer, _("Foursquare"), _("Powered"), image_cog); } else { menu_cell_basic_draw(ctx, cell_layer, venues[cell_index->row].name, venues[cell_index->row].address, NULL); } @@ -608,16 +610,16 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI if(cell_index->row == NUM_MENU_ITEMS - 1) { GRect bitmap_bounds = gbitmap_get_bounds(image_cog); #ifdef PBL_ROUND - graphics_draw_text(ctx, "Powered by Foursquare", little_font, + graphics_draw_text(ctx, _("Powered by Foursquare"), little_font, GRect(10, (bounds.size.h/2) - 15, bounds.size.w - 20, 25), - GTextOverflowModeTrailingEllipsis, + GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, - NULL); + NULL); GRect cog_bounds = GRect((bounds.size.w / 2) - (bitmap_bounds.size.w / 2), (bounds.size.h/2) + 5, bitmap_bounds.size.w, bitmap_bounds.size.h); #else - graphics_draw_text(ctx, "Powered by Foursquare", little_font, + graphics_draw_text(ctx, _("Powered by Foursquare"), little_font, GRect(5, 4, bounds.size.w - 10, 20), GTextOverflowModeFill, GTextAlignmentCenter, @@ -634,27 +636,27 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI venues[cell_index->row].name, big_font, GRect(0, 5, bounds.size.w - 20, 50), - GTextOverflowModeTrailingEllipsis, + GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter); graphics_draw_text(ctx, venues[cell_index->row].name, big_font, GRect(10, text_size.h > 25 ? 7 : 20, bounds.size.w - 20, 50), - GTextOverflowModeTrailingEllipsis, + GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); graphics_draw_text(ctx, venues[cell_index->row].address, little_font, GRect(10, bounds.size.h-24, bounds.size.w - 20, 20), - GTextOverflowModeTrailingEllipsis, + GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); #else graphics_draw_text(ctx, venues[cell_index->row].name, big_font, GRect(5, 4, bounds.size.w - 10, 25), - GTextOverflowModeTrailingEllipsis, + GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); graphics_draw_text(ctx, venues[cell_index->row].address, little_font, GRect(5, 30, bounds.size.w - 10, 20), - GTextOverflowModeTrailingEllipsis, + GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); #endif @@ -694,11 +696,11 @@ static void window_load(Window *window) { GRect bounds = layer_get_frame(window_layer); SCREEN_HEIGHT = bounds.size.h; SCREEN_WIDTH = bounds.size.w; - + #ifdef PBL_COLOR setup_theme_colors(config_get_theme()); #endif - + // Background #ifdef PBL_COLOR accent_color = get_accent_color(); @@ -710,17 +712,17 @@ static void window_load(Window *window) { #else window_set_background_color(window, GColorWhite); #endif - + // Main Background layer_back = layer_create(GRect(0,0,bounds.size.w,bounds.size.h)); layer_set_update_proc(layer_back, draw_image_layer_back); layer_add_child(window_layer, layer_back); - + #ifdef PBL_COLOR // TODO: Show image from the first venue, maybe start_transitioning_rect(layer_back, 100, 1); #endif - + // Last Checkin layer_last_checkin = layer_create(GRect(0,0-bounds.size.h, bounds.size.w, bounds.size.h)); @@ -734,7 +736,7 @@ static void window_load(Window *window) { text_layer_set_background_color(text_layer_last_checkin_title, GColorClear); text_layer_set_text_alignment(text_layer_last_checkin_title, PBL_IF_ROUND_ELSE(GTextAlignmentCenter, GTextAlignmentLeft)); text_layer_set_font(text_layer_last_checkin_title, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); - text_layer_set_text(text_layer_last_checkin_title, "Last Check-In"); + text_layer_set_text(text_layer_last_checkin_title, _("Last Check-In")); layer_add_child(layer_last_checkin, text_layer_get_layer(text_layer_last_checkin_title)); // Venue @@ -747,7 +749,7 @@ static void window_load(Window *window) { text_layer_set_background_color(text_layer_last_checkin_venue, GColorClear); text_layer_set_text_alignment(text_layer_last_checkin_venue, PBL_IF_ROUND_ELSE(GTextAlignmentCenter, GTextAlignmentLeft)); text_layer_set_font(text_layer_last_checkin_venue, fonts_get_system_font(FONT_KEY_ROBOTO_CONDENSED_21)); - text_layer_set_text(text_layer_last_checkin_venue, "Venue Name"); + text_layer_set_text(text_layer_last_checkin_venue, _("Venue Name")); layer_add_child(layer_last_checkin, text_layer_get_layer(text_layer_last_checkin_venue)); // Date @@ -761,14 +763,14 @@ static void window_load(Window *window) { text_layer_set_text_alignment(text_layer_last_checkin_date, PBL_IF_ROUND_ELSE(GTextAlignmentCenter, GTextAlignmentLeft)); text_layer_set_font(text_layer_last_checkin_date, fonts_get_system_font(FONT_KEY_GOTHIC_14)); - text_layer_set_text(text_layer_last_checkin_date, "at sometime..."); + text_layer_set_text(text_layer_last_checkin_date, _("at sometime...")); layer_add_child(layer_last_checkin, text_layer_get_layer(text_layer_last_checkin_date)); // TODO: Not sure about address placement here... //layer_add_child(layer_last_checkin, text_layer_get_layer(text_layer_last_checkin_address)); layer_add_child(window_layer, layer_last_checkin); - + // Menu layer_menu_venues = menu_layer_create( GRect(bounds.origin.x, bounds.origin.y+bounds.size.h, bounds.size.w, bounds.size.h)); @@ -781,9 +783,9 @@ static void window_load(Window *window) { .draw_row = menu_draw_row_callback }); menu_mode = false; - + image_cog = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_COG); - + #ifdef PBL_SDK_3 #ifdef PBL_COLOR menu_layer_set_normal_colors(layer_menu_venues, GColorWhite, GColorLightGray); @@ -799,7 +801,7 @@ static void window_load(Window *window) { layer_primary_back = layer_create(GRect(0,(bounds.size.h/2) - STATUS_BAR_OFFSET,bounds.size.w, (bounds.size.h/2) + STATUS_BAR_OFFSET)); layer_set_update_proc(layer_primary_back, draw_layer_primary_back); layer_add_child(window_layer, layer_primary_back); - + // Text 1 #ifdef PBL_ROUND text_layer_primary = text_layer_create(GRect(15,5,bounds.size.w-25,74)); @@ -812,7 +814,7 @@ static void window_load(Window *window) { text_layer_set_text_alignment(text_layer_primary, PBL_IF_ROUND_ELSE(GTextAlignmentCenter, GTextAlignmentLeft)); text_layer_set_font(text_layer_primary, fonts_get_system_font(FONT_KEY_ROBOTO_CONDENSED_21)); text_layer_set_overflow_mode(text_layer_primary, GTextOverflowModeTrailingEllipsis); - text_layer_set_text(text_layer_primary, "Loading..."); + text_layer_set_text(text_layer_primary, _("Loading...")); layer_add_child(layer_primary_back, text_layer_get_layer(text_layer_primary)); // Text 2 @@ -828,14 +830,14 @@ static void window_load(Window *window) { text_layer_set_font(text_layer_primary_address, fonts_get_system_font(FONT_KEY_GOTHIC_14)); text_layer_set_text(text_layer_primary_address, ""); layer_add_child(layer_primary_back, text_layer_get_layer(text_layer_primary_address)); - - // FAB + + // FAB layer_primary_circle = layer_create(GRect(0,PBL_IF_ROUND_ELSE(0,0 - STATUS_BAR_OFFSET),bounds.size.w,bounds.size.h)); layer_set_update_proc(layer_primary_circle, draw_layer_primary_circle); layer_add_child(window_layer, layer_primary_circle); - + image_refresh = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_REFRESH); - + // Status Bar #ifdef PBL_SDK_3 s_status_bar = status_bar_layer_create(); @@ -848,21 +850,21 @@ static void window_load(Window *window) { layer_add_child( window_layer, status_bar_layer_get_layer(s_status_bar)); #endif - + reverse_menu_animation = false; - + if(bluetooth_connection_service_peek()) { if(persist_exists(KEY_TOKEN)) { no_foursquare = false; } else { no_foursquare = true; - text_layer_set_text(text_layer_primary, DIALOG_MESSAGE_NOT_CONNECTED); + text_layer_set_text(text_layer_primary, _("Connect to Foursquare on Phone")); // text_layer_set_text(text_layer_primary, "Mos Eisley Cantina"); // text_layer_set_text(text_layer_primary_address, "24m - 7 Jawa Way"); } } else { no_internet = true; - text_layer_set_text(text_layer_primary, DIALOG_MESSAGE_NO_PHONE); + text_layer_set_text(text_layer_primary, _("Error:\n No connection to phone")); } } @@ -907,9 +909,9 @@ void in_received_handler(DictionaryIterator *iter, void *context) { Tuple *text_tuple_error = dict_find(iter, SPOON_ERROR); Tuple *text_tuple_ready = dict_find(iter, SPOON_READY); Tuple *text_tuple_config = dict_find(iter, SPOON_CONFIG); - + // APP_LOG(APP_LOG_LEVEL_DEBUG, "In received"); - + if(text_tuple_error) { text_layer_set_text(text_layer_primary, text_tuple_error->value->cstring); } else if(text_tuple_config) { @@ -925,7 +927,8 @@ void in_received_handler(DictionaryIterator *iter, void *context) { } } else if(text_tuple_token && !text_tuple_latlng) { // APP_LOG(APP_LOG_LEVEL_DEBUG, "Token: %s", text_tuple_token->value->cstring); - text_layer_set_text(text_layer_primary, "Connected to Foursquare!"); + text_layer_set_text(text_layer_primary, _("Connected to Foursquare!")); + persist_write_string(KEY_TOKEN, text_tuple_token->value->cstring); persist_exists(KEY_TOKEN); char key_stored[50]; @@ -950,7 +953,7 @@ void in_received_handler(DictionaryIterator *iter, void *context) { if(index == -1) { venue.isRecent = true; lastCheckinVenue = venue; - + text_layer_set_text(text_layer_last_checkin_venue, lastCheckinVenue.name); // HACK: Using the address field for date here text_layer_set_text(text_layer_last_checkin_date, lastCheckinVenue.address); @@ -959,7 +962,7 @@ void in_received_handler(DictionaryIterator *iter, void *context) { venues[venue.index] = venue; num_venues++; } - + if(venue.index == 0) { text_layer_set_size(text_layer_primary, GSize(SCREEN_WIDTH-40,50)); text_layer_set_text(text_layer_primary, venues[0].name); @@ -968,7 +971,7 @@ void in_received_handler(DictionaryIterator *iter, void *context) { layer_mark_dirty(layer_primary_back); } menu_layer_reload_data_and_mark_dirty(layer_menu_venues); - + if(index == MAX_VENUES - 1) { is_refreshing = false; vibes_short_pulse(); @@ -976,9 +979,9 @@ void in_received_handler(DictionaryIterator *iter, void *context) { } } else { if(!text_tuple_token) { - text_layer_set_text(text_layer_primary, DIALOG_MESSAGE_NOT_CONNECTED); + text_layer_set_text(text_layer_primary, _("Connect to Foursquare on Phone")); } else { - text_layer_set_text(text_layer_primary, "Cannot determine current location. :("); + text_layer_set_text(text_layer_primary, _("Cannot determine current location. :(")); } } } @@ -994,7 +997,10 @@ static void init(void) { app_message_register_outbox_sent(out_sent_handler); app_message_register_outbox_failed(out_failed_handler); app_message_open(128, 128); - + + // Init locale + locale_init(); + s_main_window = window_create(); window_set_click_config_provider(s_main_window, click_config_provider); window_set_window_handlers(s_main_window, (WindowHandlers) { @@ -1006,7 +1012,7 @@ static void init(void) { static void deinit(void) { animation_unschedule_all(); - + text_layer_destroy_safe(text_layer_last_checkin_title); text_layer_destroy_safe(text_layer_last_checkin_venue); text_layer_destroy_safe(text_layer_last_checkin_address); @@ -1041,4 +1047,4 @@ int main(void) { init(); app_event_loop(); deinit(); -} \ No newline at end of file +} diff --git a/src/share_menu.c b/src/share_menu.c index 96a4f91..8d21a4d 100644 --- a/src/share_menu.c +++ b/src/share_menu.c @@ -5,7 +5,8 @@ #include "share_menu.h" #include "checkin.h" #include "colors.h" - +#include + #define NUM_MENU_SECTIONS 1 #define NUM_MENU_ITEMS 3 #define BOX_SIZE 13 @@ -35,19 +36,19 @@ static bool facebook; void share_menu_draw_layer_bar(Layer *cell_layer, GContext *ctx) { graphics_context_set_fill_color(ctx, (GColor)get_primary_color()); graphics_fill_rect(ctx, GRect(0,0,SIDE_BAR_WIDTH,168), 8, GCornerNone); - + if(split_bar) { Layer *window_layer = window_get_root_layer(s_window); GRect bounds = layer_get_frame(window_layer); graphics_context_set_fill_color(ctx, (GColor)get_back_color()); graphics_fill_rect(ctx, GRect(0,bounds.size.h/2,SIDE_BAR_WIDTH,bounds.size.h/2), 8, GCornerNone); } - + #ifdef PBL_ROUND #else graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_circle(ctx, GPoint(7,10), 3); - + graphics_fill_circle(ctx, GPoint(7,20), 3); #endif } @@ -69,13 +70,13 @@ static void menu_draw_header_callback(GContext* ctx, const Layer *cell_layer, ui #ifdef PBL_ROUND GRect bounds = layer_get_bounds(cell_layer); GFont little_font = fonts_get_system_font(FONT_KEY_GOTHIC_14); - graphics_draw_text(ctx, "Share To...", little_font, + graphics_draw_text(ctx, _("Share To..."), little_font, GRect(40, 0, bounds.size.w - 20, 25), - GTextOverflowModeTrailingEllipsis, + GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); #else - menu_cell_basic_header_draw(ctx, cell_layer, "Share To..."); + menu_cell_basic_header_draw(ctx, cell_layer, _("Share To...")); #endif } @@ -93,13 +94,13 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI GRect check_bounds = GRect(bounds.size.w - 22, (bounds.size.h / 2) - (bitmap_bounds.size.h /2) - 2, bitmap_bounds.size.w, bitmap_bounds.size.h); - + switch (cell_index->section) { default: graphics_context_set_stroke_color(ctx, GColorWhite); switch (cell_index->row) { case 0: - menu_cell_basic_draw(ctx, cell_layer, "Twitter", NULL, NULL); + menu_cell_basic_draw(ctx, cell_layer, _("Twitter"), NULL, NULL); graphics_draw_rect(ctx, box_bounds); if(twitter) { graphics_context_set_compositing_mode(ctx, GCompOpSet); @@ -107,15 +108,15 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI } break; case 1: - menu_cell_basic_draw(ctx, cell_layer, "Facebook", NULL, NULL); + menu_cell_basic_draw(ctx, cell_layer, _("Facebook"), NULL, NULL); graphics_draw_rect(ctx, box_bounds); if(facebook) { graphics_context_set_compositing_mode(ctx, GCompOpSet); graphics_draw_bitmap_in_rect(ctx, check, check_bounds); } break; - case 2: - menu_cell_basic_draw(ctx, cell_layer, "Checkin", NULL, NULL); + case 2: + menu_cell_basic_draw(ctx, cell_layer, _("Checkin"), NULL, NULL); break; } break; @@ -142,7 +143,7 @@ static void menu_select_callback(MenuLayer *menu_layer, MenuIndex *cell_index, v static void window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); GRect bounds = layer_get_frame(window_layer); - + #ifdef PBL_COLOR window_set_background_color(window, GColorBlack); #else @@ -161,7 +162,7 @@ static void window_load(Window *window) { s_menu_layer = menu_layer_create( GRect(0,0,bounds.size.w, bounds.size.h)); #endif - + menu_layer_set_callbacks(s_menu_layer, NULL, (MenuLayerCallbacks) { .get_num_sections = menu_get_num_sections_callback, .get_num_rows = menu_get_num_rows_callback, @@ -171,7 +172,7 @@ static void window_load(Window *window) { .draw_row = menu_draw_row_callback, .select_click = menu_select_callback }); - + menu_layer_set_click_config_onto_window(s_menu_layer, window); #ifdef PBL_COLOR menu_layer_set_normal_colors(s_menu_layer, GColorBlack, GColorLightGray); @@ -182,13 +183,13 @@ static void window_load(Window *window) { #endif layer_add_child(window_layer, menu_layer_get_layer(s_menu_layer)); - + #if PBL_COLOR layer_bar = layer_create(GRect(0,0,SIDE_BAR_WIDTH,bounds.size.h)); layer_set_update_proc(layer_bar, share_menu_draw_layer_bar); layer_add_child(window_layer, layer_bar); #endif - + check_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_CHECK_ON); } @@ -203,7 +204,7 @@ static void init(void) { .load = window_load, .unload = window_unload, }); - window_stack_push(s_window, true); + window_stack_push(s_window, true); } void share_menu_deinit(void) { @@ -221,4 +222,4 @@ void share_menu_show(bool menu_mode, char venue_guid[128], char venue_name[512]) bool share_menu_is_on_top() { return s_window == window_stack_get_top_window(); } -*/ \ No newline at end of file +*/ From 36f63c60434cfb6854b19c6512323e66e5da73c7 Mon Sep 17 00:00:00 2001 From: Thomas Hunsaker Date: Fri, 21 Aug 2015 20:16:37 +0000 Subject: [PATCH 2/9] Added French/German placeholders --- appinfo.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/appinfo.json b/appinfo.json index 9ca1bec..146b433 100644 --- a/appinfo.json +++ b/appinfo.json @@ -65,6 +65,16 @@ "type": "raw", "name": "LOCALE_SPANISH", "file": "locale_spanish.bin" + }, + { + "type": "raw", + "name": "LOCALE_FRENCH", + "file": "locale_french.bin" + }, + { + "type": "raw", + "name": "LOCALE_GERMAN", + "file": "locale_german.bin" } ] }, From 5daa26a56a6e1c4460c3a6abb6a13bc7ac090a0b Mon Sep 17 00:00:00 2001 From: Thomas Hunsaker Date: Fri, 21 Aug 2015 23:26:13 +0000 Subject: [PATCH 3/9] Spanish string fix --- locale_spanish.json | 4 ++-- resources/locale_spanish.bin | Bin 580 -> 577 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/locale_spanish.json b/locale_spanish.json index ae6a21f..af23fca 100644 --- a/locale_spanish.json +++ b/locale_spanish.json @@ -5,7 +5,7 @@ "1422384485": "Compartir a...", "1570984832": "Error cargando los lugares :(", "1662980952": "Twitter", - "1679635707": "Tu último check-in", + "1679635707": "Último check-in", "1720914531": "Impulsado por Foursquare", "1759176004": "¡Éxito, estás aquí!", "1805978247": "en algún momento", @@ -17,7 +17,7 @@ "278919766": "Conecte a Foursquare en tu móvil", "434695317": "Check-in Privado", "495054875": "Impulsado", - "590466778": "Checki-n", + "590466778": "Check-in", "654506729": "Nombre del Lugar", "680250322": "Foursquare", "785287647": "Facebook" diff --git a/resources/locale_spanish.bin b/resources/locale_spanish.bin index 7136ad4df5478450a9e39de9e2523ce70b297a45..17910b1e05901c5b918cf7d9ec2c9347084648f7 100644 GIT binary patch delta 25 hcmX@Ya*$<12qTkj=HxKOeQbgZ3=D^7O_pU+2LNTH2Ot0d delta 28 kcmX@ea)f0=2qROb?&L7WeVif;3=AQq3Ws-1mSR!|0DSxiEC2ui From b041de53be0bd895fcfea78a9cad6f676da3613f Mon Sep 17 00:00:00 2001 From: Thomas Hunsaker Date: Sat, 30 Jan 2016 11:01:30 -0700 Subject: [PATCH 4/9] appinfo merge wackiness --- appinfo.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/appinfo.json b/appinfo.json index 146b433..5560f8e 100644 --- a/appinfo.json +++ b/appinfo.json @@ -51,11 +51,6 @@ "name": "IMAGE_CHECK_ON", "type": "bitmap" }, - { - "file": "images/honey_spoon_white.png", - "name": "IMAGE_SPOON_WHITE", - "type": "png" - }, { "type": "raw", "name": "LOCALE_ENGLISH", From 9bbefd3ac88fe3a2e6e271eb7e1e89b0a8f62425 Mon Sep 17 00:00:00 2001 From: Thomas Hunsaker Date: Sat, 30 Jan 2016 16:28:59 -0700 Subject: [PATCH 5/9] Updated locale_framework files --- appinfo.json | 40 ++++++++++++------------ resources/{ => data}/locale_english.bin | Bin resources/{ => data}/locale_french.bin | 0 resources/{ => data}/locale_german.bin | 0 resources/{ => data}/locale_spanish.bin | Bin src/hash.h | 1 - src/localize.c | 27 +++++++--------- src/localize.h | 1 - src/main.c | 4 +-- 9 files changed, 34 insertions(+), 39 deletions(-) rename resources/{ => data}/locale_english.bin (100%) rename resources/{ => data}/locale_french.bin (100%) rename resources/{ => data}/locale_german.bin (100%) rename resources/{ => data}/locale_spanish.bin (100%) diff --git a/appinfo.json b/appinfo.json index 5560f8e..79002d8 100644 --- a/appinfo.json +++ b/appinfo.json @@ -25,6 +25,26 @@ "projectType": "native", "resources": { "media": [ + { + "file": "data/locale_spanish.bin", + "name": "LOCALE_SPANISH", + "type": "raw" + }, + { + "file": "data/locale_german.bin", + "name": "LOCALE_GERMAN", + "type": "raw" + }, + { + "file": "data/locale_french.bin", + "name": "LOCALE_FRENCH", + "type": "raw" + }, + { + "file": "data/locale_english.bin", + "name": "LOCALE_ENGLISH", + "type": "raw" + }, { "file": "images/spoon_2_menu_icon.png", "menuIcon": true, @@ -50,26 +70,6 @@ "file": "images/check_white.png", "name": "IMAGE_CHECK_ON", "type": "bitmap" - }, - { - "type": "raw", - "name": "LOCALE_ENGLISH", - "file": "locale_english.bin" - }, - { - "type": "raw", - "name": "LOCALE_SPANISH", - "file": "locale_spanish.bin" - }, - { - "type": "raw", - "name": "LOCALE_FRENCH", - "file": "locale_french.bin" - }, - { - "type": "raw", - "name": "LOCALE_GERMAN", - "file": "locale_german.bin" } ] }, diff --git a/resources/locale_english.bin b/resources/data/locale_english.bin similarity index 100% rename from resources/locale_english.bin rename to resources/data/locale_english.bin diff --git a/resources/locale_french.bin b/resources/data/locale_french.bin similarity index 100% rename from resources/locale_french.bin rename to resources/data/locale_french.bin diff --git a/resources/locale_german.bin b/resources/data/locale_german.bin similarity index 100% rename from resources/locale_german.bin rename to resources/data/locale_german.bin diff --git a/resources/locale_spanish.bin b/resources/data/locale_spanish.bin similarity index 100% rename from resources/locale_spanish.bin rename to resources/data/locale_spanish.bin diff --git a/src/hash.h b/src/hash.h index 75aea5b..b593e81 100644 --- a/src/hash.h +++ b/src/hash.h @@ -56,4 +56,3 @@ static FORCE_INLINE uint32_t hash_djb2( return hash; } - diff --git a/src/localize.c b/src/localize.c index 3e72874..4d8f471 100644 --- a/src/localize.c +++ b/src/localize.c @@ -44,20 +44,17 @@ void locale_init(void) { dict_write_begin(&s_locale_dict, (uint8_t*)dict_buffer, dict_buffer_size); for (int i = 0; i < locale_entries; i++) { - resource_offset += resource_load_byte_range(locale_handle, resource_offset, - (uint8_t*)&locale_info, sizeof(struct locale)); - - struct Tuplet tupl = { - .type = TUPLE_CSTRING, - .key = locale_info.hashval, - .cstring.length = locale_info.strlen}; - - tupl.cstring.data = malloc(tupl.cstring.length); - - resource_offset += resource_load_byte_range(locale_handle, - resource_offset, (uint8_t*)tupl.cstring.data, tupl.cstring.length); - - dict_write_tuplet(&s_locale_dict, &tupl); + resource_offset += resource_load_byte_range(locale_handle, + resource_offset, + (uint8_t*)&locale_info, + sizeof(struct locale)); + char *buffer = malloc(locale_info.strlen); + resource_offset += resource_load_byte_range(locale_handle, + resource_offset, + (uint8_t*)buffer, + locale_info.strlen); + dict_write_cstring(&s_locale_dict, locale_info.hashval, buffer); + free(buffer); } dict_write_end(&s_locale_dict); @@ -70,4 +67,4 @@ char *locale_str(int hashval) { return tupl->value->cstring; } return "\7"; //return blank character -} +} \ No newline at end of file diff --git a/src/localize.h b/src/localize.h index b80e099..65d5e22 100644 --- a/src/localize.h +++ b/src/localize.h @@ -6,4 +6,3 @@ void locale_init(void); char *locale_str(int hashval); - diff --git a/src/main.c b/src/main.c index 5518e59..ca11dfe 100644 --- a/src/main.c +++ b/src/main.c @@ -3,8 +3,8 @@ #include #include "libs/pebble-assist.h" #ifdef PBL_COLOR -#include "libs/dithered_rects.h" -#include "colors.h" + #include "libs/dithered_rects.h" + #include "colors.h" #endif #include "checkin_menu.h" #include "checkin.h" From c0d3d378e306505dd5b1a9e7ffe8fab9b4a6ae49 Mon Sep 17 00:00:00 2001 From: Thomas Hunsaker Date: Mon, 1 Feb 2016 20:42:53 +0000 Subject: [PATCH 6/9] WIP - Moved js strings to pebble --- locale_english.json | 4 +++ locale_french.json | 28 ++++++++++++++++ locale_german.json | 28 ++++++++++++++++ locale_spanish.json | 6 +++- resources/data/locale_english.bin | Bin 533 -> 669 bytes resources/data/locale_french.bin | Bin 0 -> 669 bytes resources/data/locale_german.bin | Bin 0 -> 669 bytes resources/data/locale_spanish.bin | Bin 577 -> 669 bytes src/common.h | 6 ++-- src/js/pebble-js-app.js | 54 +++++++++++++++++------------- src/main.c | 34 ++++++++++++++++--- 11 files changed, 128 insertions(+), 32 deletions(-) create mode 100644 locale_french.json create mode 100644 locale_german.json diff --git a/locale_english.json b/locale_english.json index 0c8dff7..d99b6e1 100644 --- a/locale_english.json +++ b/locale_english.json @@ -1,4 +1,5 @@ { + "1035871787": "No internet connection detected.", "1039756945": "Cannot determine current location. :(", "1192109149": "Error:\\n No connection to phone", "1382248430": "Timeout :(", @@ -10,11 +11,14 @@ "1759176004": "Checked In!", "1805978247": "at sometime...", "187547209": "Connected to Foursquare!", + "1882800246": "Error with request :(", "1918266236": "Refreshing...", + "1963970170": "Request timed out!", "1986659266": "Checking in...", "2120535917": "Loading...", "236430616": "Share", "278919766": "Connect to Foursquare on Phone", + "431615381": "Connection Failed. Try Again.", "434695317": "Private Checkin", "495054875": "Powered", "590466778": "Checkin", diff --git a/locale_french.json b/locale_french.json new file mode 100644 index 0000000..d99b6e1 --- /dev/null +++ b/locale_french.json @@ -0,0 +1,28 @@ +{ + "1035871787": "No internet connection detected.", + "1039756945": "Cannot determine current location. :(", + "1192109149": "Error:\\n No connection to phone", + "1382248430": "Timeout :(", + "1422384485": "Share To...", + "1570984832": "Something went wrong :(", + "1662980952": "Twitter", + "1679635707": "Last Check-In", + "1720914531": "Powered by Foursquare", + "1759176004": "Checked In!", + "1805978247": "at sometime...", + "187547209": "Connected to Foursquare!", + "1882800246": "Error with request :(", + "1918266236": "Refreshing...", + "1963970170": "Request timed out!", + "1986659266": "Checking in...", + "2120535917": "Loading...", + "236430616": "Share", + "278919766": "Connect to Foursquare on Phone", + "431615381": "Connection Failed. Try Again.", + "434695317": "Private Checkin", + "495054875": "Powered", + "590466778": "Checkin", + "654506729": "Venue Name", + "680250322": "Foursquare", + "785287647": "Facebook" +} \ No newline at end of file diff --git a/locale_german.json b/locale_german.json new file mode 100644 index 0000000..d99b6e1 --- /dev/null +++ b/locale_german.json @@ -0,0 +1,28 @@ +{ + "1035871787": "No internet connection detected.", + "1039756945": "Cannot determine current location. :(", + "1192109149": "Error:\\n No connection to phone", + "1382248430": "Timeout :(", + "1422384485": "Share To...", + "1570984832": "Something went wrong :(", + "1662980952": "Twitter", + "1679635707": "Last Check-In", + "1720914531": "Powered by Foursquare", + "1759176004": "Checked In!", + "1805978247": "at sometime...", + "187547209": "Connected to Foursquare!", + "1882800246": "Error with request :(", + "1918266236": "Refreshing...", + "1963970170": "Request timed out!", + "1986659266": "Checking in...", + "2120535917": "Loading...", + "236430616": "Share", + "278919766": "Connect to Foursquare on Phone", + "431615381": "Connection Failed. Try Again.", + "434695317": "Private Checkin", + "495054875": "Powered", + "590466778": "Checkin", + "654506729": "Venue Name", + "680250322": "Foursquare", + "785287647": "Facebook" +} \ No newline at end of file diff --git a/locale_spanish.json b/locale_spanish.json index af23fca..26fa1a3 100644 --- a/locale_spanish.json +++ b/locale_spanish.json @@ -1,5 +1,6 @@ { - "1039756945": "No pude localizar :(", + "1035871787": "¡No hay internet!", + "1039756945": "No pude localizar :(", "1192109149": "Error:\\n No pudo connectar al móvil", "1382248430": "Se falló :(", "1422384485": "Compartir a...", @@ -10,11 +11,14 @@ "1759176004": "¡Éxito, estás aquí!", "1805978247": "en algún momento", "187547209": "Conectado a Foursquare", + "1882800246": "Error con la pedida :(", "1918266236": "Actualizando...", + "1963970170": "Se falló :(", "1986659266": "Haciendo check-in...", "2120535917": "Cargando...", "236430616": "Compartir", "278919766": "Conecte a Foursquare en tu móvil", + "431615381": ":( La conexión falló. Inténtalo de nuevo", "434695317": "Check-in Privado", "495054875": "Impulsado", "590466778": "Check-in", diff --git a/resources/data/locale_english.bin b/resources/data/locale_english.bin index f38570fe30814b6bd15583ff81548a9b3f537da8..8e794ce2aeab631863a1b4ee5176ea37ea66f7ab 100644 GIT binary patch delta 180 zcmbQrGMAN6Y9eE%%G;fiatsU%&iQ$HsmUdo`FRR%iJ3X6DS8SaMU@JU>4}+ndJ`Mu zHMG_C*(w4R`sFKR=9Q!t<)xM=BqKDXq?Q1+1GR0O=gnwQ=3rSM22|`?RFq$&P@Y+m zp-_}sSejZ~qF|-LP<4*KR2V251QjaD%uP*E$S*BXocw}OS7Pd$7m@-%>42ilvc!^9 N1?P;^4e-6n-d(8o2}mnp0xlp~Qe>L9j6pP@*RX5{}DqSeRlm`;whpb|#sdy(1!` zm57x{Y75Daut{NKA)H_t5Gz4J#n#yP-sZw3)$aS=H{bidH**01o-Vvy9OLhT%P6GA zu3(pJz^-@vJ2M5(Pj9z|xvv7Yg<>*_q6l8uzq6AJ&natNz=Q(%%veI5doKcOPOD&? zjYMSY*Sqp1VLNL{3yf7|)+mWE_M3QnMHw5x*!KC-39*tYPjK=t%=*Dp)m zcLj@AO81cKyWTrL^UxyaIuwU}tQR_8U-Y6=%&RI*OU|`GpMAZ2j)DGOaB1_9W1ue| zVo6!-5Mw9Ff9xH*Dj}L=bHaI*5oDi|Cj#AfD&Z9g>$lSlfnvU4mj}7F&aIp4GOF;1 z93(|g8#%R$?xWstKFZxjACjk$ARn#3zZ>I8N#qq%i^S743y)h(FKC07J+KuK;Xia;&LRK+ literal 0 HcmV?d00001 diff --git a/resources/data/locale_german.bin b/resources/data/locale_german.bin index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8e794ce2aeab631863a1b4ee5176ea37ea66f7ab 100644 GIT binary patch literal 669 zcmY*XF>4e-6n-d(8o2}mnp0xlp~Qe>L9j6pP@*RX5{}DqSeRlm`;whpb|#sdy(1!` zm57x{Y75Daut{NKA)H_t5Gz4J#n#yP-sZw3)$aS=H{bidH**01o-Vvy9OLhT%P6GA zu3(pJz^-@vJ2M5(Pj9z|xvv7Yg<>*_q6l8uzq6AJ&natNz=Q(%%veI5doKcOPOD&? zjYMSY*Sqp1VLNL{3yf7|)+mWE_M3QnMHw5x*!KC-39*tYPjK=t%=*Dp)m zcLj@AO81cKyWTrL^UxyaIuwU}tQR_8U-Y6=%&RI*OU|`GpMAZ2j)DGOaB1_9W1ue| zVo6!-5Mw9Ff9xH*Dj}L=bHaI*5oDi|Cj#AfD&Z9g>$lSlfnvU4mj}7F&aIp4GOF;1 z93(|g8#%R$?xWstKFZxjACjk$ARn#3zZ>I8N#qq%i^S743y)h(FKC07J+KuK;Xia;&LRK+ literal 0 HcmV?d00001 diff --git a/resources/data/locale_spanish.bin b/resources/data/locale_spanish.bin index 17910b1e05901c5b918cf7d9ec2c9347084648f7..8e794ce2aeab631863a1b4ee5176ea37ea66f7ab 100644 GIT binary patch literal 669 zcmY*XF>4e-6n-d(8o2}mnp0xlp~Qe>L9j6pP@*RX5{}DqSeRlm`;whpb|#sdy(1!` zm57x{Y75Daut{NKA)H_t5Gz4J#n#yP-sZw3)$aS=H{bidH**01o-Vvy9OLhT%P6GA zu3(pJz^-@vJ2M5(Pj9z|xvv7Yg<>*_q6l8uzq6AJ&natNz=Q(%%veI5doKcOPOD&? zjYMSY*Sqp1VLNL{3yf7|)+mWE_M3QnMHw5x*!KC-39*tYPjK=t%=*Dp)m zcLj@AO81cKyWTrL^UxyaIuwU}tQR_8U-Y6=%&RI*OU|`GpMAZ2j)DGOaB1_9W1ue| zVo6!-5Mw9Ff9xH*Dj}L=bHaI*5oDi|Cj#AfD&Z9g>$lSlfnvU4mj}7F&aIp4GOF;1 z93(|g8#%R$?xWstKFZxjACjk$ARn#3zZ>I8N#qq%i^S743y)h(FKC07J+KuK;Xia;&LRK+ literal 577 zcmY*WJ4jqX6dhuds4+%KR*}`~C&VHy2&se=qA@N65f!nB#W-(VCp&Luciy~JL`16~ zRw1OZ5eb&5>?|yNg@vGCDTq}df=JqElY2L-G1b61=bpLuoacj> z<+uqfXd8i!bKJ=Y`nuVt>g{|3s-yv~bIGoO(1y}@%RZamZ=NADVxbTR5(fp>YLPn{ z`+E7a`6-eEb5i7clz~yFN<6TvX**R{O@s{#+xeY_RUb>_Jj{iX zw3Dc~WHK2x_~Uf03CaDfWNkrt`wC>_ldTANF;2d>v+Q0^O{)BXk;0=La2T?&i;6Mc z#7+*^yK9iX2TfjY)_2@Z$p7?!cl#K^WT&Jwn`&$m4^cTWue_IzogVdeKBCFWer&p{ z?%fLn%9-|kFz`1Vyuh0BIu293bvs`>%Fy%>7jnkhJQEFHW}6YXO9Bem%)L$J*}=pU z`tLS8;1tQl^@Eob_J|E -1) + appMessageQueue.push({'message': { 'result' : result ? 1 : 0, 'name':message, 'error':error }}); + else + appMessageQueue.push({'message': { 'result' : result ? 1 : 0, 'name':message }}); sendAppMessage(); } var error = function(e) { - Pebble.sendAppMessage({'error': e}); + Pebble.sendAppMessage({'error':2}); + console.log("Error:" + e); }; var success = function(position) { @@ -98,23 +102,25 @@ function fetchClosestVenues(token, position) { var offsetIndex = index; var venueId = element.id.replace('\'',''); var venueName = element.name.length >= 60 ? element.name.substring(0,59).trim().replace('\'','') : element.name.replace('\'',''); - var venueAddress = element.location.address ? element.location.address.length > 20 ? element.location.address.substring(0,20).trim() : element.location.address : '(No Address)'; + var venueAddress = element.location.address ? element.location.address.length > 20 ? element.location.address.substring(0,20).trim() : element.location.address : ''; + var venueDistance = ""; if(element.location.distance) { - var venueDistance = ""; if(localStorage.spoon_unit === null || localStorage.spoon_unit === "0") { - venueDistance = element.location.distance >= 1000 ? (element.location.distance/1000).toFixed(2) + " km - " : element.location.distance + " m - "; +// venueDistance = element.location.distance >= 1000 ? (element.location.distance/1000).toFixed(2) + " km - " : element.location.distance + " m - "; + venueDistance = element.location.distance; // Distance in m } else { - var distance = element.location.distance * mToFeet; - venueDistance = distance >= ftInMile ? (distance/ftInMile).toFixed(2) + " mi - " : distance.toFixed(0) + " ft - "; +// var distance = element.location.distance * mToFeet; +// venueDistance = distance >= ftInMile ? (distance/ftInMile).toFixed(2) + " mi - " : distance.toFixed(0) + " ft - "; + venueDistance = element.location.distance * mToFeet; // Distance in Feet } - venueAddress = venueDistance + venueAddress; +// venueAddress = venueDistance + venueAddress; } if(isNewList) { - appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':venueAddress, 'index':offsetIndex}}); + appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':venueAddress, 'distance':venueDistance, 'index':offsetIndex}}); isNewList = false; } else { - appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':venueAddress, 'index':offsetIndex}}); + appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':venueAddress, 'distance':venueDistance, 'index':offsetIndex}}); } // Send them in clusters of 5 @@ -123,7 +129,7 @@ function fetchClosestVenues(token, position) { }); } else { //console.log('Invalid response received! ' + JSON.stringify(req)); - appMessageQueue.push({'message': {'error': 'Error: Error with request :('}}); + appMessageQueue.push({'message': {'error':2}}); } } else { console.log('Request returned error code ' + req.status.toString()); @@ -134,12 +140,12 @@ function fetchClosestVenues(token, position) { req.ontimeout = function() { console.log('HTTP request timed out'); - appMessageQueue.push({'message': {'error': 'Error:\nRequest timed out!'}}); + appMessageQueue.push({'message': {'error':1}}); sendAppMessage(); }; req.onerror = function() { console.log('HTTP request return error'); - appMessageQueue.push({'message': {'error': 'Error:\nNo internet connection detected.'}}); + appMessageQueue.push({'message': {'error':0}}); sendAppMessage(); }; req.send(null); @@ -163,12 +169,12 @@ function fetchMostRecentCheckin(token) { : element.venue.name.replace('\'',''); var checkinDate = new Date(element.createdAt*1000); var checkinString = checkinDate !== null ? - "at " + checkinDate.getHours() + ":" + checkinDate.getMinutes() + " " + checkinDate.toDateString() - : "Sometime in the past. :)"; + checkinDate.getHours() + ":" + checkinDate.getMinutes() + " " + checkinDate.toDateString() + : ""; appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':checkinString, 'index':-1 }}); }); } else { - appMessageQueue.push({'message': {'error': 'Error: Error with request :(' }}); + appMessageQueue.push({'message': {'error':2 }}); } } } @@ -176,12 +182,12 @@ function fetchMostRecentCheckin(token) { }; reqRecent.ontimeout = function() { //console.log('HTTP request timed out'); - appMessageQueue.push({'message': {'error': 'Error:\nRequest timed out!'}}); + appMessageQueue.push({'message': {'error':1}}); sendAppMessage(); }; reqRecent.onerror = function() { //console.log('HTTP request return error'); - appMessageQueue.push({'message': {'error': 'Error:\nNo internet connection detected.'}}); + appMessageQueue.push({'message': {'error':0}}); sendAppMessage(); }; reqRecent.send(null); @@ -265,11 +271,11 @@ function attemptCheckin(id, name, private, twitter, facebook) { //console.log('Response: ' + req.responseText); if(response) { // TODO: Maybe show the user a popular tip after checkin? - notifyPebbleCheckinOutcome(true, name, ''); + notifyPebbleCheckinOutcome(true, name, '', -1); } } else { console.log('Invalid response received! ' + JSON.stringify(req)); - notifyPebbleCheckinOutcome(false, 'Error:\nError with Request', ''); + notifyPebbleCheckinOutcome(false, name, '', 2); } } else { console.log('Request returned error code ' + req.status.toString()); @@ -278,12 +284,12 @@ function attemptCheckin(id, name, private, twitter, facebook) { }; req.ontimeout = function() { console.log('HTTP request timed out'); - appMessageQueue.push({'message': {'error': 'Error:\nRequest timed out!'}}); + appMessageQueue.push({'message': {'error':1}}); sendAppMessage(); }; req.onerror = function() { console.log('HTTP request return error'); - appMessageQueue.push({'message': {'error': 'Error:\nNo internet connection detected.'}}); + appMessageQueue.push({'message': {'error':0}}); sendAppMessage(); }; req.send(null); diff --git a/src/main.c b/src/main.c index ca11dfe..27a4345 100644 --- a/src/main.c +++ b/src/main.c @@ -107,6 +107,26 @@ static PropertyAnimation *s_transition_text_2_animation; static PropertyAnimation *s_transition_circle_animation; static PropertyAnimation *s_transition_menu_animation; +static char *getErrorReason(int error_code) { + switch(error_code) { + case 0: + return _("No internet connection detected."); + break; + case 1: + return _("Request timed out!"); + break; + case 2: + return _("Error with request :("); + break; + case 3: + return _("Connection Failed. Try Again."); + break; + default: + return _("Something went wrong :("); + break; + }; +} + static void getListOfLocations() { is_refreshing = true; Tuplet refresh_tuple = TupletInteger(SPOON_REFRESH, MAX_VENUES); @@ -906,6 +926,7 @@ void in_received_handler(DictionaryIterator *iter, void *context) { Tuple *text_tuple_name = dict_find(iter, SPOON_NAME); Tuple *text_tuple_id = dict_find(iter, SPOON_ID); Tuple *text_tuple_address = dict_find(iter, SPOON_ADDRESS); + Tuple *text_tuple_distance = dict_find(iter, SPOON_DISTANCE); Tuple *text_tuple_error = dict_find(iter, SPOON_ERROR); Tuple *text_tuple_ready = dict_find(iter, SPOON_READY); Tuple *text_tuple_config = dict_find(iter, SPOON_CONFIG); @@ -913,7 +934,7 @@ void in_received_handler(DictionaryIterator *iter, void *context) { // APP_LOG(APP_LOG_LEVEL_DEBUG, "In received"); if(text_tuple_error) { - text_layer_set_text(text_layer_primary, text_tuple_error->value->cstring); + text_layer_set_text(text_layer_primary, getErrorReason(text_tuple_error->value->int16)); } else if(text_tuple_config) { #ifdef PBL_COLOR int config = text_tuple_config->value->int16; @@ -944,10 +965,14 @@ void in_received_handler(DictionaryIterator *iter, void *context) { strncpy(venue.id, text_tuple_id->value->cstring, sizeof(venue.id)); strncpy(venue.name, text_tuple_name->value->cstring, sizeof(venue.name)); - if(text_tuple_address) { + if(text_tuple_address && strlen(text_tuple_address->value->cstring) > 0) { strncpy(venue.address, text_tuple_address->value->cstring, sizeof(venue.address)); } else { - strncpy(venue.address, "-", sizeof(venue.address)); + strncpy(venue.address, _("(No Address)"), sizeof(venue.address)); + } + + if(text_tuple_distance) { + venue.distance = text_tuple_distance->value->int16; } if(index == -1) { @@ -987,8 +1012,7 @@ void in_received_handler(DictionaryIterator *iter, void *context) { } void in_dropped_handler(AppMessageResult reason, void *context) { - APP_LOG(APP_LOG_LEVEL_DEBUG, "Hello. It's me, I dropped a message."); - APP_LOG(APP_LOG_LEVEL_DEBUG, "In dropped: %i - %s", reason, translate_error(reason)); + APP_LOG(APP_LOG_LEVEL_DEBUG, "Hello. It's me, I dropped a message: %i - %s", reason, translate_error(reason)); } static void init(void) { From 76dcdc8500ac501b3d3bcb7ebadbb5e3054e932d Mon Sep 17 00:00:00 2001 From: Thomas Hunsaker Date: Mon, 1 Feb 2016 20:50:39 +0000 Subject: [PATCH 7/9] Added missing string --- locale_english.json | 53 +++++++++++++++--------------- locale_french.json | 1 + locale_german.json | 1 + locale_spanish.json | 49 +++++++++++++-------------- resources/data/locale_english.bin | Bin 669 -> 688 bytes resources/data/locale_french.bin | Bin 669 -> 688 bytes resources/data/locale_german.bin | Bin 669 -> 688 bytes resources/data/locale_spanish.bin | Bin 669 -> 688 bytes src/main.c | 2 +- 9 files changed, 55 insertions(+), 51 deletions(-) diff --git a/locale_english.json b/locale_english.json index d99b6e1..bb92a3d 100644 --- a/locale_english.json +++ b/locale_english.json @@ -1,28 +1,29 @@ { - "1035871787": "No internet connection detected.", - "1039756945": "Cannot determine current location. :(", - "1192109149": "Error:\\n No connection to phone", - "1382248430": "Timeout :(", - "1422384485": "Share To...", - "1570984832": "Something went wrong :(", - "1662980952": "Twitter", - "1679635707": "Last Check-In", - "1720914531": "Powered by Foursquare", - "1759176004": "Checked In!", - "1805978247": "at sometime...", - "187547209": "Connected to Foursquare!", - "1882800246": "Error with request :(", - "1918266236": "Refreshing...", - "1963970170": "Request timed out!", - "1986659266": "Checking in...", - "2120535917": "Loading...", - "236430616": "Share", - "278919766": "Connect to Foursquare on Phone", - "431615381": "Connection Failed. Try Again.", - "434695317": "Private Checkin", - "495054875": "Powered", - "590466778": "Checkin", - "654506729": "Venue Name", - "680250322": "Foursquare", - "785287647": "Facebook" + "187547209": "Connected to Foursquare!", + "236430616": "Share", + "278919766": "Connect to Foursquare on Phone", + "431615381": "Connection Failed. Try Again.", + "434695317": "Private Checkin", + "495054875": "Powered", + "590466778": "Checkin", + "654506729": "Venue Name", + "680250322": "Foursquare", + "785287647": "Facebook", + "1035871787": "No internet connection detected.", + "1039756945": "Cannot determine current location. :(", + "1192109149": "Error:\\n No connection to phone", + "1382248430": "Timeout :(", + "1422384485": "Share To...", + "1570984832": "Something went wrong :(", + "1662980952": "Twitter", + "1679635707": "Last Check-In", + "1720914531": "Powered by Foursquare", + "1759176004": "Checked In!", + "1805978247": "at sometime...", + "1882800246": "Error with request :(", + "1918266236": "Refreshing...", + "1963970170": "Request timed out!", + "1986659266": "Checking in...", + "1999950152": "No Address", + "2120535917": "Loading..." } \ No newline at end of file diff --git a/locale_french.json b/locale_french.json index d99b6e1..b3e53e3 100644 --- a/locale_french.json +++ b/locale_french.json @@ -15,6 +15,7 @@ "1918266236": "Refreshing...", "1963970170": "Request timed out!", "1986659266": "Checking in...", + "1999950152": "No Address", "2120535917": "Loading...", "236430616": "Share", "278919766": "Connect to Foursquare on Phone", diff --git a/locale_german.json b/locale_german.json index d99b6e1..b3e53e3 100644 --- a/locale_german.json +++ b/locale_german.json @@ -15,6 +15,7 @@ "1918266236": "Refreshing...", "1963970170": "Request timed out!", "1986659266": "Checking in...", + "1999950152": "No Address", "2120535917": "Loading...", "236430616": "Share", "278919766": "Connect to Foursquare on Phone", diff --git a/locale_spanish.json b/locale_spanish.json index 26fa1a3..f0194ad 100644 --- a/locale_spanish.json +++ b/locale_spanish.json @@ -1,28 +1,29 @@ { - "1035871787": "¡No hay internet!", + "187547209": "Conectado a Foursquare", + "236430616": "Compartir", + "278919766": "Conecte a Foursquare en tu móvil", + "431615381": ":( La conexión falló. Inténtalo de nuevo", + "434695317": "Check-in Privado", + "495054875": "Impulsado", + "590466778": "Check-in", + "654506729": "Nombre del Lugar", + "680250322": "Foursquare", + "785287647": "Facebook", + "1035871787": "¡No hay internet!", "1039756945": "No pude localizar :(", - "1192109149": "Error:\\n No pudo connectar al móvil", - "1382248430": "Se falló :(", - "1422384485": "Compartir a...", - "1570984832": "Error cargando los lugares :(", - "1662980952": "Twitter", - "1679635707": "Último check-in", - "1720914531": "Impulsado por Foursquare", - "1759176004": "¡Éxito, estás aquí!", - "1805978247": "en algún momento", - "187547209": "Conectado a Foursquare", + "1192109149": "Error:\\n No pudo connectar al móvil", + "1382248430": "Se falló :(", + "1422384485": "Compartir a...", + "1570984832": "Error cargando los lugares :(", + "1662980952": "Twitter", + "1679635707": "Último check-in", + "1720914531": "Impulsado por Foursquare", + "1759176004": "¡Éxito, estás aquí!", + "1805978247": "en algún momento", "1882800246": "Error con la pedida :(", - "1918266236": "Actualizando...", - "1963970170": "Se falló :(", - "1986659266": "Haciendo check-in...", - "2120535917": "Cargando...", - "236430616": "Compartir", - "278919766": "Conecte a Foursquare en tu móvil", - "431615381": ":( La conexión falló. Inténtalo de nuevo", - "434695317": "Check-in Privado", - "495054875": "Impulsado", - "590466778": "Check-in", - "654506729": "Nombre del Lugar", - "680250322": "Foursquare", - "785287647": "Facebook" + "1918266236": "Actualizando...", + "1963970170": "Se falló :(", + "1986659266": "Haciendo check-in...", + "1999950152": "No dirección", + "2120535917": "Cargando..." } \ No newline at end of file diff --git a/resources/data/locale_english.bin b/resources/data/locale_english.bin index 8e794ce2aeab631863a1b4ee5176ea37ea66f7ab..a00110c22861a879ff244ec59e19d44b494b57eb 100644 GIT binary patch delta 32 ncmbQsx`CBZdLbjDkjF)na&86&2ETj-$CQ+!)Z*ezjB^{5G delta 14 VcmdnMI+vAEY9S-zW)a3Yi~t;#1A71f diff --git a/resources/data/locale_french.bin b/resources/data/locale_french.bin index 8e794ce2aeab631863a1b4ee5176ea37ea66f7ab..a00110c22861a879ff244ec59e19d44b494b57eb 100644 GIT binary patch delta 32 ncmbQsx`CBZdLbjDkjF)na&86&2ETj-$CQ+!)Z*ezjB^{5G delta 14 VcmdnMI+vAEY9S-zW)a3Yi~t;#1A71f diff --git a/resources/data/locale_german.bin b/resources/data/locale_german.bin index 8e794ce2aeab631863a1b4ee5176ea37ea66f7ab..a00110c22861a879ff244ec59e19d44b494b57eb 100644 GIT binary patch delta 32 ncmbQsx`CBZdLbjDkjF)na&86&2ETj-$CQ+!)Z*ezjB^{5G delta 14 VcmdnMI+vAEY9S-zW)a3Yi~t;#1A71f diff --git a/resources/data/locale_spanish.bin b/resources/data/locale_spanish.bin index 8e794ce2aeab631863a1b4ee5176ea37ea66f7ab..a00110c22861a879ff244ec59e19d44b494b57eb 100644 GIT binary patch delta 32 ncmbQsx`CBZdLbjDkjF)na&86&2ETj-$CQ+!)Z*ezjB^{5G delta 14 VcmdnMI+vAEY9S-zW)a3Yi~t;#1A71f diff --git a/src/main.c b/src/main.c index 27a4345..0a414d7 100644 --- a/src/main.c +++ b/src/main.c @@ -968,7 +968,7 @@ void in_received_handler(DictionaryIterator *iter, void *context) { if(text_tuple_address && strlen(text_tuple_address->value->cstring) > 0) { strncpy(venue.address, text_tuple_address->value->cstring, sizeof(venue.address)); } else { - strncpy(venue.address, _("(No Address)"), sizeof(venue.address)); + strncpy(venue.address, _("No Address"), sizeof(venue.address)); } if(text_tuple_distance) { From 5d7130e917865048e86c637009e2ef40ade35f3f Mon Sep 17 00:00:00 2001 From: Thomas Hunsaker Date: Mon, 1 Feb 2016 20:55:30 +0000 Subject: [PATCH 8/9] It has been a while --- resources/data/locale_spanish.bin | Bin 688 -> 730 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/resources/data/locale_spanish.bin b/resources/data/locale_spanish.bin index a00110c22861a879ff244ec59e19d44b494b57eb..49e15fdcdafbe7c7c29725774941a5520d3de459 100644 GIT binary patch literal 730 zcmZWnO-NNi6dr0*T2E6#A7UN*eUM%V-1I;wEc1a#q)3ZgjC05LrZ;!yI(O!35>cy= zRuOL6goKM0t=_5@F1(8t!HZf7(JCmYXq#<1^Loz|R|DTU-<v9`<{r6va*^G}Pq6xs8!-L^juOY=zzhp)5Cw+X1q9@J{OWj8i7K--J~-s}2bj z1Od7FWvkNL;AJaI!s=1TNFA9q*kgfW~ z(}z8?shZ55$z4B-KqH^xZ3X{~#=W#^$T65m>$lG<^}w^oDC2WlR|)HSI-f^i$2y2H zVokMn1^KlD?xXVQx3e{|$tb;fjJ;R>^^aa|a! UpS=40Yu*!DZov&BQhy+S0ZqB<>;M1& literal 688 zcmY*XF>4e-6n-d(8o2}mnj^%#Lx};&f{?~Qzz{t>kZ@d>Uvi ztwgLuQd>xVgiQ(?3*kh|fLI9%Dz?VP_x4UMR=e+;?|tw4-pn`vJX(IWGREI!o03no zS;r0;j~!?EcWxSKVFwF2-_M%k-%70dXwS+L$`wq>q?sd#`eyaPKcF6IfC(Dk0(xYRks~-6vLIN z{rL*lOBS`^X@)#T13hsNc~*os$2Z#Icrl@D zonxTCDqP(;;uz@D+fafRYsJvYGQJ%iyDTA^WOBkKl@g@yu`1@R3G1hg8UlrU z={EOrlkMx*wq#V{5jjYLj<$2kiqreu;e3=&8+}M#ON`uFfj_eoaY^JAQ;WniH3JV? eO($rB)_D8!{ABL#_pjv Date: Tue, 2 Feb 2016 23:58:47 -0700 Subject: [PATCH 9/9] Localized js, optimized distance display Extracted localizable strings, added locale to query string for API requests to Foursquare. --- appinfo.json | 44 ++++++++++++++-------------- src/common.h | 6 ++-- src/js/pebble-js-app.js | 38 +++++++++++++++++------- src/main.c | 64 +++++++++++++++++++++++++++++++++-------- 4 files changed, 106 insertions(+), 46 deletions(-) diff --git a/appinfo.json b/appinfo.json index 79002d8..b823128 100644 --- a/appinfo.json +++ b/appinfo.json @@ -2,6 +2,7 @@ "appKeys": { "address": 5, "config": 12, + "distance": 15, "error": 11, "facebook": 10, "id": 3, @@ -14,7 +15,8 @@ "refresh": 6, "result": 7, "token": 0, - "twitter": 9 + "twitter": 9, + "unit": 16 }, "capabilities": [ "location", @@ -25,26 +27,6 @@ "projectType": "native", "resources": { "media": [ - { - "file": "data/locale_spanish.bin", - "name": "LOCALE_SPANISH", - "type": "raw" - }, - { - "file": "data/locale_german.bin", - "name": "LOCALE_GERMAN", - "type": "raw" - }, - { - "file": "data/locale_french.bin", - "name": "LOCALE_FRENCH", - "type": "raw" - }, - { - "file": "data/locale_english.bin", - "name": "LOCALE_ENGLISH", - "type": "raw" - }, { "file": "images/spoon_2_menu_icon.png", "menuIcon": true, @@ -70,6 +52,26 @@ "file": "images/check_white.png", "name": "IMAGE_CHECK_ON", "type": "bitmap" + }, + { + "file": "data/locale_spanish.bin", + "name": "LOCALE_SPANISH", + "type": "raw" + }, + { + "file": "data/locale_german.bin", + "name": "LOCALE_GERMAN", + "type": "raw" + }, + { + "file": "data/locale_french.bin", + "name": "LOCALE_FRENCH", + "type": "raw" + }, + { + "file": "data/locale_english.bin", + "name": "LOCALE_ENGLISH", + "type": "raw" } ] }, diff --git a/src/common.h b/src/common.h index 88e9cb2..aedd2fd 100644 --- a/src/common.h +++ b/src/common.h @@ -9,7 +9,8 @@ typedef struct { char id[25]; char name[128]; char address[128]; - int distance; + char distance[10]; + int distance_unit; int index; bool isRecent; } SpoonVenue; @@ -30,7 +31,8 @@ enum { SPOON_CONFIG = 0xC, SPOON_RECENT = 0xD, SPOON_READY = 0xE, - SPOON_DISTANCE = 0xF + SPOON_DISTANCE = 0xF, + SPOON_UNIT = 0x10 }; #define KEY_TOKEN 10 diff --git a/src/js/pebble-js-app.js b/src/js/pebble-js-app.js index 91d5783..a9840a0 100644 --- a/src/js/pebble-js-app.js +++ b/src/js/pebble-js-app.js @@ -13,14 +13,20 @@ var api_mode = '&m=swarm'; var sending = false; var mToFeet = 3.2808; var ftInMile = 5280; +var lang = "en"; + +var appendLangToUrl = function(url) { + return url += "&locale=" + lang; +}; Pebble.addEventListener('ready', function(e) { Pebble.sendAppMessage({'ready':true}); + lang = navigator.language.substring(0,2); }); Pebble.addEventListener('showConfiguration', - function(e) { + function(e) { // TODO: Add the existing user settings to the url // Pebble.openURL('https://thunsaker.github.io/spoon/config'); // Prod @@ -45,9 +51,10 @@ Pebble.addEventListener('webviewclosed', Pebble.showSimpleNotificationOnPebble('Spoon', ':( Connection Failed. Try Again.'); } + // TODO: Config Stuff // if(configuration.theme !== null && configuration.unit !== null) { // localStorage.spoon_theme = configuration.theme; -// localStorage.spoon_unit = configuration.unit; // 0 == km | 1 == mi +// localStorage.spoon_unit = configuration.unit; // 0 == km | 1 == mi // notifyPebbleConfiguration(configuration.theme); // } } @@ -90,6 +97,7 @@ function fetchClosestVenues(token, position) { var req = new XMLHttpRequest(); var requestUrl = 'https://api.foursquare.com/v2/venues/search?oauth_token=' + token + '&v=' + api_date + '&ll=' + position.coords.latitude + ',' + position.coords.longitude + '&limit=' + max_venues + '&radius=' + max_radius + api_mode; // console.log("requestUrl: " + requestUrl); + requestUrl = appendLangToUrl(requestUrl); req.open('GET', requestUrl, true); req.onload = function(e) { if (req.readyState == 4) { @@ -104,23 +112,28 @@ function fetchClosestVenues(token, position) { var venueName = element.name.length >= 60 ? element.name.substring(0,59).trim().replace('\'','') : element.name.replace('\'',''); var venueAddress = element.location.address ? element.location.address.length > 20 ? element.location.address.substring(0,20).trim() : element.location.address : ''; var venueDistance = ""; + var venueDistanceUnit = 0; if(element.location.distance) { - if(localStorage.spoon_unit === null || localStorage.spoon_unit === "0") { + var distance = element.location.distance; + // TODO: Once configuration is in place + if(localStorage.spoon_unit === null || localStorage.spoon_unit === "0") { // venueDistance = element.location.distance >= 1000 ? (element.location.distance/1000).toFixed(2) + " km - " : element.location.distance + " m - "; - venueDistance = element.location.distance; // Distance in m + venueDistanceUnit = distance >= 1000 ? 1 : 0; + venueDistance = distance >= 1000 ? (distance/1000).toFixed(2) : distance; // Distance in m } else { -// var distance = element.location.distance * mToFeet; + distance *= mToFeet; // Distance in Feet // venueDistance = distance >= ftInMile ? (distance/ftInMile).toFixed(2) + " mi - " : distance.toFixed(0) + " ft - "; - venueDistance = element.location.distance * mToFeet; // Distance in Feet + venueDistanceUnit = distance >= ftInMile ? 3 : 2; + venueDistance = distance >= ftInMile ? (distance/ftInMile).toFixed(2) : distance.toFixed(0); } // venueAddress = venueDistance + venueAddress; - } + } if(isNewList) { - appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':venueAddress, 'distance':venueDistance, 'index':offsetIndex}}); + appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':venueAddress, 'distance':venueDistance, 'unit':venueDistanceUnit, 'index':offsetIndex}}); isNewList = false; } else { - appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':venueAddress, 'distance':venueDistance, 'index':offsetIndex}}); + appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':venueAddress, 'distance':venueDistance, 'unit':venueDistanceUnit, 'index':offsetIndex}}); } // Send them in clusters of 5 @@ -155,6 +168,7 @@ function fetchMostRecentCheckin(token) { var reqRecent = new XMLHttpRequest(); var current_time = Math.round(new Date().getTime() / 1000); var requestUrlRecent = 'https://api.foursquare.com/v2/users/self/checkins?oauth_token=' + token + '&v=' + api_date + '&m=foursquare&beforeTimestamp=' + current_time + '&sort=newestfirst&limit=1'; + requestUrlRecent = appendLangToUrl(requestUrlRecent); reqRecent.open('GET', requestUrlRecent, true); reqRecent.onload = function(e) { if (reqRecent.readyState == 4) { @@ -168,8 +182,10 @@ function fetchMostRecentCheckin(token) { element.venue.name.substring(0,45).replace('\'','') : element.venue.name.replace('\'',''); var checkinDate = new Date(element.createdAt*1000); + var minutes = checkinDate.getMinutes(); + minutes = minutes < 10 ? "0" + minutes : minutes; var checkinString = checkinDate !== null ? - checkinDate.getHours() + ":" + checkinDate.getMinutes() + " " + checkinDate.toDateString() + checkinDate.getHours() + ":" + minutes + " " + checkinDate.toDateString() : ""; appMessageQueue.push({'message': {'id':venueId, 'name':venueName, 'address':checkinString, 'index':-1 }}); }); @@ -261,7 +277,7 @@ function attemptCheckin(id, name, private, twitter, facebook) { checkinRequestUrl += '&broadcast=' + broadcastType; } // console.log("After broadcast checkinRequestUrl: " + checkinRequestUrl); - + checkinRequestUrl = appendLangToUrl(checkinRequestUrl); req.open('POST', checkinRequestUrl, true); req.onload = function(e) { if (req.readyState == 4) { diff --git a/src/main.c b/src/main.c index 0a414d7..d9dfb8f 100644 --- a/src/main.c +++ b/src/main.c @@ -53,6 +53,7 @@ static Layer *layer_back; static Layer *layer_primary_back; static TextLayer *text_layer_primary; static TextLayer *text_layer_primary_address; +static TextLayer *text_layer_primary_distance; static Layer *layer_primary_circle; static MenuLayer *layer_menu_venues; static TextLayer *text_layer_last_checkin_title; @@ -107,7 +108,7 @@ static PropertyAnimation *s_transition_text_2_animation; static PropertyAnimation *s_transition_circle_animation; static PropertyAnimation *s_transition_menu_animation; -static char *getErrorReason(int error_code) { +char *getErrorReason(int error_code) { switch(error_code) { case 0: return _("No internet connection detected."); @@ -127,6 +128,19 @@ static char *getErrorReason(int error_code) { }; } +char *get_unit(int unit) { + switch(unit) { + case 1: + return "km"; + case 2: + return "ft"; + case 3: + return "mi"; + default: + return "m"; + } +} + static void getListOfLocations() { is_refreshing = true; Tuplet refresh_tuple = TupletInteger(SPOON_REFRESH, MAX_VENUES); @@ -650,7 +664,10 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI #endif graphics_context_set_compositing_mode(ctx, GCompOpSet); graphics_draw_bitmap_in_rect(ctx, image_cog, cog_bounds); - } else { + } else if (strlen(venues[cell_index->row].name) > 0) { + static char addressString[30]; + snprintf(addressString, sizeof(addressString), + "%s %s - %s", venues[cell_index->row].distance, get_unit(venues[cell_index->row].distance_unit), venues[cell_index->row].address); #ifdef PBL_ROUND GSize text_size = graphics_text_layout_get_content_size( venues[cell_index->row].name, @@ -663,7 +680,7 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); - graphics_draw_text(ctx, venues[cell_index->row].address, little_font, + graphics_draw_text(ctx, addressString, little_font, GRect(10, bounds.size.h-24, bounds.size.w - 20, 20), GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, @@ -674,7 +691,7 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); - graphics_draw_text(ctx, venues[cell_index->row].address, little_font, + graphics_draw_text(ctx, addressString, little_font, GRect(5, 30, bounds.size.w - 10, 20), GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, @@ -763,7 +780,7 @@ static void window_load(Window *window) { #ifdef PBL_ROUND text_layer_last_checkin_venue = text_layer_create(GRect(0,(bounds.size.h/2)-40,SCREEN_WIDTH,74)); #else - text_layer_last_checkin_venue = text_layer_create(GRect(10,74,bounds.size.w-10,74)); + text_layer_last_checkin_venue = text_layer_create(GRect(10,40,bounds.size.w-10,74)); #endif text_layer_set_text_color(text_layer_last_checkin_venue, GColorBlack); text_layer_set_background_color(text_layer_last_checkin_venue, GColorClear); @@ -839,7 +856,7 @@ static void window_load(Window *window) { // Text 2 #ifdef PBL_ROUND - text_layer_primary_address = text_layer_create(GRect(30,50,bounds.size.w-60,60)); + text_layer_primary_address = text_layer_create(GRect(30,50,bounds.size.w-60,20)); text_layer_enable_screen_text_flow_and_paging(text_layer_primary_address, 10); #else text_layer_primary_address = text_layer_create(GRect(10,60,bounds.size.w-10,20)); @@ -850,6 +867,16 @@ static void window_load(Window *window) { text_layer_set_font(text_layer_primary_address, fonts_get_system_font(FONT_KEY_GOTHIC_14)); text_layer_set_text(text_layer_primary_address, ""); layer_add_child(layer_primary_back, text_layer_get_layer(text_layer_primary_address)); + + #ifdef PBL_ROUND + text_layer_primary_distance = text_layer_create(GRect(0,65,bounds.size.w,20)); + text_layer_enable_screen_text_flow_and_paging(text_layer_primary_distance, 5); + text_layer_set_background_color(text_layer_primary_distance, GColorClear); + text_layer_set_text_alignment(text_layer_primary_distance, GTextAlignmentCenter); + text_layer_set_font(text_layer_primary_distance, fonts_get_system_font(FONT_KEY_GOTHIC_14)); + text_layer_set_text(text_layer_primary_distance, ""); + layer_add_child(layer_primary_back, text_layer_get_layer(text_layer_primary_distance)); + #endif // FAB layer_primary_circle = layer_create(GRect(0,PBL_IF_ROUND_ELSE(0,0 - STATUS_BAR_OFFSET),bounds.size.w,bounds.size.h)); @@ -927,6 +954,7 @@ void in_received_handler(DictionaryIterator *iter, void *context) { Tuple *text_tuple_id = dict_find(iter, SPOON_ID); Tuple *text_tuple_address = dict_find(iter, SPOON_ADDRESS); Tuple *text_tuple_distance = dict_find(iter, SPOON_DISTANCE); + Tuple *text_tuple_distance_unit = dict_find(iter, SPOON_UNIT); Tuple *text_tuple_error = dict_find(iter, SPOON_ERROR); Tuple *text_tuple_ready = dict_find(iter, SPOON_READY); Tuple *text_tuple_config = dict_find(iter, SPOON_CONFIG); @@ -963,16 +991,17 @@ void in_received_handler(DictionaryIterator *iter, void *context) { SpoonVenue venue; venue.index = index; strncpy(venue.id, text_tuple_id->value->cstring, sizeof(venue.id)); - strncpy(venue.name, text_tuple_name->value->cstring, sizeof(venue.name)); + strcpy(venue.name, text_tuple_name->value->cstring); if(text_tuple_address && strlen(text_tuple_address->value->cstring) > 0) { - strncpy(venue.address, text_tuple_address->value->cstring, sizeof(venue.address)); + strcpy(venue.address, text_tuple_address->value->cstring); } else { - strncpy(venue.address, _("No Address"), sizeof(venue.address)); + strcpy(venue.address, _("No Address")); } - if(text_tuple_distance) { - venue.distance = text_tuple_distance->value->int16; + if(text_tuple_distance && text_tuple_distance_unit) { + strcpy(venue.distance, text_tuple_distance->value->cstring); + venue.distance_unit = text_tuple_distance_unit->value->int16; } if(index == -1) { @@ -991,7 +1020,17 @@ void in_received_handler(DictionaryIterator *iter, void *context) { if(venue.index == 0) { text_layer_set_size(text_layer_primary, GSize(SCREEN_WIDTH-40,50)); text_layer_set_text(text_layer_primary, venues[0].name); - text_layer_set_text(text_layer_primary_address, venues[0].address); + static char addressString[30]; + #ifdef PBL_ROUND + text_layer_set_text(text_layer_primary_address, venues[0].address); + snprintf(addressString, sizeof(addressString), + "%s %s", venues[0].distance, get_unit(venues[0].distance_unit)); + text_layer_set_text(text_layer_primary_distance, addressString); + #else + snprintf(addressString, sizeof(addressString), + "%s %s - %s", venues[0].distance, get_unit(venues[0].distance_unit), venues[0].address); + text_layer_set_text(text_layer_primary_address, addressString); + #endif layer_mark_dirty(text_layer_get_layer(text_layer_primary)); layer_mark_dirty(layer_primary_back); } @@ -1040,6 +1079,7 @@ static void deinit(void) { text_layer_destroy_safe(text_layer_last_checkin_title); text_layer_destroy_safe(text_layer_last_checkin_venue); text_layer_destroy_safe(text_layer_last_checkin_address); + text_layer_destroy_safe(text_layer_primary_distance); text_layer_destroy_safe(text_layer_last_checkin_date); layer_destroy_safe(layer_last_checkin);