summaryrefslogtreecommitdiff
path: root/addons/website_twitter/static
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/website_twitter/static
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/website_twitter/static')
-rw-r--r--addons/website_twitter/static/description/icon.pngbin0 -> 6432 bytes
-rw-r--r--addons/website_twitter/static/description/icon.svg1
-rw-r--r--addons/website_twitter/static/src/img/api_key.pngbin0 -> 39304 bytes
-rw-r--r--addons/website_twitter/static/src/img/loadtweet.gifbin0 -> 16060 bytes
-rw-r--r--addons/website_twitter/static/src/js/website.twitter.animation.js186
-rw-r--r--addons/website_twitter/static/src/js/website.twitter.editor.js68
-rw-r--r--addons/website_twitter/static/src/scss/website_twitter.scss109
-rw-r--r--addons/website_twitter/static/src/xml/website.twitter.xml45
8 files changed, 409 insertions, 0 deletions
diff --git a/addons/website_twitter/static/description/icon.png b/addons/website_twitter/static/description/icon.png
new file mode 100644
index 00000000..09bb7eb5
--- /dev/null
+++ b/addons/website_twitter/static/description/icon.png
Binary files differ
diff --git a/addons/website_twitter/static/description/icon.svg b/addons/website_twitter/static/description/icon.svg
new file mode 100644
index 00000000..384aebf0
--- /dev/null
+++ b/addons/website_twitter/static/description/icon.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="70" height="70" viewBox="0 0 70 70"><defs><path id="a" d="M4 0h61c4 0 5 1 5 5v60c0 4-1 5-5 5H4c-3 0-4-1-4-5V5c0-4 1-5 4-5z"/><linearGradient id="c" x1="100%" x2="0%" y1="0%" y2="100%"><stop offset="0%" stop-color="#B06161"/><stop offset="45.785%" stop-color="#984E4E"/><stop offset="100%" stop-color="#7C3838"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M0 0H70V70H0z"/><path fill="#FFF" fill-opacity=".383" d="M4 1h61c2.667 0 4.333.667 5 2V0H0v3c.667-1.333 2-2 4-2z"/><path fill="#393939" d="M4 69c-2 0-4-1-4-4V41.016L12 28l4 4 6-4 5 5 6-6h20l6 16-16.49 26H4z" opacity=".324"/><path fill="#000" fill-opacity=".383" d="M4 69h61c2.667 0 4.333-1 5-3v4H0v-4c.667 2 2 3 4 3z"/><path fill="#000" d="M33 29h26v16H29c4.667-7.333 6-12.667 4-16zm11 4l-4 4 4 4 1-1-3-3 3-3-1-1zm4 0l-1 1 3 3-3 3 1 1 4-4-4-4zm-19.056-.074c.013.178.013.356.013.533 0 5.42-4.124 11.663-11.663 11.663-2.322 0-4.48-.673-6.294-1.84.33.038.647.05.99.05 1.916 0 3.68-.647 5.089-1.75a4.106 4.106 0 0 1-3.833-2.843c.254.038.508.063.774.063.368 0 .736-.05 1.079-.14a4.1 4.1 0 0 1-3.287-4.022v-.051c.546.304 1.18.495 1.853.52a4.096 4.096 0 0 1-1.827-3.414c0-.761.203-1.459.558-2.068a11.651 11.651 0 0 0 8.452 4.29 4.627 4.627 0 0 1-.102-.94 4.097 4.097 0 0 1 4.1-4.099 4.09 4.09 0 0 1 2.994 1.295 8.07 8.07 0 0 0 2.602-.99 4.088 4.088 0 0 1-1.802 2.259 8.217 8.217 0 0 0 2.36-.635 8.811 8.811 0 0 1-2.056 2.12z" opacity=".3"/><path fill="#FFF" d="M33 27h26v16H29c4.667-7.333 6-12.667 4-16zm11 4l-4 4 4 4 1-1-3-3 3-3-1-1zm4 0l-1 1 3 3-3 3 1 1 4-4-4-4zm-19.056-.074c.013.178.013.356.013.533 0 5.42-4.124 11.663-11.663 11.663-2.322 0-4.48-.673-6.294-1.84.33.038.647.05.99.05 1.916 0 3.68-.647 5.089-1.75a4.106 4.106 0 0 1-3.833-2.843c.254.038.508.063.774.063.368 0 .736-.05 1.079-.14a4.1 4.1 0 0 1-3.287-4.022v-.051c.546.304 1.18.495 1.853.52a4.096 4.096 0 0 1-1.827-3.414c0-.761.203-1.459.558-2.068a11.651 11.651 0 0 0 8.452 4.29 4.627 4.627 0 0 1-.102-.94 4.097 4.097 0 0 1 4.1-4.099 4.09 4.09 0 0 1 2.994 1.295 8.07 8.07 0 0 0 2.602-.99 4.088 4.088 0 0 1-1.802 2.259 8.217 8.217 0 0 0 2.36-.635 8.811 8.811 0 0 1-2.056 2.12z"/></g></g></svg> \ No newline at end of file
diff --git a/addons/website_twitter/static/src/img/api_key.png b/addons/website_twitter/static/src/img/api_key.png
new file mode 100644
index 00000000..8f53f964
--- /dev/null
+++ b/addons/website_twitter/static/src/img/api_key.png
Binary files differ
diff --git a/addons/website_twitter/static/src/img/loadtweet.gif b/addons/website_twitter/static/src/img/loadtweet.gif
new file mode 100644
index 00000000..f8a0a617
--- /dev/null
+++ b/addons/website_twitter/static/src/img/loadtweet.gif
Binary files differ
diff --git a/addons/website_twitter/static/src/js/website.twitter.animation.js b/addons/website_twitter/static/src/js/website.twitter.animation.js
new file mode 100644
index 00000000..295ae199
--- /dev/null
+++ b/addons/website_twitter/static/src/js/website.twitter.animation.js
@@ -0,0 +1,186 @@
+odoo.define('website_twitter.animation', function (require) {
+'use strict';
+
+var core = require('web.core');
+var publicWidget = require('web.public.widget');
+
+var qweb = core.qweb;
+
+publicWidget.registry.twitter = publicWidget.Widget.extend({
+ selector: '.twitter',
+ xmlDependencies: ['/website_twitter/static/src/xml/website.twitter.xml'],
+ disabledInEditableMode: false,
+ events: {
+ 'mouseenter .wrap-row': '_onEnterRow',
+ 'mouseleave .wrap-row': '_onLeaveRow',
+ 'click .twitter_timeline .tweet': '_onTweetClick',
+ },
+
+ /**
+ * @override
+ */
+ start: function () {
+ var self = this;
+ var $timeline = this.$('.twitter_timeline');
+
+ $timeline.append('<center><div><img src="/website_twitter/static/src/img/loadtweet.gif"></div></center>');
+ var def = this._rpc({route: '/website_twitter/get_favorites'}).then(function (data) {
+ $timeline.empty();
+
+ if (data.error) {
+ $timeline.append(qweb.render('website.Twitter.Error', {data: data}));
+ return;
+ }
+
+ if (_.isEmpty(data)) {
+ return;
+ }
+
+ var tweets = _.map(data, function (tweet) {
+ // Parse tweet date
+ if (_.isEmpty(tweet.created_at)) {
+ tweet.created_at = '';
+ } else {
+ var v = tweet.created_at.split(' ');
+ var d = new Date(Date.parse(v[1]+' '+v[2]+', '+v[5]+' '+v[3]+' UTC'));
+ tweet.created_at = d.toDateString();
+ }
+
+ // Parse tweet text
+ tweet.text = tweet.text
+ .replace(
+ /[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&~\?\/.=]+/g,
+ function (url) {
+ return _makeLink(url, url);
+ }
+ )
+ .replace(
+ /[@]+[A-Za-z0-9_]+/g,
+ function (screen_name) {
+ return _makeLink('http://twitter.com/' + screen_name.replace('@', ''), screen_name);
+ }
+ )
+ .replace(
+ /[#]+[A-Za-z0-9_]+/g,
+ function (hashtag) {
+ return _makeLink('http://twitter.com/search?q='+hashtag.replace('#',''), hashtag);
+ }
+ );
+
+ return qweb.render('website.Twitter.Tweet', {tweet: tweet});
+
+ function _makeLink(url, text) {
+ var c = $('<a/>', {
+ text: text,
+ href: url,
+ target: '_blank',
+ rel: 'noreferrer noopener',
+ });
+ return c.prop('outerHTML');
+ }
+ });
+
+ var f = Math.floor(tweets.length / 3);
+ var tweetSlices = [tweets.slice(0, f).join(' '), tweets.slice(f, f * 2).join(' '), tweets.slice(f * 2, tweets.length).join(' ')];
+
+ self.$scroller = $(qweb.render('website.Twitter.Scroller')).appendTo($timeline);
+ _.each(self.$scroller.find('div[id^="scroller"]'), function (element, index) {
+ var $scrollWrapper = $('<div/>', {class: 'scrollWrapper'});
+ var $scrollableArea = $('<div/>', {class: 'scrollableArea'});
+ $scrollWrapper.append($scrollableArea)
+ .data('scrollableArea', $scrollableArea);
+ $scrollableArea.append(tweetSlices[index]);
+ $(element).append($scrollWrapper);
+ var totalWidth = 0;
+ _.each($scrollableArea.children(), function (area) {
+ totalWidth += $(area).outerWidth(true);
+ });
+ $scrollableArea.width(totalWidth);
+ $scrollWrapper.scrollLeft(index*180);
+ });
+ self._startScrolling();
+ });
+
+ return Promise.all([this._super.apply(this, arguments), def]);
+ },
+ /**
+ * @override
+ */
+ destroy: function () {
+ this._stopScrolling();
+ this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ _startScrolling: function () {
+ if (!this.$scroller) {
+ return;
+ }
+ _.each(this.$scroller.find('.scrollWrapper'), function (el) {
+ var $wrapper = $(el);
+ $wrapper.data('getNextElementWidth', true);
+ $wrapper.data('autoScrollingInterval', setInterval(function () {
+ $wrapper.scrollLeft($wrapper.scrollLeft() + 1);
+ if ($wrapper.data('getNextElementWidth')) {
+ $wrapper.data('swapAt', $wrapper.data('scrollableArea').children(':first').outerWidth(true));
+ $wrapper.data('getNextElementWidth', false);
+ }
+ if ($wrapper.data('swapAt') <= $wrapper.scrollLeft()) {
+ var swap_el = $wrapper.data('scrollableArea').children(':first').detach();
+ $wrapper.data('scrollableArea').append(swap_el);
+ $wrapper.scrollLeft($wrapper.scrollLeft() - swap_el.outerWidth(true));
+ $wrapper.data('getNextElementWidth', true);
+ }
+ }, 20));
+ });
+ },
+ /**
+ * @private
+ */
+ _stopScrolling: function (wrapper) {
+ if (!this.$scroller) {
+ return;
+ }
+ _.each(this.$scroller.find('.scrollWrapper'), function (el) {
+ var $wrapper = $(el);
+ clearInterval($wrapper.data('autoScrollingInterval'));
+ });
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ _onEnterRow: function () {
+ this._stopScrolling();
+ },
+ /**
+ * @private
+ */
+ _onLeaveRow: function () {
+ this._startScrolling();
+ },
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onTweetClick: function (ev) {
+ if (ev.target.tagName === 'A') {
+ return;
+ }
+ var url = $(ev.currentTarget).data('url');
+ if (url) {
+ window.open(url, '_blank');
+ }
+ },
+});
+});
diff --git a/addons/website_twitter/static/src/js/website.twitter.editor.js b/addons/website_twitter/static/src/js/website.twitter.editor.js
new file mode 100644
index 00000000..bc9a38a4
--- /dev/null
+++ b/addons/website_twitter/static/src/js/website.twitter.editor.js
@@ -0,0 +1,68 @@
+odoo.define('website_twitter.editor', function (require) {
+'use strict';
+
+var core = require('web.core');
+var dom = require('web.dom');
+var sOptions = require('web_editor.snippets.options');
+
+var _t = core._t;
+
+sOptions.registry.twitter = sOptions.Class.extend({
+ /**
+ * @override
+ */
+ start: function () {
+ var self = this;
+ var $configuration = dom.renderButton({
+ attrs: {
+ class: 'btn-primary d-none',
+ contenteditable: 'false',
+ },
+ text: _t("Reload"),
+ });
+ $configuration.appendTo(document.body).on('click', function (ev) {
+ ev.preventDefault();
+ ev.stopPropagation();
+ self._rpc({route: '/website_twitter/reload'});
+ });
+ this.$target.on('mouseover.website_twitter', function () {
+ var $selected = $(this);
+ var position = $selected.offset();
+ $configuration.removeClass('d-none').offset({
+ top: $selected.outerHeight() / 2
+ + position.top
+ - $configuration.outerHeight() / 2,
+ left: $selected.outerWidth() / 2
+ + position.left
+ - $configuration.outerWidth() / 2,
+ });
+ }).on('mouseleave.website_twitter', function (e) {
+ var current = document.elementFromPoint(e.clientX, e.clientY);
+ if (current === $configuration[0]) {
+ return;
+ }
+ $configuration.addClass('d-none');
+ });
+ this.$target.on('click.website_twitter', '.lnk_configure', function (e) {
+ window.location = e.currentTarget.href;
+ });
+ this.trigger_up('widgets_stop_request', {
+ $target: this.$target,
+ });
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
+ cleanForSave: function () {
+ this.$target.find('.twitter_timeline').empty();
+ },
+ /**
+ * @override
+ */
+ destroy: function () {
+ this._super.apply(this, arguments);
+ this.$target.off('.website_twitter');
+ },
+});
+});
diff --git a/addons/website_twitter/static/src/scss/website_twitter.scss b/addons/website_twitter/static/src/scss/website_twitter.scss
new file mode 100644
index 00000000..301b5dab
--- /dev/null
+++ b/addons/website_twitter/static/src/scss/website_twitter.scss
@@ -0,0 +1,109 @@
+.wrap-row {
+ position: relative;
+ overflow: hidden;
+ height: 310px;
+ .twitter-row {
+ position: absolute;
+ width: 100%;
+ height: auto;
+ div {
+ &.scrollWrapper {
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+ height: 100%;
+ }
+ &.scrollableArea {
+ position: relative;
+ width: auto;
+ height: 100%;
+ }
+ .tweet {
+ border: 1px solid #ccc;
+ max-width: 500px;
+ width: 500px;
+ font-size: 0.8em;
+ padding-top: 12px;
+ padding-right: 10px;
+ padding-bottom: 12px;
+ padding-left: 10px;
+ float: left;
+ display: block;
+ margin: 6px;
+ max-height: 90px;
+ height: 90px;
+ opacity: 0.6;
+ h4, p {
+ padding: 0;
+ margin: 0;
+ }
+ .left {
+ display: block;
+ float: left;
+ width: 80px;
+ img {
+ width: 65px;
+ height: auto;
+ float: left;
+ display: block;
+ margin: 0px 5px 0px -5px;
+ }
+ }
+ .right {
+ display: block;
+ float: left;
+ width: 470px;
+ .top {
+ height: 20px;
+ }
+ }
+ h4 {
+ font-size: 14px;
+ font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
+ font-weight: bold;
+ color: #000;
+ float: left;
+ display: block;
+ position: relative;
+ margin-left: 70px;
+ margin-top: -65px;
+ span {
+ color: #ccc;
+ font-weight: bold;
+ font-size: 14px;
+ }
+ }
+ p {
+ line-height: 1.5em;
+ float: left;
+ position: relative;
+ display: block;
+ &.date {
+ float: right;
+ line-height: 0.5em;
+ margin-top: -60px;
+ margin-right: -10px;
+ }
+ }
+ .right .bottom p {
+ margin-top: -65px;
+ margin-left: 70px;
+ font-size: 12px;
+ word-break: break-word;
+ }
+ &:hover {
+ box-shadow: 0.5px 0.5px 0.5px 1px #428BCA;
+ cursor: pointer;
+ opacity: 1;
+ }
+ }
+ }
+ }
+}
+@media screen and (max-width: 580px) {
+ .wrap-row {
+ position: relative;
+ overflow: hidden;
+ height: 100px;
+ }
+}
diff --git a/addons/website_twitter/static/src/xml/website.twitter.xml b/addons/website_twitter/static/src/xml/website.twitter.xml
new file mode 100644
index 00000000..e6ceb3cc
--- /dev/null
+++ b/addons/website_twitter/static/src/xml/website.twitter.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates id="template" xml:space="preserve">
+ <t t-name="website.Twitter.Tweet">
+ <div class="tweet" t-attf-data-url="http://twitter.com/#{tweet.user.screen_name}/status/#{tweet.id_str}" t-attf-data-tweet-id="#{tweet.id_str}">
+ <div class="left">
+ <img t-att-src="tweet.user.profile_image_url_https" alt="Twitter's user"/>
+ </div>
+ <div class="right">
+ <div class="top">
+ <h4>
+ <t t-esc="tweet.user.name"/>
+ <span>
+ <a t-att-href="'https://twitter.com/' + tweet.user.screen_name" target="_blank"><t t-esc="'@' + tweet.user.screen_name "/></a>
+ </span>
+ </h4>
+ <a class="date" target="_blank" t-attf-href="http://twitter.com/#{tweet.user.screen_name}/status/#{tweet.id_str}"><t t-esc="tweet.created_at"/></a>
+ </div>
+ <div class="bottom">
+ <p><t t-raw="tweet.text"/></p>
+ </div>
+ </div>
+ </div>
+ </t>
+ <t t-name="website.Twitter.Scroller">
+ <div class="wrap-row" contenteditable="false">
+ <div class="twitter-row">
+ <div class="twitter-scroller">
+ <div id="scroller1"/>
+ <div id="scroller2"/>
+ <div id="scroller3"/>
+ </div>
+ </div>
+ </div>
+ </t>
+ <t t-name="website.Twitter.Error">
+ <div class="container" contenteditable="false">
+ <div class="alert alert-warning" role="alert">
+ <t t-esc="data.error"/>
+ <t t-if='!data.nodata'>
+ <a class="lnk_configure" href="/web#action=website.action_website_configuration"><i class="fa fa-plus-circle"/> Twitter Configuration</a>
+ </t>
+ </div>
+ </div>
+ </t>
+</templates>