From 04cf441c5ae18400c6b4865b0b37a71718dc9d46 Mon Sep 17 00:00:00 2001 From: Ola Bini Date: Thu, 31 Jul 2014 19:29:33 -0300 Subject: Add web-ui based on previous code --- web-ui/app/404.html | 157 ++ web-ui/app/favicon.ico | 0 web-ui/app/fonts/NewsCycleBold.ttf | Bin 0 -> 73912 bytes web-ui/app/fonts/NewsCycleRegular.ttf | Bin 0 -> 193996 bytes web-ui/app/fonts/OpenSans-Bold.woff | Bin 0 -> 14504 bytes web-ui/app/fonts/OpenSans-BoldItalic.woff | Bin 0 -> 15488 bytes web-ui/app/fonts/OpenSans-Extrabold.woff | Bin 0 -> 15312 bytes web-ui/app/fonts/OpenSans-ExtraboldItalic.woff | Bin 0 -> 15932 bytes web-ui/app/fonts/OpenSans-Italic.woff | Bin 0 -> 15768 bytes web-ui/app/fonts/OpenSans-Light.woff | Bin 0 -> 15048 bytes web-ui/app/fonts/OpenSans-Semibold.woff | Bin 0 -> 15236 bytes web-ui/app/fonts/OpenSans-SemiboldItalic.woff | Bin 0 -> 15736 bytes web-ui/app/fonts/OpenSans.woff | Bin 0 -> 14604 bytes web-ui/app/fonts/OpenSansLight-Italic.woff | Bin 0 -> 15956 bytes web-ui/app/index.html | 84 + web-ui/app/js/dispatchers/left_pane_dispatcher.js | 51 + .../app/js/dispatchers/middle_pane_dispatcher.js | 36 + web-ui/app/js/dispatchers/right_pane_dispatcher.js | 93 + web-ui/app/js/foundation/off_canvas.js | 21 + web-ui/app/js/helpers/contenttype.js | 164 ++ web-ui/app/js/helpers/iterator.js | 43 + web-ui/app/js/helpers/triggering.js | 13 + web-ui/app/js/helpers/view_helper.js | 145 ++ web-ui/app/js/lib/highlightRegex.js | 127 ++ web-ui/app/js/lib/html-sanitizer.js | 1064 ++++++++++ web-ui/app/js/lib/html4-defs.js | 640 ++++++ web-ui/app/js/lib/html_whitelister.js | 70 + web-ui/app/js/mail_list/domain/refresher.js | 25 + web-ui/app/js/mail_list/ui/mail_item_factory.js | 49 + .../app/js/mail_list/ui/mail_items/draft_item.js | 55 + .../mail_list/ui/mail_items/generic_mail_item.js | 97 + web-ui/app/js/mail_list/ui/mail_items/mail_item.js | 63 + web-ui/app/js/mail_list/ui/mail_items/sent_item.js | 62 + web-ui/app/js/mail_list/ui/mail_list.js | 185 ++ .../app/js/mail_list_actions/ui/compose_trigger.js | 31 + .../js/mail_list_actions/ui/delete_many_trigger.js | 31 + .../js/mail_list_actions/ui/mail_list_actions.js | 50 + .../mail_list_actions/ui/mark_as_unread_trigger.js | 31 + .../ui/mark_many_as_read_trigger.js | 31 + .../js/mail_list_actions/ui/pagination_trigger.js | 50 + .../app/js/mail_list_actions/ui/refresh_trigger.js | 28 + .../ui/toggle_check_all_trigger.js | 33 + web-ui/app/js/mail_view/data/mail_builder.js | 79 + web-ui/app/js/mail_view/data/mail_sender.js | 74 + web-ui/app/js/mail_view/ui/compose_box.js | 63 + web-ui/app/js/mail_view/ui/draft_box.js | 74 + web-ui/app/js/mail_view/ui/draft_save_status.js | 25 + web-ui/app/js/mail_view/ui/forward_box.js | 66 + web-ui/app/js/mail_view/ui/mail_actions.js | 70 + web-ui/app/js/mail_view/ui/mail_view.js | 242 +++ .../js/mail_view/ui/no_message_selected_pane.js | 25 + web-ui/app/js/mail_view/ui/recipients/recipient.js | 36 + .../app/js/mail_view/ui/recipients/recipients.js | 127 ++ .../js/mail_view/ui/recipients/recipients_input.js | 140 ++ .../mail_view/ui/recipients/recipients_iterator.js | 41 + web-ui/app/js/mail_view/ui/reply_box.js | 102 + web-ui/app/js/mail_view/ui/reply_section.js | 102 + web-ui/app/js/mail_view/ui/send_button.js | 85 + web-ui/app/js/main.js | 58 + web-ui/app/js/mixins/with_compose_inline.js | 63 + .../app/js/mixins/with_enable_disable_on_event.js | 34 + web-ui/app/js/mixins/with_hide_and_show.js | 14 + web-ui/app/js/mixins/with_mail_edit_base.js | 182 ++ web-ui/app/js/monkey_patching/all.js | 1 + web-ui/app/js/monkey_patching/array.js | 11 + web-ui/app/js/monkey_patching/post_message.js | 16 + web-ui/app/js/page/default.js | 87 + web-ui/app/js/page/events.js | 168 ++ web-ui/app/js/page/pane_contract_expand.js | 34 + web-ui/app/js/page/router.js | 51 + web-ui/app/js/page/router/url_params.js | 40 + web-ui/app/js/search/results_highlighter.js | 53 + web-ui/app/js/search/search_trigger.js | 68 + web-ui/app/js/services/delete_service.js | 43 + web-ui/app/js/services/mail_service.js | 254 +++ web-ui/app/js/services/model/mail.js | 147 ++ web-ui/app/js/tags/data/tags.js | 42 + web-ui/app/js/tags/ui/tag.js | 94 + web-ui/app/js/tags/ui/tag_base.js | 24 + web-ui/app/js/tags/ui/tag_list.js | 93 + web-ui/app/js/tags/ui/tag_shortcut.js | 68 + web-ui/app/js/user_alerts/ui/user_alerts.js | 35 + web-ui/app/js/views/i18n.js | 18 + web-ui/app/js/views/recipientListFormatter.js | 16 + web-ui/app/js/views/templates.js | 46 + web-ui/app/locales/en/translation.json | 69 + web-ui/app/locales/pt/translation.json | 20 + web-ui/app/locales/sv/translation.json | 66 + web-ui/app/robots.txt | 3 + web-ui/app/scss/_alerts.scss | 14 + web-ui/app/scss/_colors.scss | 13 + web-ui/app/scss/_compose.scss | 92 + web-ui/app/scss/_mascot.scss | 32 + web-ui/app/scss/_mixins.scss | 205 ++ web-ui/app/scss/_read.scss | 105 + web-ui/app/scss/_reply.scss | 36 + web-ui/app/scss/_security.scss | 47 + web-ui/app/scss/foundation.scss | 2066 ++++++++++++++++++++ web-ui/app/scss/main.scss | 46 + web-ui/app/scss/news-cycle.scss | 13 + web-ui/app/scss/opensans.scss | 61 + web-ui/app/scss/reset.scss | 421 ++++ web-ui/app/scss/styles.scss | 610 ++++++ web-ui/app/templates/compose/compose_box.hbs | 23 + web-ui/app/templates/compose/fixed_recipient.hbs | 6 + web-ui/app/templates/compose/inline_box.hbs | 18 + web-ui/app/templates/compose/recipient_input.hbs | 1 + web-ui/app/templates/compose/recipients.hbs | 19 + web-ui/app/templates/compose/reply_section.hbs | 6 + web-ui/app/templates/mail_actions/actions_box.hbs | 6 + .../app/templates/mail_actions/compose_trigger.hbs | 3 + .../templates/mail_actions/pagination_trigger.hbs | 3 + .../app/templates/mail_actions/refresh_trigger.hbs | 3 + web-ui/app/templates/mails/full_view.hbs | 87 + web-ui/app/templates/mails/mail_actions.hbs | 6 + web-ui/app/templates/mails/sent.hbs | 23 + web-ui/app/templates/mails/single.hbs | 19 + web-ui/app/templates/no_message_selected.hbs | 3 + web-ui/app/templates/search/search_trigger.hbs | 3 + web-ui/app/templates/tags/shortcut.hbs | 9 + web-ui/app/templates/tags/tag.hbs | 3 + web-ui/app/templates/tags/tag_inner.hbs | 4 + web-ui/app/templates/tags/tag_list.hbs | 3 + web-ui/app/templates/user_alerts/message.hbs | 1 + 124 files changed, 10808 insertions(+) create mode 100644 web-ui/app/404.html create mode 100644 web-ui/app/favicon.ico create mode 100644 web-ui/app/fonts/NewsCycleBold.ttf create mode 100644 web-ui/app/fonts/NewsCycleRegular.ttf create mode 100644 web-ui/app/fonts/OpenSans-Bold.woff create mode 100644 web-ui/app/fonts/OpenSans-BoldItalic.woff create mode 100644 web-ui/app/fonts/OpenSans-Extrabold.woff create mode 100644 web-ui/app/fonts/OpenSans-ExtraboldItalic.woff create mode 100644 web-ui/app/fonts/OpenSans-Italic.woff create mode 100644 web-ui/app/fonts/OpenSans-Light.woff create mode 100644 web-ui/app/fonts/OpenSans-Semibold.woff create mode 100644 web-ui/app/fonts/OpenSans-SemiboldItalic.woff create mode 100644 web-ui/app/fonts/OpenSans.woff create mode 100644 web-ui/app/fonts/OpenSansLight-Italic.woff create mode 100644 web-ui/app/index.html create mode 100644 web-ui/app/js/dispatchers/left_pane_dispatcher.js create mode 100644 web-ui/app/js/dispatchers/middle_pane_dispatcher.js create mode 100644 web-ui/app/js/dispatchers/right_pane_dispatcher.js create mode 100644 web-ui/app/js/foundation/off_canvas.js create mode 100644 web-ui/app/js/helpers/contenttype.js create mode 100644 web-ui/app/js/helpers/iterator.js create mode 100644 web-ui/app/js/helpers/triggering.js create mode 100644 web-ui/app/js/helpers/view_helper.js create mode 100644 web-ui/app/js/lib/highlightRegex.js create mode 100644 web-ui/app/js/lib/html-sanitizer.js create mode 100644 web-ui/app/js/lib/html4-defs.js create mode 100644 web-ui/app/js/lib/html_whitelister.js create mode 100644 web-ui/app/js/mail_list/domain/refresher.js create mode 100644 web-ui/app/js/mail_list/ui/mail_item_factory.js create mode 100644 web-ui/app/js/mail_list/ui/mail_items/draft_item.js create mode 100644 web-ui/app/js/mail_list/ui/mail_items/generic_mail_item.js create mode 100644 web-ui/app/js/mail_list/ui/mail_items/mail_item.js create mode 100644 web-ui/app/js/mail_list/ui/mail_items/sent_item.js create mode 100644 web-ui/app/js/mail_list/ui/mail_list.js create mode 100644 web-ui/app/js/mail_list_actions/ui/compose_trigger.js create mode 100644 web-ui/app/js/mail_list_actions/ui/delete_many_trigger.js create mode 100644 web-ui/app/js/mail_list_actions/ui/mail_list_actions.js create mode 100644 web-ui/app/js/mail_list_actions/ui/mark_as_unread_trigger.js create mode 100644 web-ui/app/js/mail_list_actions/ui/mark_many_as_read_trigger.js create mode 100644 web-ui/app/js/mail_list_actions/ui/pagination_trigger.js create mode 100644 web-ui/app/js/mail_list_actions/ui/refresh_trigger.js create mode 100644 web-ui/app/js/mail_list_actions/ui/toggle_check_all_trigger.js create mode 100644 web-ui/app/js/mail_view/data/mail_builder.js create mode 100644 web-ui/app/js/mail_view/data/mail_sender.js create mode 100644 web-ui/app/js/mail_view/ui/compose_box.js create mode 100644 web-ui/app/js/mail_view/ui/draft_box.js create mode 100644 web-ui/app/js/mail_view/ui/draft_save_status.js create mode 100644 web-ui/app/js/mail_view/ui/forward_box.js create mode 100644 web-ui/app/js/mail_view/ui/mail_actions.js create mode 100644 web-ui/app/js/mail_view/ui/mail_view.js create mode 100644 web-ui/app/js/mail_view/ui/no_message_selected_pane.js create mode 100644 web-ui/app/js/mail_view/ui/recipients/recipient.js create mode 100644 web-ui/app/js/mail_view/ui/recipients/recipients.js create mode 100644 web-ui/app/js/mail_view/ui/recipients/recipients_input.js create mode 100644 web-ui/app/js/mail_view/ui/recipients/recipients_iterator.js create mode 100644 web-ui/app/js/mail_view/ui/reply_box.js create mode 100644 web-ui/app/js/mail_view/ui/reply_section.js create mode 100644 web-ui/app/js/mail_view/ui/send_button.js create mode 100644 web-ui/app/js/main.js create mode 100644 web-ui/app/js/mixins/with_compose_inline.js create mode 100644 web-ui/app/js/mixins/with_enable_disable_on_event.js create mode 100644 web-ui/app/js/mixins/with_hide_and_show.js create mode 100644 web-ui/app/js/mixins/with_mail_edit_base.js create mode 100644 web-ui/app/js/monkey_patching/all.js create mode 100644 web-ui/app/js/monkey_patching/array.js create mode 100644 web-ui/app/js/monkey_patching/post_message.js create mode 100644 web-ui/app/js/page/default.js create mode 100644 web-ui/app/js/page/events.js create mode 100644 web-ui/app/js/page/pane_contract_expand.js create mode 100644 web-ui/app/js/page/router.js create mode 100644 web-ui/app/js/page/router/url_params.js create mode 100644 web-ui/app/js/search/results_highlighter.js create mode 100644 web-ui/app/js/search/search_trigger.js create mode 100644 web-ui/app/js/services/delete_service.js create mode 100644 web-ui/app/js/services/mail_service.js create mode 100644 web-ui/app/js/services/model/mail.js create mode 100644 web-ui/app/js/tags/data/tags.js create mode 100644 web-ui/app/js/tags/ui/tag.js create mode 100644 web-ui/app/js/tags/ui/tag_base.js create mode 100644 web-ui/app/js/tags/ui/tag_list.js create mode 100644 web-ui/app/js/tags/ui/tag_shortcut.js create mode 100644 web-ui/app/js/user_alerts/ui/user_alerts.js create mode 100644 web-ui/app/js/views/i18n.js create mode 100644 web-ui/app/js/views/recipientListFormatter.js create mode 100644 web-ui/app/js/views/templates.js create mode 100644 web-ui/app/locales/en/translation.json create mode 100644 web-ui/app/locales/pt/translation.json create mode 100644 web-ui/app/locales/sv/translation.json create mode 100644 web-ui/app/robots.txt create mode 100644 web-ui/app/scss/_alerts.scss create mode 100644 web-ui/app/scss/_colors.scss create mode 100644 web-ui/app/scss/_compose.scss create mode 100644 web-ui/app/scss/_mascot.scss create mode 100644 web-ui/app/scss/_mixins.scss create mode 100644 web-ui/app/scss/_read.scss create mode 100644 web-ui/app/scss/_reply.scss create mode 100644 web-ui/app/scss/_security.scss create mode 100644 web-ui/app/scss/foundation.scss create mode 100644 web-ui/app/scss/main.scss create mode 100644 web-ui/app/scss/news-cycle.scss create mode 100644 web-ui/app/scss/opensans.scss create mode 100644 web-ui/app/scss/reset.scss create mode 100644 web-ui/app/scss/styles.scss create mode 100644 web-ui/app/templates/compose/compose_box.hbs create mode 100644 web-ui/app/templates/compose/fixed_recipient.hbs create mode 100644 web-ui/app/templates/compose/inline_box.hbs create mode 100644 web-ui/app/templates/compose/recipient_input.hbs create mode 100644 web-ui/app/templates/compose/recipients.hbs create mode 100644 web-ui/app/templates/compose/reply_section.hbs create mode 100644 web-ui/app/templates/mail_actions/actions_box.hbs create mode 100644 web-ui/app/templates/mail_actions/compose_trigger.hbs create mode 100644 web-ui/app/templates/mail_actions/pagination_trigger.hbs create mode 100644 web-ui/app/templates/mail_actions/refresh_trigger.hbs create mode 100644 web-ui/app/templates/mails/full_view.hbs create mode 100644 web-ui/app/templates/mails/mail_actions.hbs create mode 100644 web-ui/app/templates/mails/sent.hbs create mode 100644 web-ui/app/templates/mails/single.hbs create mode 100644 web-ui/app/templates/no_message_selected.hbs create mode 100644 web-ui/app/templates/search/search_trigger.hbs create mode 100644 web-ui/app/templates/tags/shortcut.hbs create mode 100644 web-ui/app/templates/tags/tag.hbs create mode 100644 web-ui/app/templates/tags/tag_inner.hbs create mode 100644 web-ui/app/templates/tags/tag_list.hbs create mode 100644 web-ui/app/templates/user_alerts/message.hbs (limited to 'web-ui/app') diff --git a/web-ui/app/404.html b/web-ui/app/404.html new file mode 100644 index 00000000..fdace4ab --- /dev/null +++ b/web-ui/app/404.html @@ -0,0 +1,157 @@ + + + + + Page Not Found :( + + + +
+

Not found :(

+

Sorry, but the page you were trying to view does not exist.

+

It looks like this was the result of either:

+ + + +
+ + diff --git a/web-ui/app/favicon.ico b/web-ui/app/favicon.ico new file mode 100644 index 00000000..e69de29b diff --git a/web-ui/app/fonts/NewsCycleBold.ttf b/web-ui/app/fonts/NewsCycleBold.ttf new file mode 100644 index 00000000..8265217f Binary files /dev/null and b/web-ui/app/fonts/NewsCycleBold.ttf differ diff --git a/web-ui/app/fonts/NewsCycleRegular.ttf b/web-ui/app/fonts/NewsCycleRegular.ttf new file mode 100644 index 00000000..9fbfd346 Binary files /dev/null and b/web-ui/app/fonts/NewsCycleRegular.ttf differ diff --git a/web-ui/app/fonts/OpenSans-Bold.woff b/web-ui/app/fonts/OpenSans-Bold.woff new file mode 100644 index 00000000..dacf3c9c Binary files /dev/null and b/web-ui/app/fonts/OpenSans-Bold.woff differ diff --git a/web-ui/app/fonts/OpenSans-BoldItalic.woff b/web-ui/app/fonts/OpenSans-BoldItalic.woff new file mode 100644 index 00000000..a4e29c0f Binary files /dev/null and b/web-ui/app/fonts/OpenSans-BoldItalic.woff differ diff --git a/web-ui/app/fonts/OpenSans-Extrabold.woff b/web-ui/app/fonts/OpenSans-Extrabold.woff new file mode 100644 index 00000000..7a2e352b Binary files /dev/null and b/web-ui/app/fonts/OpenSans-Extrabold.woff differ diff --git a/web-ui/app/fonts/OpenSans-ExtraboldItalic.woff b/web-ui/app/fonts/OpenSans-ExtraboldItalic.woff new file mode 100644 index 00000000..ce3ab2e7 Binary files /dev/null and b/web-ui/app/fonts/OpenSans-ExtraboldItalic.woff differ diff --git a/web-ui/app/fonts/OpenSans-Italic.woff b/web-ui/app/fonts/OpenSans-Italic.woff new file mode 100644 index 00000000..c5f6bac1 Binary files /dev/null and b/web-ui/app/fonts/OpenSans-Italic.woff differ diff --git a/web-ui/app/fonts/OpenSans-Light.woff b/web-ui/app/fonts/OpenSans-Light.woff new file mode 100644 index 00000000..eb601d70 Binary files /dev/null and b/web-ui/app/fonts/OpenSans-Light.woff differ diff --git a/web-ui/app/fonts/OpenSans-Semibold.woff b/web-ui/app/fonts/OpenSans-Semibold.woff new file mode 100644 index 00000000..56c44944 Binary files /dev/null and b/web-ui/app/fonts/OpenSans-Semibold.woff differ diff --git a/web-ui/app/fonts/OpenSans-SemiboldItalic.woff b/web-ui/app/fonts/OpenSans-SemiboldItalic.woff new file mode 100644 index 00000000..3a439fc3 Binary files /dev/null and b/web-ui/app/fonts/OpenSans-SemiboldItalic.woff differ diff --git a/web-ui/app/fonts/OpenSans.woff b/web-ui/app/fonts/OpenSans.woff new file mode 100644 index 00000000..77706fa6 Binary files /dev/null and b/web-ui/app/fonts/OpenSans.woff differ diff --git a/web-ui/app/fonts/OpenSansLight-Italic.woff b/web-ui/app/fonts/OpenSansLight-Italic.woff new file mode 100644 index 00000000..3f9f088f Binary files /dev/null and b/web-ui/app/fonts/OpenSansLight-Italic.woff differ diff --git a/web-ui/app/index.html b/web-ui/app/index.html new file mode 100644 index 00000000..568cff8a --- /dev/null +++ b/web-ui/app/index.html @@ -0,0 +1,84 @@ + + + + + +Pixelated Mail + + + + + + + + + + +
+
+ +
+
+ +
+
+ +
    +
+ +
+ +
+ +
+ +
+
+
+
+
+
+
+
+
+
    +
    + +
    +
      +
    +
    +
    + +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + diff --git a/web-ui/app/js/dispatchers/left_pane_dispatcher.js b/web-ui/app/js/dispatchers/left_pane_dispatcher.js new file mode 100644 index 00000000..8fd2b81d --- /dev/null +++ b/web-ui/app/js/dispatchers/left_pane_dispatcher.js @@ -0,0 +1,51 @@ +define( + [ + 'flight/lib/component', + 'page/router/url_params', + 'page/events' + ], + + function(defineComponent, urlParams, events) { + 'use strict'; + + return defineComponent(leftPaneDispatcher); + + function leftPaneDispatcher() { + var initialized = false; + + this.refreshTagList = function () { + this.trigger(document, events.tags.want, { caller: this.$node }); + }; + + this.loadTags = function (ev, data) { + this.trigger(document, events.ui.tagList.load, data); + }; + + this.selectTag = function (ev, data) { + var tag = (data && data.tag) || urlParams.getTag(); + this.trigger(document, events.ui.tag.select, { tag: tag }); + }; + + this.pushUrlState = function (ev, data) { + if (initialized) { + this.trigger(document, events.router.pushState, data); + } + initialized = true; + + if (data.skipMailListRefresh) { + return; + } + + this.trigger(document, events.ui.mails.fetchByTag, data); + }; + + this.after('initialize', function () { + this.on(this.$node, events.tags.received, this.loadTags); + this.on(document, events.dispatchers.tags.refreshTagList, this.refreshTagList); + this.on(document, events.ui.tags.loaded, this.selectTag); + this.on(document, events.ui.tag.selected, this.pushUrlState); + this.trigger(document, events.tags.want, { caller: this.$node } ); + }); + } + } +); diff --git a/web-ui/app/js/dispatchers/middle_pane_dispatcher.js b/web-ui/app/js/dispatchers/middle_pane_dispatcher.js new file mode 100644 index 00000000..26c32235 --- /dev/null +++ b/web-ui/app/js/dispatchers/middle_pane_dispatcher.js @@ -0,0 +1,36 @@ +define(['flight/lib/component', 'page/events', 'helpers/triggering'], function(defineComponent, events, triggering) { + 'use strict'; + + return defineComponent(function() { + this.defaultAttrs({ + middlePane: '#middle-pane' + }); + + this.refreshMailList = function (ev, data) { + this.trigger(document, events.ui.mails.fetchByTag, data); + }; + + this.cleanSelected = function(ev, data) { + this.trigger(document, events.ui.mails.cleanSelected); + }; + + this.resetScroll = function() { + this.select('middlePane').scrollTop(0); + }; + + this.updateMiddlePaneHeight = function() { + var vh = $(window).height(); + var top = $("#main").outerHeight() + $("#top-pane").outerHeight(); + this.select('middlePane').css({height: (vh - top) + 'px'}); + }; + + this.after('initialize', function () { + this.on(document, events.dispatchers.middlePane.refreshMailList, this.refreshMailList); + this.on(document, events.dispatchers.middlePane.cleanSelected, this.cleanSelected); + this.on(document, events.dispatchers.middlePane.resetScroll, this.resetScroll); + + this.updateMiddlePaneHeight(); + $(window).on('resize', this.updateMiddlePaneHeight.bind(this)); + }); + }); +}); diff --git a/web-ui/app/js/dispatchers/right_pane_dispatcher.js b/web-ui/app/js/dispatchers/right_pane_dispatcher.js new file mode 100644 index 00000000..3e62e581 --- /dev/null +++ b/web-ui/app/js/dispatchers/right_pane_dispatcher.js @@ -0,0 +1,93 @@ +/*global Smail */ + +define( + [ + 'flight/lib/component', + 'mail_view/ui/compose_box', + 'mail_view/ui/mail_view', + 'mail_view/ui/reply_section', + 'mail_view/ui/draft_box', + 'mail_view/ui/no_message_selected_pane', + 'page/events' + ], + + function(defineComponent, ComposeBox, MailView, ReplySection, DraftBox, NoMessageSelectedPane, events) { + 'use strict'; + + return defineComponent(rightPaneDispatcher); + + function rightPaneDispatcher() { + this.defaultAttrs({ + rightPane: '#right-pane', + composeBox: 'compose-box', + mailView: 'mail-view', + noMessageSelectedPane: 'no-message-selected-pane', + replySection: 'reply-section', + draftBox: 'draft-box', + currentTag: '' + }); + + this.createAndAttach = function(newContainer) { + var stage = $('
    ', { id: newContainer }); + this.select('rightPane').append(stage); + return stage; + }; + + this.reset = function (newContainer) { + this.trigger(document, events.dispatchers.rightPane.clear); + this.select('rightPane').empty(); + var stage = this.createAndAttach(newContainer); + return stage; + }; + + this.openComposeBox = function() { + var stage = this.reset(this.attr.composeBox); + ComposeBox.attachTo(stage, {currentTag: this.attr.currentTag}); + }; + + this.openMail = function(ev, data) { + var stage = this.reset(this.attr.mailView); + MailView.attachTo(stage, data); + + var replySectionContainer = this.createAndAttach(this.attr.replySection); + ReplySection.attachTo(replySectionContainer, { ident: data.ident }); + }; + + this.initializeNoMessageSelectedPane = function () { + var stage = this.reset(this.attr.noMessageSelectedPane); + NoMessageSelectedPane.attachTo(stage); + this.trigger(document, events.dispatchers.middlePane.cleanSelected); + }; + + this.openNoMessageSelectedPane = function(ev, data) { + this.initializeNoMessageSelectedPane(); + + this.trigger(document, events.router.pushState, { tag: this.attr.currentTag, isDisplayNoMessageSelected: true }); + }; + + this.openDraft = function (ev, data) { + var stage = this.reset(this.attr.draftBox); + DraftBox.attachTo(stage, { mailIdent: data.ident, currentTag: this.attr.currentTag }); + }; + + this.selectTag = function(ev, data) { + this.trigger(document, events.ui.tags.loaded, {tag: data.tag}); + }; + + this.saveTag = function(ev, data) { + this.attr.currentTag = data.tag; + }; + + this.after('initialize', function () { + this.on(document, events.dispatchers.rightPane.openComposeBox, this.openComposeBox); + this.on(document, events.dispatchers.rightPane.openDraft, this.openDraft); + this.on(document, events.ui.mail.open, this.openMail); + this.on(document, events.dispatchers.rightPane.openNoMessageSelected, this.openNoMessageSelectedPane); + this.on(document, events.dispatchers.rightPane.selectTag, this.selectTag); + this.on(document, events.ui.tag.selected, this.saveTag); + this.on(document, events.dispatchers.rightPane.openNoMessageSelectedWithoutPushState, this.initializeNoMessageSelectedPane); + this.initializeNoMessageSelectedPane(); + }); + } + } +); diff --git a/web-ui/app/js/foundation/off_canvas.js b/web-ui/app/js/foundation/off_canvas.js new file mode 100644 index 00000000..7dfd6f34 --- /dev/null +++ b/web-ui/app/js/foundation/off_canvas.js @@ -0,0 +1,21 @@ +define(['flight/lib/component', 'page/events'], function (defineComponent, events) { + + return defineComponent(function() { + + this.toggleSlider = function (){ + $('.off-canvas-wrap').foundation('offcanvas', 'toggle', 'move-right'); + }; + + this.closeSlider = function (){ + if ($('.off-canvas-wrap').attr('class').indexOf('move-right') > -1) { + $('.off-canvas-wrap').foundation('offcanvas', 'toggle', 'move-right'); + } + }; + + this.after('initialize', function () { + this.on($('.left-off-canvas-toggle'), 'click', this.toggleSlider); + this.on($('#middle-pane-container'), 'click', this.closeSlider); + this.on($('#right-pane'), 'click', this.closeSlider); + }); + }); +}); diff --git a/web-ui/app/js/helpers/contenttype.js b/web-ui/app/js/helpers/contenttype.js new file mode 100644 index 00000000..81519452 --- /dev/null +++ b/web-ui/app/js/helpers/contenttype.js @@ -0,0 +1,164 @@ +define([], function () { + var exports = {}; + + // Licence: PUBLIC DOMAIN + // Author: Austin Wright + + function MediaType(s, p){ + this.type = ''; + this.params = {}; + if(typeof s=='string'){ + var c = splitQuotedString(s); + this.type = c.shift(); + for(var i=0; i=0){ + offset = [delim,quote].reduce(findNextChar, 1/0); + if(offset===1/0) break; + switch(str[offset]){ + case quote: + // Skip to end of quoted string + while(1){ + offset=str.indexOf(quote, offset+1); + if(offset<0) break; + if(str[offset-1]==='\\') continue; + break; + } + continue; + case delim: + res.push(str.substr(start, offset-start).trim()); + start = ++offset; + break; + } + } + res.push(str.substr(start).trim()); + return res; + } + exports.splitQuotedString = splitQuotedString; + + // Split a list of content types found in an Accept header + // Maybe use it like: splitContentTypes(request.headers.accept).map(parseMedia) + function splitContentTypes(str){ + return splitQuotedString(str, ','); + } + exports.splitContentTypes = splitContentTypes; + + function parseMedia(str){ + var o = new MediaType(str); + if(o.q===undefined) o.q=1; + return o; + } + exports.parseMedia = parseMedia; + + // Pick an ideal representation to send given a list of representations to choose from and the client-preferred list + function select(reps, accept){ + var cr = {q:0}; + var ca = {q:0}; + var cq = 0; + for(var i=0; i=0){ + if(aq*rq>cq){ + ca = a; + cr = r; + cq = ca.q*cr.q; + if(cq===1 && cr.type) return cr; + } + } + } + } + return cr.type&&cr; + } + exports.select = select; + + // Determine if one media type is a subset of another + // If a is a superset of b (b is smaller than a), return 1 + // If b is a superset of a, return -1 + // If they are the exact same, return 0 + // If they are disjoint, return null + function mediaCmp(a, b){ + if(a.type==='*/*' && b.type!=='*/*') return 1; + else if(a.type!=='*/*' && b.type==='*/*') return -1; + var ac = (a.type||'').split('/'); + var bc = (b.type||'').split('/'); + if(ac[0]=='*' && bc[0]!='*') return 1; + if(ac[0]!='*' && bc[0]=='*') return -1; + if(a.type!==b.type) return null; + var ap = a.params || {}; + var bp = b.params || {}; + var ak = Object.keys(ap); + var bk = Object.keys(bp); + if(ak.length < bk.length) return 1; + if(ak.length > bk.length) return -1; + var k = ak.concat(bk).sort(); + var dir = 0; + for(var n in ap){ + if(ap[n] && !bp[n]){ if(dir<0) return null; else dir=1; } + if(!ap[n] && bp[n]){ if(dir>0) return null; else dir=-1; } + } + return dir; + } + exports.mediaCmp = mediaCmp; + + return exports; +}); diff --git a/web-ui/app/js/helpers/iterator.js b/web-ui/app/js/helpers/iterator.js new file mode 100644 index 00000000..9d8358a7 --- /dev/null +++ b/web-ui/app/js/helpers/iterator.js @@ -0,0 +1,43 @@ +define(function () { + + return Iterator; + + function Iterator(elems, startingIndex) { + + this.index = startingIndex || 0; + this.elems = elems; + + this.hasPrevious = function () { + return this.index != 0; + }; + + this.hasNext = function () { + return this.index < this.elems.length - 1; + }; + + this.previous = function () { + return this.elems[--this.index]; + }; + + this.next = function () { + return this.elems[++this.index]; + }; + + this.current = function () { + return this.elems[this.index]; + }; + + this.hasElements = function () { + return this.elems.length > 0; + }; + + this.removeCurrent = function () { + var removed = this.current(), + toRemove = this.index; + + !this.hasNext() && this.index--; + this.elems.remove(toRemove); + return removed; + }; + } +}); \ No newline at end of file diff --git a/web-ui/app/js/helpers/triggering.js b/web-ui/app/js/helpers/triggering.js new file mode 100644 index 00000000..7c8ae136 --- /dev/null +++ b/web-ui/app/js/helpers/triggering.js @@ -0,0 +1,13 @@ +define([], function() { + 'use strict'; + + return function(that, event, data, on) { + return function() { + if(on) { + that.trigger(on, event, data || {}); + } else { + that.trigger(event, data || {}); + } + }; + }; +}); diff --git a/web-ui/app/js/helpers/view_helper.js b/web-ui/app/js/helpers/view_helper.js new file mode 100644 index 00000000..3fa9edc1 --- /dev/null +++ b/web-ui/app/js/helpers/view_helper.js @@ -0,0 +1,145 @@ +define( + [ + 'helpers/contenttype', + 'lib/html_whitelister', + 'views/i18n', + 'quoted-printable/quoted-printable' + ], + function(contentType, htmlWhitelister, i18n_lib, quotedPrintable) { + 'use strict'; + + function formatStatusClasses(ss) { + return _.map(ss, function(s) { + return 'status-' + s; + }).join(' '); + } + + function addParagraphsToPlainText(plainTextBodyPart) { + return _.map(plainTextBodyPart.split('\n'), function (paragraph) { + return '

    ' + paragraph + '

    '; + }).join(''); + } + + function isQuotedPrintableBodyPart (bodyPart) { + return bodyPart.headers['Content-Transfer-Encoding'] && bodyPart.headers['Content-Transfer-Encoding'] === 'quoted-printable'; + } + + function getHtmlContentType (mail) { + return _.find(mail.availableBodyPartsContentType(), function (contentType) { + return contentType.indexOf('text/html') >= 0; + }); + } + + function getSanitizedAndDecodedMailBody (bodyPart) { + var body; + + if (isQuotedPrintableBodyPart(bodyPart)) { + body = quotedPrintable.decode(bodyPart.body); + } else { + body = bodyPart.body; + } + + return htmlWhitelister.sanitize(body, htmlWhitelister.tagPolicy); + } + + function formatMailBody (mail) { + if (mail.isMailMultipartAlternative()) { + var htmlContentType; + + htmlContentType = getHtmlContentType(mail); + + if (htmlContentType) { + return $(getSanitizedAndDecodedMailBody(mail.getMailPartByContentType(htmlContentType))); + } + + return $(addParagraphsToPlainText(mail.getMailMultiParts[0])); + } + + return $(addParagraphsToPlainText(mail.body)); + + /* + var body; + // probably parse MIME parts and ugliness here + // content_type: "multipart/alternative; boundary="----=_Part_1115_17865397.1370312509342"" + var mediaType = new contentType.MediaType(mail.header.content_type); + if(mediaType.type === 'multipart/alternative') { + var parsedBodyParts = getMailMultiParts(mail.body, mediaType); + var selectedBodyPart = getHtmlMailPart(parsedBodyParts) || getPlainTextMailPart(parsedBodyParts) || parsedBodyParts[0]; + body = selectedBodyPart.body; + + if (isQuotedPrintableBodyPart(selectedBodyPart)) { + body = quotedPrintable.decode(body); + } + } else { + body = addParagraphsToPlainText(mail.body); + } + return $(htmlWhitelister.sanitize(body, htmlWhitelister.tagPolicy)); + */ + } + + function moveCaretToEnd(el) { + if (typeof el.selectionStart == "number") { + el.selectionStart = el.selectionEnd = el.value.length; + } else if (typeof el.createTextRange != "undefined") { + el.focus(); + var range = el.createTextRange(); + range.collapse(false); + range.select(); + } + } + + function fixedSizeNumber(num, size) { + var res = num.toString(); + while(res.length < size) { + res = "0" + res; + } + return res; + } + + function getFormattedDate(date){ + var today = createTodayDate(); + if (date.getTime() > today.getTime()) { + return fixedSizeNumber(date.getHours(), 2) + ":" + fixedSizeNumber(date.getMinutes(), 2); + } else { + return "" + date.getFullYear() + "-" + fixedSizeNumber(date.getMonth() + 1, 2) + "-" + fixedSizeNumber(date.getDate(), 2); + } + } + + function createTodayDate() { + var today = new Date(); + today.setHours(0); + today.setMinutes(0); + today.setSeconds(0); + return today; + } + + function moveCaretToEndOfText() { + var self = this; + + moveCaretToEnd(self); + window.setTimeout(function() { + moveCaretToEnd(self); + }, 1); + } + + function quoteMail(mail) { + var quotedLines = _.map(mail.body.split('\n'), function (line) { + return '> ' + line; + }); + + return '\n\n' + quotedLines.join('\n'); + } + + function i18n(text) { + return i18n_lib.get(text); + } + + return { + formatStatusClasses: formatStatusClasses, + formatMailBody: formatMailBody, + moveCaretToEndOfText: moveCaretToEndOfText, + getFormattedDate: getFormattedDate, + quoteMail: quoteMail, + i18n: i18n + }; +}); diff --git a/web-ui/app/js/lib/highlightRegex.js b/web-ui/app/js/lib/highlightRegex.js new file mode 100644 index 00000000..17caaa23 --- /dev/null +++ b/web-ui/app/js/lib/highlightRegex.js @@ -0,0 +1,127 @@ +/* + * jQuery Highlight Regex Plugin v0.1.2 + * + * Based on highlight v3 by Johann Burkard + * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html + * + * (c) 2009-13 Jacob Rothstein + * MIT license + */ + +;(function( $ ) { + + + + var normalize = function( node ) { + if ( ! ( node && node.childNodes )) return + + var children = $.makeArray( node.childNodes ) + , prevTextNode = null + + $.each( children, function( i, child ) { + if ( child.nodeType === 3 ) { + if ( child.nodeValue === "" ) { + + node.removeChild( child ) + + } else if ( prevTextNode !== null ) { + + prevTextNode.nodeValue += child.nodeValue; + node.removeChild( child ) + + } else { + + prevTextNode = child + + } + } else { + prevTextNode = null + + if ( child.childNodes ) { + normalize( child ) + } + } + }) + } + + + + + $.fn.highlightRegex = function( regex, options ) { + + if ( typeof regex === 'object' && !(regex.constructor.name == 'RegExp' || regex instanceof RegExp ) ) { + options = regex + regex = undefined + } + + if ( typeof options === 'undefined' ) options = {} + + options.className = options.className || 'highlight' + options.tagType = options.tagType || 'span' + options.attrs = options.attrs || {} + + if ( typeof regex === 'undefined' || regex.source === '' ) { + + $( this ).find( options.tagType + '.' + options.className ).each( function() { + + $( this ).replaceWith( $( this ).text() ) + + normalize( $( this ).parent().get( 0 )) + + }) + + } else { + + $( this ).each( function() { + + var elt = $( this ).get( 0 ) + + normalize( elt ) + + $.each( $.makeArray( elt.childNodes ), function( i, searchnode ) { + + var spannode, middlebit, middleclone, pos, match, parent + + normalize( searchnode ) + + if ( searchnode.nodeType == 3 ) { + + // don't re-highlight the same node over and over + if ( $(searchnode).parent(options.tagType + '.' + options.className).length ) { + return; + } + + while ( searchnode.data && + ( pos = searchnode.data.search( regex )) >= 0 ) { + + match = searchnode.data.slice( pos ).match( regex )[ 0 ] + + if ( match.length > 0 ) { + + spannode = document.createElement( options.tagType ) + spannode.className = options.className + $(spannode).attr(options.attrs) + + parent = searchnode.parentNode + middlebit = searchnode.splitText( pos ) + searchnode = middlebit.splitText( match.length ) + middleclone = middlebit.cloneNode( true ) + + spannode.appendChild( middleclone ) + parent.replaceChild( spannode, middlebit ) + + } else break + } + + } else { + + $( searchnode ).highlightRegex( regex, options ) + + } + }) + }) + } + + return $( this ) + } +})( jQuery ); diff --git a/web-ui/app/js/lib/html-sanitizer.js b/web-ui/app/js/lib/html-sanitizer.js new file mode 100644 index 00000000..80fb0041 --- /dev/null +++ b/web-ui/app/js/lib/html-sanitizer.js @@ -0,0 +1,1064 @@ +// Copyright (C) 2006 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview + * An HTML sanitizer that can satisfy a variety of security policies. + * + *

    + * The HTML sanitizer is built around a SAX parser and HTML element and + * attributes schemas. + * + * If the cssparser is loaded, inline styles are sanitized using the + * css property and value schemas. Else they are remove during + * sanitization. + * + * If it exists, uses parseCssDeclarations, sanitizeCssProperty, cssSchema + * + * @author mikesamuel@gmail.com + * @author jasvir@gmail.com + * \@requires html4, URI + * \@overrides window + * \@provides html, html_sanitize + */ + +// The Turkish i seems to be a non-issue, but abort in case it is. +if ('I'.toLowerCase() !== 'i') { throw 'I/i problem'; } + +/** + * \@namespace + */ +define(['lib/html4-defs'], function (html4) { +var html = (function(html4) { + + // For closure compiler + var parseCssDeclarations, sanitizeCssProperty, cssSchema; + if ('undefined' !== typeof window) { + parseCssDeclarations = window['parseCssDeclarations']; + sanitizeCssProperty = window['sanitizeCssProperty']; + cssSchema = window['cssSchema']; + } + + // The keys of this object must be 'quoted' or JSCompiler will mangle them! + // This is a partial list -- lookupEntity() uses the host browser's parser + // (when available) to implement full entity lookup. + // Note that entities are in general case-sensitive; the uppercase ones are + // explicitly defined by HTML5 (presumably as compatibility). + var ENTITIES = { + 'lt': '<', + 'LT': '<', + 'gt': '>', + 'GT': '>', + 'amp': '&', + 'AMP': '&', + 'quot': '"', + 'apos': '\'', + 'nbsp': '\240' + }; + + // Patterns for types of entity/character reference names. + var decimalEscapeRe = /^#(\d+)$/; + var hexEscapeRe = /^#x([0-9A-Fa-f]+)$/; + // contains every entity per http://www.w3.org/TR/2011/WD-html5-20110113/named-character-references.html + var safeEntityNameRe = /^[A-Za-z][A-za-z0-9]+$/; + // Used as a hook to invoke the browser's entity parsing. + +{{> recipients }} + +

    + +
    + + + +
    +
    diff --git a/web-ui/app/templates/compose/fixed_recipient.hbs b/web-ui/app/templates/compose/fixed_recipient.hbs new file mode 100644 index 00000000..2f773c76 --- /dev/null +++ b/web-ui/app/templates/compose/fixed_recipient.hbs @@ -0,0 +1,6 @@ +
    + +
    {{ address }}
    +
    + +
    diff --git a/web-ui/app/templates/compose/inline_box.hbs b/web-ui/app/templates/compose/inline_box.hbs new file mode 100644 index 00000000..eb339c21 --- /dev/null +++ b/web-ui/app/templates/compose/inline_box.hbs @@ -0,0 +1,18 @@ +
    +

    {{subject}}

    + +
    + + + + {{t 'To'}}: {{formatRecipients recipients}} + + +{{> recipients }} + +
    + + + +
    +
    diff --git a/web-ui/app/templates/compose/recipient_input.hbs b/web-ui/app/templates/compose/recipient_input.hbs new file mode 100644 index 00000000..9416f11f --- /dev/null +++ b/web-ui/app/templates/compose/recipient_input.hbs @@ -0,0 +1 @@ + diff --git a/web-ui/app/templates/compose/recipients.hbs b/web-ui/app/templates/compose/recipients.hbs new file mode 100644 index 00000000..6ec29ae5 --- /dev/null +++ b/web-ui/app/templates/compose/recipients.hbs @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/web-ui/app/templates/compose/reply_section.hbs b/web-ui/app/templates/compose/reply_section.hbs new file mode 100644 index 00000000..9e833ffe --- /dev/null +++ b/web-ui/app/templates/compose/reply_section.hbs @@ -0,0 +1,6 @@ +
    + + + + +
    diff --git a/web-ui/app/templates/mail_actions/actions_box.hbs b/web-ui/app/templates/mail_actions/actions_box.hbs new file mode 100644 index 00000000..b6dc2f53 --- /dev/null +++ b/web-ui/app/templates/mail_actions/actions_box.hbs @@ -0,0 +1,6 @@ +
  • +
  • +
  • +
  • +
  • +
  • diff --git a/web-ui/app/templates/mail_actions/compose_trigger.hbs b/web-ui/app/templates/mail_actions/compose_trigger.hbs new file mode 100644 index 00000000..ccdb4df0 --- /dev/null +++ b/web-ui/app/templates/mail_actions/compose_trigger.hbs @@ -0,0 +1,3 @@ +
    + {{t 'compose' }} +
    diff --git a/web-ui/app/templates/mail_actions/pagination_trigger.hbs b/web-ui/app/templates/mail_actions/pagination_trigger.hbs new file mode 100644 index 00000000..cbd8a089 --- /dev/null +++ b/web-ui/app/templates/mail_actions/pagination_trigger.hbs @@ -0,0 +1,3 @@ + +{{ currentPage }} + diff --git a/web-ui/app/templates/mail_actions/refresh_trigger.hbs b/web-ui/app/templates/mail_actions/refresh_trigger.hbs new file mode 100644 index 00000000..68685442 --- /dev/null +++ b/web-ui/app/templates/mail_actions/refresh_trigger.hbs @@ -0,0 +1,3 @@ +
    + +
    diff --git a/web-ui/app/templates/mails/full_view.hbs b/web-ui/app/templates/mails/full_view.hbs new file mode 100644 index 00000000..a466308d --- /dev/null +++ b/web-ui/app/templates/mails/full_view.hbs @@ -0,0 +1,87 @@ + +
    + +
    + + + + +
    + +
    + + {{t signatureStatus }} + + + {{t encryptionStatus }} + +
    +
    + {{ header.formattedDate }} +
    +
    + + {{#if header.from }} + {{ header.from }} + {{else}} + {{t 'you'}} + {{/if}} + + + {{{formatRecipients header}}} +
    + +
    +

    + {{ header.subject }} + +
    +
      + {{#each tags }} +
    • {{ this }}
    • + {{/each }} + +
    • + +
    • +
    • + +
    • +
    +
    +

    + +
    + +
    +
    + +
    +

    {{t 'You are trying to delete the last tag on this message.'}}

    + +

    {{t 'What would you like to do?'}}

    + + + × + {{t 'Trash:'}} {{t 'we will keep this message for 30 days, then delete it forever.'}} + + + {{t 'Archive:'}} {{t 'we will remove all the tags, but keep it in your account in case you need it.'}} + +
    + +
    + {{#each body }} +

    {{ this }}

    + {{/each }} +
    +
    + diff --git a/web-ui/app/templates/mails/mail_actions.hbs b/web-ui/app/templates/mails/mail_actions.hbs new file mode 100644 index 00000000..8933db79 --- /dev/null +++ b/web-ui/app/templates/mails/mail_actions.hbs @@ -0,0 +1,6 @@ + + +
      +
    • {{t 'Reply to All'}}
    • +
    • {{t 'Trash this message'}}
    • +
    diff --git a/web-ui/app/templates/mails/sent.hbs b/web-ui/app/templates/mails/sent.hbs new file mode 100644 index 00000000..826a66d5 --- /dev/null +++ b/web-ui/app/templates/mails/sent.hbs @@ -0,0 +1,23 @@ + + + + + + {{ header.formattedDate }} + +
    {{t 'to:'}} {{#if header.to }}{{ + header.to }}{{else}}{{t 'no_recipient'}}{{/if}}
    +
    +
      + {{#each tagsForListView }} +
    • {{ this }}
    • + {{/each }} +
    + {{#if header.subject }} + {{header.subject}} + {{else}} + {{t 'no_subject'}} + {{/if}} +
    +
    +
    diff --git a/web-ui/app/templates/mails/single.hbs b/web-ui/app/templates/mails/single.hbs new file mode 100644 index 00000000..9a054c79 --- /dev/null +++ b/web-ui/app/templates/mails/single.hbs @@ -0,0 +1,19 @@ + + + + + + {{ header.formattedDate }} + +
    {{#if header.from }}{{ header.from }}{{else}}{{t "you"}}{{/if}}
    +
    +
      + {{#each tagsForListView }} +
    • {{ this }}
    • + {{/each }} +
    + + {{ header.subject }} +
    +
    +
    diff --git a/web-ui/app/templates/no_message_selected.hbs b/web-ui/app/templates/no_message_selected.hbs new file mode 100644 index 00000000..0442192d --- /dev/null +++ b/web-ui/app/templates/no_message_selected.hbs @@ -0,0 +1,3 @@ +
    +
    {{t 'NOTHING SELECTED'}}.
    +
    diff --git a/web-ui/app/templates/search/search_trigger.hbs b/web-ui/app/templates/search/search_trigger.hbs new file mode 100644 index 00000000..fbf24170 --- /dev/null +++ b/web-ui/app/templates/search/search_trigger.hbs @@ -0,0 +1,3 @@ +
    + +
    diff --git a/web-ui/app/templates/tags/shortcut.hbs b/web-ui/app/templates/tags/shortcut.hbs new file mode 100644 index 00000000..49ddfdb2 --- /dev/null +++ b/web-ui/app/templates/tags/shortcut.hbs @@ -0,0 +1,9 @@ +
  • + + {{#if displayBadge }} + {{ count }} + {{/if}} + +
    {{ tagName }}
    +
    +
  • \ No newline at end of file diff --git a/web-ui/app/templates/tags/tag.hbs b/web-ui/app/templates/tags/tag.hbs new file mode 100644 index 00000000..c645f782 --- /dev/null +++ b/web-ui/app/templates/tags/tag.hbs @@ -0,0 +1,3 @@ +
  • + {{> tag_inner }} +
  • diff --git a/web-ui/app/templates/tags/tag_inner.hbs b/web-ui/app/templates/tags/tag_inner.hbs new file mode 100644 index 00000000..2e0958cb --- /dev/null +++ b/web-ui/app/templates/tags/tag_inner.hbs @@ -0,0 +1,4 @@ +{{ tagName }} +{{#if displayBadge }} +{{ count }} +{{/if}} diff --git a/web-ui/app/templates/tags/tag_list.hbs b/web-ui/app/templates/tags/tag_list.hbs new file mode 100644 index 00000000..e2e97833 --- /dev/null +++ b/web-ui/app/templates/tags/tag_list.hbs @@ -0,0 +1,3 @@ +
      +

      {{t 'Tags'}}

      +
        diff --git a/web-ui/app/templates/user_alerts/message.hbs b/web-ui/app/templates/user_alerts/message.hbs new file mode 100644 index 00000000..d2fff04a --- /dev/null +++ b/web-ui/app/templates/user_alerts/message.hbs @@ -0,0 +1 @@ +{{ message }} -- cgit v1.2.3