|
1 | | -// @ts-nocheck |
2 | 1 | import "@hotwired/turbo-rails"; |
3 | 2 | import "@rails/activestorage"; |
4 | 3 | import "jquery"; |
| 4 | +// @ts-expect-error — Bootstrap 3 has no type declarations |
5 | 5 | import "bootstrap"; |
6 | | -import "mousetrap"; |
7 | | -import "jquery-visible"; |
8 | | -import _ from "underscore"; |
9 | | -import Backbone from "backbone"; |
10 | 6 |
|
11 | 7 | import "./controllers/index"; |
12 | 8 |
|
13 | | -Turbo.session.drive = false; |
14 | | - |
15 | | -/* global jQuery, Mousetrap */ |
16 | | -var $ = jQuery; |
17 | | - |
18 | | -window.$ = $; |
19 | | - |
20 | | -Backbone.$ = $; |
21 | | - |
22 | | -_.templateSettings = { |
23 | | - interpolate: /\{\{=(.+?)\}\}/g, |
24 | | - evaluate: /\{\{(.+?)\}\}/g |
25 | | -}; |
26 | | - |
27 | | -function CSRFToken() { |
28 | | - const tokenTag = document.getElementsByName('csrf-token')[0]; |
29 | | - |
30 | | - return (tokenTag && tokenTag.content) || ''; |
31 | | -} |
32 | | - |
33 | | -function requestHeaders() { |
34 | | - return { 'X-CSRF-Token': CSRFToken() }; |
35 | | -} |
36 | | - |
37 | | -var Story = Backbone.Model.extend({ |
38 | | - defaults: function() { |
39 | | - return { |
40 | | - "open" : false, |
41 | | - "selected" : false |
42 | | - } |
43 | | - }, |
44 | | - |
45 | | - toggle: function() { |
46 | | - if (this.get("open")) { |
47 | | - this.close(); |
48 | | - } else { |
49 | | - this.open(); |
50 | | - } |
51 | | - }, |
52 | | - |
53 | | - shouldSave: function() { |
54 | | - return this.changedAttributes() && this.get("id") > 0; |
55 | | - }, |
56 | | - |
57 | | - open: function() { |
58 | | - if (!this.get("keep_unread")) this.set("is_read", true); |
59 | | - if (this.shouldSave()) this.save(null, { headers: requestHeaders() }); |
60 | | - |
61 | | - if(this.collection){ |
62 | | - this.collection.closeOthers(this); |
63 | | - this.collection.unselectAll(); |
64 | | - this.collection.setSelection(this); |
65 | | - } |
66 | | - |
67 | | - this.set("open", true); |
68 | | - this.set("selected", true); |
69 | | - }, |
70 | | - |
71 | | - toggleKeepUnread: function() { |
72 | | - if (this.get("keep_unread")) { |
73 | | - this.set("keep_unread", false); |
74 | | - this.set("is_read", true); |
75 | | - } else { |
76 | | - this.set("keep_unread", true); |
77 | | - this.set("is_read", false); |
78 | | - } |
79 | | - |
80 | | - if (this.shouldSave()) this.save(null, { headers: requestHeaders() }); |
81 | | - }, |
82 | | - |
83 | | - close: function() { |
84 | | - this.set("open", false); |
85 | | - }, |
86 | | - |
87 | | - select: function() { |
88 | | - if(this.collection) this.collection.unselectAll(); |
89 | | - this.set("selected", true); |
90 | | - }, |
91 | | - |
92 | | - unselect: function() { |
93 | | - this.set("selected", false); |
94 | | - }, |
95 | | - |
96 | | - openInTab: function() { |
97 | | - window.open(this.get("permalink"), '_blank'); |
| 9 | +declare global { |
| 10 | + interface JQuery { |
| 11 | + modal: (action: string) => JQuery; |
98 | 12 | } |
99 | | -}); |
100 | | - |
101 | | -var StoryView = Backbone.View.extend({ |
102 | | - tagName: "li", |
103 | | - className: "story", |
104 | | - |
105 | | - template: "#story-template", |
106 | | - |
107 | | - events: { |
108 | | - "click .story-preview" : "storyClicked" |
109 | | - }, |
110 | | - |
111 | | - initialize: function() { |
112 | | - this.template = _.template($(this.template).html()); |
113 | | - this.listenTo(this.model, 'add', this.render); |
114 | | - this.listenTo(this.model, 'change:selected', this.itemSelected); |
115 | | - this.listenTo(this.model, 'change:open', this.itemOpened); |
116 | | - this.listenTo(this.model, 'change:is_read', this.itemRead); |
117 | | - this.el.addEventListener('keep-unread-toggle:toggled', (e) => { |
118 | | - var detail = e.detail; |
119 | | - this.model.set({keep_unread: detail.keepUnread, is_read: detail.isRead}, {silent: true}); |
120 | | - this.model.trigger('change:is_read'); |
121 | | - }); |
122 | | - }, |
123 | | - |
124 | | - render: function() { |
125 | | - var jsonModel = this.model.toJSON(); |
126 | | - this.$el.html(this.template(jsonModel)); |
127 | | - if (jsonModel.is_read) { |
128 | | - this.$el.addClass('read'); |
129 | | - } |
130 | | - if (jsonModel.keep_unread) { |
131 | | - this.$el.addClass('keepUnread'); |
132 | | - } |
133 | | - Object.assign(this.el.dataset, { |
134 | | - controller: "star-toggle keep-unread-toggle", |
135 | | - keepUnreadToggleIdValue: String(jsonModel.id), |
136 | | - keepUnreadToggleIsReadValue: String(jsonModel.is_read), |
137 | | - keepUnreadToggleKeepUnreadValue: String(jsonModel.keep_unread), |
138 | | - starToggleIdValue: String(jsonModel.id), |
139 | | - starToggleStarredValue: String(jsonModel.is_starred), |
140 | | - }); |
141 | | - return this; |
142 | | - }, |
143 | | - |
144 | | - itemRead: function() { |
145 | | - this.$el.toggleClass("read", this.model.get("is_read")); |
146 | | - }, |
147 | | - |
148 | | - itemOpened: function() { |
149 | | - if (this.model.get("open")) { |
150 | | - this.$el.addClass("open"); |
151 | | - $(".story-lead", this.$el).fadeOut(1000); |
152 | | - window.scrollTo(0, this.$el.offset().top); |
153 | | - } else { |
154 | | - this.$el.removeClass("open"); |
155 | | - $(".story-lead", this.$el).show(); |
156 | | - } |
157 | | - }, |
158 | | - |
159 | | - itemSelected: function() { |
160 | | - this.$el.toggleClass("cursor", this.model.get("selected")); |
161 | | - if (!this.$el.visible()) window.scrollTo(0, this.$el.offset().top); |
162 | | - }, |
163 | | - |
164 | | - storyClicked: function(e) { |
165 | | - if (e.metaKey || e.ctrlKey || e.which == 2) { |
166 | | - var backgroundTab = window.open(this.model.get("permalink")); |
167 | | - if (backgroundTab) backgroundTab.blur(); |
168 | | - window.focus(); |
169 | | - if (!this.model.get("keep_unread")) this.model.set("is_read", true); |
170 | | - if (this.model.shouldSave()) this.model.save(null, { headers: requestHeaders() }); |
171 | | - } else { |
172 | | - this.model.toggle(); |
173 | | - window.scrollTo(0, this.$el.offset().top); |
174 | | - } |
175 | | - }, |
176 | | - |
177 | | -}); |
178 | | - |
179 | | -var StoryList = Backbone.Collection.extend({ |
180 | | - model: Story, |
181 | | - url: "/stories", |
182 | | - |
183 | | - initialize: function() { |
184 | | - this.cursorPosition = -1; |
185 | | - }, |
186 | | - |
187 | | - max_position: function() { |
188 | | - return this.length - 1; |
189 | | - }, |
190 | | - |
191 | | - unreadCount: function() { |
192 | | - return this.where({is_read: false}).length; |
193 | | - }, |
194 | | - |
195 | | - closeOthers: function(modelToSkip) { |
196 | | - this.each(function(model) { |
197 | | - if (model.id != modelToSkip.id) { |
198 | | - model.close(); |
199 | | - } |
200 | | - }); |
201 | | - }, |
202 | | - |
203 | | - selected: function() { |
204 | | - return this.where({selected: true}); |
205 | | - }, |
206 | | - |
207 | | - unselectAll: function() { |
208 | | - _.invoke(this.selected(), "unselect"); |
209 | | - }, |
210 | | - |
211 | | - selectedStoryId: function() { |
212 | | - var selectedStory = this.at(this.cursorPosition); |
213 | | - return selectedStory ? selectedStory.id : -1; |
214 | | - }, |
215 | | - |
216 | | - setSelection: function(model) { |
217 | | - this.cursorPosition = this.indexOf(model); |
218 | | - }, |
219 | | - |
220 | | - moveCursorDown: function() { |
221 | | - if (this.cursorPosition < this.max_position()) { |
222 | | - this.cursorPosition++; |
223 | | - } else { |
224 | | - this.cursorPosition = 0; |
225 | | - } |
226 | | - |
227 | | - this.at(this.cursorPosition).select(); |
228 | | - }, |
229 | | - |
230 | | - moveCursorUp: function() { |
231 | | - if (this.cursorPosition > 0) { |
232 | | - this.cursorPosition--; |
233 | | - } else { |
234 | | - this.cursorPosition = this.max_position(); |
235 | | - } |
236 | | - |
237 | | - this.at(this.cursorPosition).select(); |
238 | | - }, |
239 | | - |
240 | | - openCurrentSelection: function() { |
241 | | - this.at(this.cursorPosition).open(); |
242 | | - }, |
243 | | - |
244 | | - toggleCurrent: function() { |
245 | | - if (this.cursorPosition < 0) this.cursorPosition = 0; |
246 | | - this.at(this.cursorPosition).toggle(); |
247 | | - }, |
248 | | - |
249 | | - viewCurrentInTab: function() { |
250 | | - if (this.cursorPosition < 0) this.cursorPosition = 0; |
251 | | - this.at(this.cursorPosition).openInTab(); |
252 | | - }, |
253 | | - |
254 | | - toggleCurrentKeepUnread: function() { |
255 | | - if (this.cursorPosition < 0) this.cursorPosition = 0; |
256 | | - this.at(this.cursorPosition).toggleKeepUnread(); |
257 | | - } |
258 | | -}); |
259 | | - |
260 | | -var AppView = Backbone.View.extend({ |
261 | | - el: "#stories", |
262 | | - |
263 | | - initialize: function(collection) { |
264 | | - this.stories = collection; |
265 | | - this.el = $(this.el); |
266 | | - |
267 | | - this.listenTo(this.stories, 'add', this.addOne); |
268 | | - this.listenTo(this.stories, 'reset', this.addAll); |
269 | | - this.listenTo(this.stories, 'all', this.render); |
270 | | - }, |
271 | | - |
272 | | - loadData: function(data) { |
273 | | - this.stories.reset(data); |
274 | | - }, |
275 | | - |
276 | | - render: function() { |
277 | | - var unreadCount = this.stories.unreadCount(); |
278 | | - |
279 | | - if (unreadCount === 0) { |
280 | | - document.title = window.i18n.titleName; |
281 | | - } else { |
282 | | - document.title = "(" + unreadCount + ") " + window.i18n.titleName; |
283 | | - } |
284 | | - }, |
285 | | - |
286 | | - addOne: function(story) { |
287 | | - var view = new StoryView({model: story}); |
288 | | - this.$("#story-list").append(view.render().el); |
289 | | - }, |
290 | | - |
291 | | - addAll: function() { |
292 | | - this.stories.each(this.addOne, this); |
293 | | - }, |
294 | | - |
295 | | - moveCursorDown: function() { |
296 | | - this.stories.moveCursorDown(); |
297 | | - }, |
298 | | - |
299 | | - moveCursorUp: function() { |
300 | | - this.stories.moveCursorUp(); |
301 | | - }, |
302 | | - |
303 | | - openCurrentSelection: function() { |
304 | | - this.stories.openCurrentSelection(); |
305 | | - }, |
306 | | - |
307 | | - toggleCurrent: function() { |
308 | | - this.stories.toggleCurrent(); |
309 | | - }, |
| 13 | +} |
310 | 14 |
|
311 | | - viewCurrentInTab: function() { |
312 | | - this.stories.viewCurrentInTab(); |
313 | | - }, |
| 15 | +Turbo.session.drive = false; |
314 | 16 |
|
315 | | - toggleCurrentKeepUnread: function() { |
316 | | - this.stories.toggleCurrentKeepUnread(); |
| 17 | +document.addEventListener("keydown", (event: KeyboardEvent) => { |
| 18 | + if (event.key === "?") { |
| 19 | + jQuery("#shortcuts").modal("toggle"); |
317 | 20 | } |
318 | 21 | }); |
319 | | - |
320 | | -$(document).ready(function() { |
321 | | - Mousetrap.bind("?", function() { |
322 | | - $("#shortcuts").modal('toggle'); |
323 | | - }); |
324 | | -}); |
325 | | - |
326 | | -window.StoryList = StoryList; |
327 | | -window.AppView = AppView; |
328 | | - |
329 | | -export { Story, StoryView, StoryList, AppView }; |
0 commit comments