48 | <%= post.getMessageRegexed() %>
49 |
├── src ├── app │ ├── img │ │ ├── .gitkeep │ │ ├── profile.jpg │ │ ├── icon-post.png │ │ ├── icon-check.png │ │ ├── icon-compose.png │ │ ├── icon-cross.png │ │ ├── icon-reply.png │ │ ├── icon-retwist.png │ │ └── icon-check-border.png │ ├── svg │ │ ├── .gitkeep │ │ ├── love.svg │ │ ├── eye.svg │ │ ├── oval.svg │ │ ├── twister.svg │ │ ├── mail.svg │ │ ├── retwist.svg │ │ └── settings.svg │ ├── modules │ │ └── .gitkeep │ ├── templates │ │ ├── .gitkeep │ │ ├── main-page.html │ │ ├── context-mentions.html │ │ ├── mentions.html │ │ ├── content-posts.html │ │ ├── notyetimplemented.html │ │ ├── start.html │ │ ├── create-account.html │ │ ├── content-post.html │ │ ├── following.html │ │ ├── feed.html │ │ ├── content-feed.html │ │ ├── overlay-login.html │ │ ├── context-feed.html │ │ ├── overlay-accounts.html │ │ ├── post-detail.html │ │ ├── settings.html │ │ ├── context-user.html │ │ ├── main-menu.html │ │ ├── preview-post.html │ │ ├── user-detail.html │ │ ├── post.html │ │ └── status.html │ ├── styles │ │ ├── section-content.less │ │ ├── post-detail.less │ │ ├── reset.less │ │ ├── section-preview.less │ │ ├── feed.less │ │ ├── following.less │ │ ├── common.less │ │ ├── start.less │ │ ├── settings.less │ │ ├── context-feed.less │ │ ├── section-context.less │ │ ├── layout.less │ │ ├── form.less │ │ ├── accounts-overlay.less │ │ ├── popup.less │ │ ├── context-user.less │ │ ├── main-menu.less │ │ ├── fonts.less │ │ ├── overlay.less │ │ ├── user-detail.less │ │ ├── main.less │ │ ├── preview-post.less │ │ ├── status.less │ │ └── posts.less │ ├── config.js │ ├── fonts │ │ ├── OpenSans-Bold.ttf │ │ ├── OpenSans-Italic.ttf │ │ ├── OpenSans-Light.ttf │ │ ├── OpenSans-Regular.ttf │ │ ├── OpenSans-Semibold.ttf │ │ ├── OpenSans-BoldItalic.ttf │ │ ├── OpenSans-ExtraBold.ttf │ │ ├── OpenSans-LightItalic.ttf │ │ ├── OpenSans-ExtraBoldItalic.ttf │ │ └── OpenSans-SemiboldItalic.ttf │ ├── collections │ │ ├── posts.js │ │ └── users.js │ ├── views │ │ ├── MentionsContext.js │ │ ├── NotYetImplemented.js │ │ ├── Overlay.js │ │ ├── Popup.js │ │ ├── FeedContext.js │ │ ├── PostContent.js │ │ ├── Settings.js │ │ ├── SlideOverlay.js │ │ ├── ConfirmPopup.js │ │ ├── UserContext.js │ │ ├── Status.js │ │ ├── AccountsOverlay.js │ │ ├── LoginOverlay.js │ │ ├── CreateAccount.js │ │ ├── MainMenu.js │ │ ├── Mentions.js │ │ ├── UserContent.js │ │ ├── Following.js │ │ ├── PostPreview.js │ │ ├── MainPage.js │ │ ├── User.js │ │ ├── Post.js │ │ ├── Start.js │ │ ├── FeedContent.js │ │ └── Feed.js │ ├── app.js │ ├── main.js │ ├── models │ │ ├── Info.js │ │ ├── Feed.js │ │ ├── User.js │ │ └── Post.js │ └── router.js ├── icon.ico ├── favicon.png ├── package.json └── index.html ├── twister-data └── .gitkeep ├── package.json ├── .gitignore ├── LICENSE.txt ├── Gruntfile.js └── README.md /src/app/img/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/svg/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /twister-data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/modules/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/templates/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/styles/section-content.less: -------------------------------------------------------------------------------- 1 | #content-section { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/icon.ico -------------------------------------------------------------------------------- /src/app/templates/main-page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/favicon.png -------------------------------------------------------------------------------- /src/app/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | DEFAULT_AVATAR: 'app/img/profile.jpg' 3 | } 4 | -------------------------------------------------------------------------------- /src/app/img/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/img/profile.jpg -------------------------------------------------------------------------------- /src/app/img/icon-post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/img/icon-post.png -------------------------------------------------------------------------------- /src/app/templates/context-mentions.html: -------------------------------------------------------------------------------- 1 |
Twists which mentioned you.
3 | -------------------------------------------------------------------------------- /src/app/img/icon-check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/img/icon-check.png -------------------------------------------------------------------------------- /src/app/img/icon-compose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/img/icon-compose.png -------------------------------------------------------------------------------- /src/app/img/icon-cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/img/icon-cross.png -------------------------------------------------------------------------------- /src/app/img/icon-reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/img/icon-reply.png -------------------------------------------------------------------------------- /src/app/img/icon-retwist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/img/icon-retwist.png -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-Italic.ttf -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-Light.ttf -------------------------------------------------------------------------------- /src/app/img/icon-check-border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/img/icon-check-border.png -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-Semibold.ttf -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-BoldItalic.ttf -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-ExtraBold.ttf -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-LightItalic.ttf -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /src/app/fonts/OpenSans-SemiboldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArcoMul/Twisting/HEAD/src/app/fonts/OpenSans-SemiboldItalic.ttf -------------------------------------------------------------------------------- /src/app/templates/mentions.html: -------------------------------------------------------------------------------- 1 |Sorry, this page is not yet implemented...
5 |Live feed of the Twists of all the accounts you follow
4 | 5 |There were 24 Twists posted in your feed, where 2 mentioned you. 3 Accounts followed you, and you received 5 messages
7 | 8 | <% if (options.tags && _.size(options.tags) > 0) { %> 9 |11 | <% _.each(options.tags, function (tag) { %> 12 | #<%= tag %> 13 | <% }) %> 14 |
15 | <% } %> 16 |
13 | <% } %>
14 | Feed
checked="true"<%}%> /> Hide replies and retwists
Network status
Account
14 | @<%= username %>
15 | Add account
16 | Switch account
17 |
Support
For support and connection problems, open an issue at the Twisting Github repository
<%= user.get('following').length %> Following
12 | <% } %> 13 | <% if (app.user.isFollowing(user.get('username'))) { %> 14 | 15 | <% } else { %> 16 | 17 | <% } %> 18 | <% if (user.get('location')) { %> 19 |<%= user.get('location') %>
20 | <% } %> 21 | <% if (user.get('bio')) { %> 22 |<%= user.get('bio') %>
23 | <% } %> 24 |' 31 | +this.options.texts.main 32 | +'
' 37 | +this.options.texts.main 38 | +'
For support and connection problems, open an issue at the Twisting Github repository
66 |Loading
73 | <% } %> 74 |
';
241 | }
242 | }
243 | });
244 |
--------------------------------------------------------------------------------
/src/app/models/Post.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // External dependencies.
4 | var $ = require("jquery"),
5 | Backbone = require("backbone"),
6 | _ = require("underscore"),
7 | Twister = require("../Twister"),
8 | app = require("../app"),
9 | twemoji = require('twemoji'),
10 | moment = require("moment");
11 |
12 | Backbone.$ = $;
13 |
14 | var TYPES = {
15 | RETWIST: 'retwist',
16 | REPLY: 'reply',
17 | POST: 'post',
18 | COMPOSE: 'compose',
19 | COMPOSE_REPLY: 'compose_reply',
20 | };
21 |
22 | // Defining the application router.
23 | var PostModel = module.exports = Backbone.Model.extend({
24 | defaults: {
25 | twister_id: null,
26 | message: null,
27 | time: null,
28 | last_time: null,
29 | user: null,
30 | retwist: null,
31 | retwisters: [],
32 | replies: [],
33 | lovers: []
34 | },
35 |
36 | initialize: function (properties) {
37 | if (!properties || !properties.retwisters) this.set('retwisters', []);
38 | if (!properties || !properties.replies) this.set('replies', []);
39 | if (!properties || !properties.lovers) this.set('lovers', []);
40 | },
41 |
42 | /**
43 | * data = Twister post data
44 | * users = user collection to retrieve users from
45 | */
46 | parse: function (data, users) {
47 | var item = data.userpost,
48 | user;
49 |
50 | if (!users.findWhere) {
51 | user = users;
52 | } else {
53 | user = users.findWhere({username: item.n});
54 | }
55 |
56 | // Maybe the user doens't excist yet when we are parsing a
57 | // parent post of a reply for example
58 | if (!user) {
59 | user = users.newUser({username: item.n, isFollowing: false});
60 | }
61 |
62 | if(item.rt) {
63 | var retwistUser = users.findWhere({username: item.rt.n});
64 |
65 | // Update the lowest_id and last_twister_id of the retwisting user,
66 | // since there is further no trace of this 'post' of the retwisting user
67 | user.processTwisterIdsOfPost(item.k, item.lastk);
68 |
69 | // If this is a retwist we might not know the user
70 | // in that case add it to the list of users
71 | if (!retwistUser) {
72 | retwistUser = users.newUser({username: item.rt.n, isFollowing: false});
73 | } else {
74 | // Check if post is already known
75 | var post = retwistUser.get('posts').findWhere({id: retwistUser.get('username') + '_' + item.rt.k});
76 | if (post) {
77 | user.addRetwist(post);
78 | post.setLastTime(item.time);
79 | post.addRetwister(user);
80 | return post;
81 | }
82 | }
83 |
84 | // Build the retwist post model
85 | var retwist = new PostModel({
86 | id: retwistUser.get('username') + '_' + item.rt.k,
87 | signature: item.sig_rt,
88 | height: item.rt.height,
89 | user: retwistUser,
90 | message: item.rt.msg,
91 | time: item.rt.time,
92 | last_time: item.time,
93 | last_rt_time: item.time,
94 | twister_id: item.rt.k,
95 | last_twister_id: item.rt.lastk,
96 | retwisters: [user]
97 | });
98 |
99 | // The the post as an post of the original poster
100 | retwistUser.addPost(retwist);
101 |
102 | user.addRetwist(retwist);
103 |
104 | // Return the retwist as if it is an original twist
105 | return retwist;
106 | }
107 |
108 | this.set({
109 | id: user.get('username') + '_' + item.k,
110 | signature: data.sig_userpost,
111 | height: item.height,
112 | user: user,
113 | message: item.msg,
114 | time: item.time,
115 | last_time: item.time,
116 | retwist: retwist,
117 | reply: item.reply ? {username: item.reply.n, twister_id: item.reply.k} : undefined,
118 | twister_id: item.k,
119 | last_twister_id: item.lastk
120 | });
121 |
122 | user.addPost(this);
123 |
124 | return this;
125 | },
126 |
127 |
128 | reply: function (user, msg, callback) {
129 | var self = this;
130 | Twister.reply(user.get('username'), msg, this.get('user').get('username'), this.get('twister_id'), function (err, data) {
131 | if (err) return callback (err);
132 | var reply = new PostModel().parse(data, user);
133 | var replies = self.get('replies');
134 | replies.push(reply);
135 | self.set('replies', replies);
136 | callback(null, reply);
137 | });
138 | },
139 |
140 | addRetwister: function (user) {
141 | var retwisters = this.get('retwisters');
142 | if (retwisters.indexOf(user) !== -1) {
143 | return;
144 | }
145 | user.fetchAvatarFromDisk();
146 | retwisters.push(user);
147 | this.set('retwisters', retwisters);
148 | },
149 |
150 | setLastTime: function (time) {
151 | if (time > this.get('last_time')) {
152 | this.set('last_time', time);
153 | }
154 | },
155 |
156 | getMessageRegexed: function () {
157 | if (!this.get('message')) return "";
158 | var msg = this.get('message');
159 | // Html
160 | msg = msg.replace(//g, ">");
161 | // Urls
162 | msg = msg.replace( /(https?:\/\/[^\s]+)/g, function(url) { return ''+url+'' });
163 | // Hashtags
164 | msg = msg.replace( /(^|[^#\w])#(\w{1,30})\b/g, '$1#$2' );
165 | // Mentions
166 | msg = msg.replace( /(^|[^@\w])@(\w{1,30})\b/g, '$1$2' );
167 | // Emojis
168 | msg = twemoji.parse(msg, {
169 | base: '',
170 | folder: 'node_modules/twemoji/svg',
171 | ext: '.svg'
172 | });
173 | // Breaks / enters
174 | msg = msg.replace(/(?:\r\n|\r|\n)/g, '