@thecodeblogs/blog 0.15.4 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/fesm2022/thecodeblogs-blog.mjs +2018 -0
  2. package/fesm2022/thecodeblogs-blog.mjs.map +1 -0
  3. package/lib/components/entry-creator/entry-creator.component.d.ts +1 -1
  4. package/lib/components/entry-renderer/entry-renderer.component.d.ts +1 -1
  5. package/lib/components/entry-renderer-wrapper/entry-renderer-wrapper.component.d.ts +1 -1
  6. package/lib/components/entry-selector-dialog/entry-selector-dialog.component.d.ts +1 -1
  7. package/lib/components/entry-summary/entry-summary.component.d.ts +1 -1
  8. package/lib/components/json-renderer/json-renderer.component.d.ts +1 -1
  9. package/lib/components/landing-page/landing-page.component.d.ts +1 -1
  10. package/lib/components/main/main.component.d.ts +1 -1
  11. package/lib/components/media-upload-modal/media-upload-modal.component.d.ts +4 -2
  12. package/lib/components/outline-view/outline-view.component.d.ts +1 -1
  13. package/lib/components/schedule-publish-dialog/schedule-publish-dialog.component.d.ts +1 -1
  14. package/lib/components/side-navigation/side-navigation.component.d.ts +8 -3
  15. package/lib/components/static-html/static-html.component.d.ts +1 -1
  16. package/lib/core.module.d.ts +38 -38
  17. package/lib/pipes/LinkyPipe.d.ts +1 -1
  18. package/lib/pipes/TimeAgoPipe.d.ts +1 -1
  19. package/package.json +22 -26
  20. package/esm2020/lib/components/entry-creator/entry-creator.component.mjs +0 -341
  21. package/esm2020/lib/components/entry-renderer/entry-renderer.component.mjs +0 -108
  22. package/esm2020/lib/components/entry-renderer-wrapper/entry-renderer-wrapper.component.mjs +0 -75
  23. package/esm2020/lib/components/entry-selector-dialog/entry-selector-dialog-data.mjs +0 -3
  24. package/esm2020/lib/components/entry-selector-dialog/entry-selector-dialog.component.mjs +0 -54
  25. package/esm2020/lib/components/entry-summary/entry-summary.component.mjs +0 -28
  26. package/esm2020/lib/components/json-renderer/json-renderer.component.mjs +0 -26
  27. package/esm2020/lib/components/landing-page/landing-page.component.mjs +0 -35
  28. package/esm2020/lib/components/main/main.component.mjs +0 -56
  29. package/esm2020/lib/components/media-upload-modal/media-upload-modal.component.mjs +0 -160
  30. package/esm2020/lib/components/outline-view/outline-view.component.mjs +0 -38
  31. package/esm2020/lib/components/schedule-publish-dialog/schedule-publish-dialog-data.mjs +0 -3
  32. package/esm2020/lib/components/schedule-publish-dialog/schedule-publish-dialog.component.mjs +0 -33
  33. package/esm2020/lib/components/side-navigation/side-navigation.component.mjs +0 -222
  34. package/esm2020/lib/components/static-html/static-html.component.mjs +0 -28
  35. package/esm2020/lib/core.module.mjs +0 -209
  36. package/esm2020/lib/data/base.mjs +0 -7
  37. package/esm2020/lib/data/content-type.mjs +0 -10
  38. package/esm2020/lib/data/content.mjs +0 -5
  39. package/esm2020/lib/data/core-event-type.enum.mjs +0 -7
  40. package/esm2020/lib/data/core-event.mjs +0 -7
  41. package/esm2020/lib/data/entry.mjs +0 -79
  42. package/esm2020/lib/data/guid.mjs +0 -12
  43. package/esm2020/lib/data/identity.mjs +0 -2
  44. package/esm2020/lib/data/list-response.mjs +0 -3
  45. package/esm2020/lib/data/section.mjs +0 -11
  46. package/esm2020/lib/data/tag.mjs +0 -7
  47. package/esm2020/lib/data/visitor-profile.mjs +0 -3
  48. package/esm2020/lib/pipes/LinkyPipe.mjs +0 -15
  49. package/esm2020/lib/pipes/TimeAgoPipe.mjs +0 -100
  50. package/esm2020/lib/routing/routes.mjs +0 -25
  51. package/esm2020/lib/services/analytics/interaction.service.mjs +0 -20
  52. package/esm2020/lib/services/analytics/view.service.mjs +0 -20
  53. package/esm2020/lib/services/comment.service.mjs +0 -28
  54. package/esm2020/lib/services/django-rest-framework-endpoint.service.mjs +0 -50
  55. package/esm2020/lib/services/entry.service.mjs +0 -106
  56. package/esm2020/lib/services/identity.service.mjs +0 -20
  57. package/esm2020/lib/services/interaction.mjs +0 -3
  58. package/esm2020/lib/services/prism.service.mjs +0 -39
  59. package/esm2020/lib/services/static-html.service.mjs +0 -22
  60. package/esm2020/lib/services/tag.service.mjs +0 -33
  61. package/esm2020/lib/services/upload.mjs +0 -3
  62. package/esm2020/lib/services/upload.service.mjs +0 -22
  63. package/esm2020/lib/services/view.mjs +0 -3
  64. package/esm2020/lib/services/visitor-profile.service.mjs +0 -35
  65. package/esm2020/public-api.mjs +0 -45
  66. package/esm2020/thecodeblogs-blog.mjs +0 -5
  67. package/fesm2015/thecodeblogs-blog.mjs +0 -1930
  68. package/fesm2015/thecodeblogs-blog.mjs.map +0 -1
  69. package/fesm2020/thecodeblogs-blog.mjs +0 -1924
  70. package/fesm2020/thecodeblogs-blog.mjs.map +0 -1
@@ -1,1924 +0,0 @@
1
- import { orderBy, map as map$1, filter } from 'lodash';
2
- import * as i0 from '@angular/core';
3
- import { Injectable, EventEmitter, PLATFORM_ID, Inject, SecurityContext, Component, Input, HostListener, ViewChild, Pipe, NgModule } from '@angular/core';
4
- import * as i1 from '@angular/common/http';
5
- import { HttpParams } from '@angular/common/http';
6
- import { map, debounceTime, startWith } from 'rxjs/operators';
7
- import { Subject, Subscription } from 'rxjs';
8
- import * as i2$1 from '@angular/common';
9
- import { isPlatformBrowser, CommonModule } from '@angular/common';
10
- import 'clipboard';
11
- import 'prismjs';
12
- import 'prismjs/plugins/toolbar/prism-toolbar';
13
- import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard';
14
- import 'prismjs/components/prism-css';
15
- import 'prismjs/components/prism-javascript';
16
- import 'prismjs/components/prism-java';
17
- import 'prismjs/components/prism-markup';
18
- import 'prismjs/components/prism-typescript';
19
- import 'prismjs/components/prism-sass';
20
- import 'prismjs/components/prism-scss';
21
- import * as i2 from 'ngx-device-detector';
22
- import * as i1$1 from '@angular/platform-browser';
23
- import { ENTER, COMMA, TAB } from '@angular/cdk/keycodes';
24
- import * as i1$2 from '@angular/material/dialog';
25
- import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
26
- import * as i4 from '@angular/material/button';
27
- import { MatButtonModule } from '@angular/material/button';
28
- import * as i5 from '@angular/material/divider';
29
- import { MatDividerModule } from '@angular/material/divider';
30
- import * as i6 from '@angular/material/table';
31
- import { MatTableModule } from '@angular/material/table';
32
- import * as i7 from 'ng2-file-upload';
33
- import { FileUploader, FileUploadModule } from 'ng2-file-upload';
34
- import * as i1$3 from '@fortawesome/angular-fontawesome';
35
- import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
36
- import * as i6$1 from '@angular/forms';
37
- import { UntypedFormControl, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
38
- import * as i8 from '@angular/material/card';
39
- import { MatCardModule } from '@angular/material/card';
40
- import * as i9 from '@angular/material/input';
41
- import { MatInputModule } from '@angular/material/input';
42
- import * as i10 from '@angular/material/form-field';
43
- import * as i11 from '@angular/cdk/text-field';
44
- import * as i12 from '@angular/material/radio';
45
- import { MatRadioModule } from '@angular/material/radio';
46
- import * as i13 from '@angular/material/autocomplete';
47
- import { MatAutocompleteModule } from '@angular/material/autocomplete';
48
- import * as i14 from '@angular/material/core';
49
- import { MatNativeDateModule } from '@angular/material/core';
50
- import * as i15 from '@angular/material/chips';
51
- import { MatChipsModule } from '@angular/material/chips';
52
- import * as i16 from '@angular/material/icon';
53
- import { MatIconModule } from '@angular/material/icon';
54
- import * as i17 from '@angular/material/datepicker';
55
- import { MatDatepickerModule } from '@angular/material/datepicker';
56
- import * as i6$2 from 'ngx-material-timepicker';
57
- import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker';
58
- import * as i1$4 from '@angular/router';
59
- import { NavigationEnd, RouterModule } from '@angular/router';
60
- import * as i3 from '@angular/cdk/drag-drop';
61
- import { DragDropModule } from '@angular/cdk/drag-drop';
62
- import { trigger, state, style, transition, animate } from '@angular/animations';
63
- import * as i8$1 from '@angular/material/list';
64
- import { MatListModule } from '@angular/material/list';
65
- import * as i3$1 from '@angular/material/sidenav';
66
- import { MatSidenavModule } from '@angular/material/sidenav';
67
- import Autolinker from 'autolinker';
68
- import { MatCheckboxModule } from '@angular/material/checkbox';
69
- import { faSpinner } from '@fortawesome/free-solid-svg-icons';
70
-
71
- class Guid {
72
- newGuid() {
73
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
74
- // tslint:disable-next-line:no-bitwise
75
- const r = Math.random() * 16 | 0,
76
- // tslint:disable-next-line:triple-equals no-bitwise
77
- v = c == 'x' ? r : (r & 0x3 | 0x8);
78
- return v.toString(16);
79
- });
80
- }
81
- }
82
-
83
- class Base {
84
- constructor() {
85
- this.id = new Guid().newGuid();
86
- }
87
- }
88
-
89
- var ContentType;
90
- (function (ContentType) {
91
- ContentType["TEXT"] = "text";
92
- ContentType["URL"] = "url";
93
- ContentType["CODE"] = "code";
94
- ContentType["IMAGE"] = "image";
95
- ContentType["MEDIA"] = "media";
96
- ContentType["HTML"] = "html";
97
- })(ContentType || (ContentType = {}));
98
-
99
- class Content extends Base {
100
- }
101
- Content.KEY_MIMETYPE = 'mimeType';
102
-
103
- class Entry extends Base {
104
- constructor(init) {
105
- super();
106
- this.should_publish_in_future = false;
107
- Object.assign(this, init);
108
- if (!this.create_date) {
109
- this.create_date = new Date();
110
- }
111
- else {
112
- this.create_date = new Date(this.create_date);
113
- }
114
- if (!this.edit_date) {
115
- this.edit_date = new Date();
116
- }
117
- else {
118
- this.edit_date = new Date(this.edit_date);
119
- }
120
- if (this.publish_date) {
121
- this.publish_date = new Date(this.publish_date);
122
- }
123
- if (this.future_publish_date) {
124
- this.future_publish_date = new Date(this.future_publish_date);
125
- }
126
- if (!this.version) {
127
- this.version = 1;
128
- }
129
- if (!this.tags) {
130
- this.tags = [];
131
- }
132
- if (this.views) {
133
- if (this.views < 10) {
134
- this._friendly_views = 'Less than ten';
135
- }
136
- else if (10 < this.views && this.views < 100) {
137
- this._friendly_views = 'Around one hundred';
138
- }
139
- else {
140
- this._friendly_views = this.views.toString();
141
- }
142
- }
143
- if (!this.sections) {
144
- this.sections = [];
145
- }
146
- // For entries that existed before this variable was introduced, the server will return undefined. If this
147
- // stays undefined, it will violate the null constraints on the DB, so this code checks for both null
148
- // and undefined and then populates the value accordingly
149
- if (typeof (this.should_publish_in_future) === 'undefined' || this.should_publish_in_future === null) {
150
- this.should_publish_in_future = false;
151
- }
152
- }
153
- sort() {
154
- this.sections = orderBy(this.sections, ({ order }) => Number(order), ['asc']);
155
- for (let i = 0; i < this.sections.length; i++) {
156
- this.sections[i].order = i * 10;
157
- }
158
- for (const section of this.sections) {
159
- section.contents = orderBy(section.contents, ({ order }) => Number(order), ['asc']);
160
- for (let i = 0; i < section.contents.length; i++) {
161
- section.contents[i].order = i * 10;
162
- }
163
- }
164
- }
165
- showEditInformation() {
166
- // @ts-ignore
167
- const difference = Math.floor((this.create_date - this.edit_date) / (1000 * 60 * 60 * 24));
168
- return (difference > 1 || difference < -1);
169
- }
170
- getProp(prop) {
171
- if (this.__server_generated_properties) {
172
- return this.__server_generated_properties[prop];
173
- }
174
- else {
175
- return '';
176
- }
177
- }
178
- }
179
-
180
- class ListResponse {
181
- }
182
-
183
- class Section extends Base {
184
- constructor() {
185
- super();
186
- if (!this.order) {
187
- this.order = -1;
188
- }
189
- this.contents = [];
190
- }
191
- }
192
-
193
- class CoreEvent {
194
- constructor(data, type) {
195
- this.data = data;
196
- this.type = type;
197
- }
198
- }
199
-
200
- var CoreEventType;
201
- (function (CoreEventType) {
202
- CoreEventType["UPDATE"] = "update";
203
- CoreEventType["CREATE"] = "create";
204
- CoreEventType["DELETE"] = "delete";
205
- })(CoreEventType || (CoreEventType = {}));
206
-
207
- class VisitorProfile {
208
- }
209
-
210
- class CommentService {
211
- constructor(http) {
212
- this.http = http;
213
- this.endpoint = '/blog_api/comments/';
214
- this.adminEndpoint = '/blog_api/admin/comments/';
215
- }
216
- getComments(entry) {
217
- return this.http.get(this.endpoint, { params: { entry } });
218
- }
219
- postComment(comment) {
220
- return this.http.post(this.endpoint, comment, { params: { entry: comment.entry } });
221
- }
222
- patchComment(comment) {
223
- return this.http.patch(this.adminEndpoint + '/' + comment.id + '/', comment);
224
- }
225
- }
226
- CommentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: CommentService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
227
- CommentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: CommentService, providedIn: 'root' });
228
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: CommentService, decorators: [{
229
- type: Injectable,
230
- args: [{
231
- providedIn: 'root'
232
- }]
233
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
234
-
235
- class DjangoRestFrameworkEndpointService {
236
- constructor(http) {
237
- this.http = http;
238
- this.events = new EventEmitter();
239
- this.endpoint = '';
240
- }
241
- triggerCoreEvent(obj, type) {
242
- this.events.next(new CoreEvent(obj, type));
243
- return obj;
244
- }
245
- handleResponse(obj) {
246
- return obj;
247
- }
248
- handleListResponse(obj) {
249
- return obj;
250
- }
251
- get() {
252
- return this.http.get(this.endpoint).pipe(map(this.handleListResponse.bind(this)));
253
- }
254
- getById(id) {
255
- return this.http.get(this.endpoint + id + '/').pipe(map(this.handleResponse.bind(this)));
256
- }
257
- create(entity) {
258
- return this.http.post(this.endpoint + '/', entity).pipe(map((val) => this.triggerCoreEvent(val, CoreEventType.CREATE)), map(this.handleResponse.bind(this)));
259
- }
260
- delete(entity) {
261
- return this.http.delete(this.endpoint + entity.id + '/').pipe(map((val) => this.triggerCoreEvent(val, CoreEventType.DELETE)), map(this.handleResponse.bind(this)));
262
- }
263
- update(entity) {
264
- return this.http.patch(this.endpoint + entity.id + '/', entity).pipe(map((val) => this.triggerCoreEvent(val, CoreEventType.UPDATE)), map(this.handleResponse.bind(this)));
265
- }
266
- getListByUrl(url) {
267
- return this.http.get(url).pipe(map(this.handleListResponse.bind(this)));
268
- }
269
- }
270
- DjangoRestFrameworkEndpointService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: DjangoRestFrameworkEndpointService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
271
- DjangoRestFrameworkEndpointService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: DjangoRestFrameworkEndpointService, providedIn: 'root' });
272
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: DjangoRestFrameworkEndpointService, decorators: [{
273
- type: Injectable,
274
- args: [{
275
- providedIn: 'root'
276
- }]
277
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
278
-
279
- class EntryService extends DjangoRestFrameworkEndpointService {
280
- handleResponse(obj) {
281
- return new Entry(obj);
282
- }
283
- handleListResponse(obj) {
284
- const response = obj;
285
- const results = [];
286
- for (const result of response.results) {
287
- results.push(new Entry(result));
288
- }
289
- response.results = results;
290
- return response;
291
- }
292
- constructor(http) {
293
- super(http);
294
- this.http = http;
295
- this.endpoint = '/blog_api/entries/';
296
- this.adminEndpoint = '/blog_api/admin/entries/';
297
- this.currentlyEditedEntry = new Subject();
298
- this.sub = this.currentlyEditedEntry.pipe(debounceTime(3000)).subscribe((e) => {
299
- e.edit_date = new Date();
300
- const params = new HttpParams().set('published', JSON.stringify(false)).set('defunct', JSON.stringify(false));
301
- this.http.patch(this.adminEndpoint + e.id + '/', e, { params }).pipe(map(this.handleResponse.bind(this))).subscribe((response) => {
302
- this.triggerCoreEvent(response, CoreEventType.UPDATE);
303
- console.log('Synced ' + e.id + '...');
304
- }, (err) => {
305
- console.log('Error encountered syncing ' + e.id + ', trying to create...');
306
- this.http.post(this.adminEndpoint, e).pipe(map(this.handleResponse)).subscribe((response) => {
307
- this.triggerCoreEvent(response, CoreEventType.CREATE);
308
- console.log('Created ' + e.id + '...');
309
- }, (createErr) => {
310
- console.log('Error creating ' + e.id);
311
- });
312
- });
313
- });
314
- }
315
- get() {
316
- return this.http.get(this.endpoint).pipe(map(this.handleListResponse.bind(this)));
317
- }
318
- search(searchTerm) {
319
- return this.http.get(this.endpoint + "?search=" + searchTerm).pipe(map(this.handleListResponse.bind(this)));
320
- }
321
- getUnpublishedEntries() {
322
- const params = new HttpParams().set('published', JSON.stringify(false)).set('defunct', JSON.stringify(false));
323
- return this.http.get(this.adminEndpoint, { params });
324
- }
325
- getBySlug(slug) {
326
- return this.http.get(this.endpoint + slug + '/by_slug/').pipe(map(this.handleResponse.bind(this)));
327
- }
328
- getUnpublishedById(id) {
329
- const params = new HttpParams().set('published', JSON.stringify(false)).set('defunct', JSON.stringify(false));
330
- return this.http.get(this.adminEndpoint + id, { params }).pipe(map(this.handleResponse.bind(this)));
331
- }
332
- updateUnpublishedEntry(entry) {
333
- const params = new HttpParams().set('published', JSON.stringify(false)).set('defunct', JSON.stringify(false));
334
- return this.http.patch(this.adminEndpoint + entry.id + '/', entry, { params }).pipe(map((val) => this.triggerCoreEvent(val, CoreEventType.UPDATE)), map(this.handleResponse.bind(this)));
335
- }
336
- slugify(s) {
337
- const charMap = JSON.parse('{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ң":"NG","ң":"ng","Ү":"UE","ү":"ue","Ұ":"U","ұ":"u","Һ":"H","һ":"h","Ә":"AE","ә":"ae","Ө":"OE","ө":"oe","Ա":"A","Բ":"B","Գ":"G","Դ":"D","Ե":"E","Զ":"Z","Է":"E\'","Ը":"Y\'","Թ":"T\'","Ժ":"JH","Ի":"I","Լ":"L","Խ":"X","Ծ":"C\'","Կ":"K","Հ":"H","Ձ":"D\'","Ղ":"GH","Ճ":"TW","Մ":"M","Յ":"Y","Ն":"N","Շ":"SH","Չ":"CH","Պ":"P","Ջ":"J","Ռ":"R\'","Ս":"S","Վ":"V","Տ":"T","Ր":"R","Ց":"C","Փ":"P\'","Ք":"Q\'","Օ":"O\'\'","Ֆ":"F","և":"EV","ء":"a","آ":"aa","أ":"a","ؤ":"u","إ":"i","ئ":"e","ا":"a","ب":"b","ة":"h","ت":"t","ث":"th","ج":"j","ح":"h","خ":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","ش":"sh","ص":"s","ض":"dh","ط":"t","ظ":"z","ع":"a","غ":"gh","ف":"f","ق":"q","ك":"k","ل":"l","م":"m","ن":"n","ه":"h","و":"w","ى":"a","ي":"y","ً":"an","ٌ":"on","ٍ":"en","َ":"a","ُ":"u","ِ":"e","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","پ":"p","چ":"ch","ژ":"zh","ک":"k","گ":"g","ی":"y","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ṣ":"S","ṣ":"s","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","–":"-","‘":"\'","’":"\'","“":"\\\"","”":"\\\"","„":"\\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial","ﻵ":"laa","ﻷ":"laa","ﻹ":"lai","ﻻ":"la"}');
338
- const locales = JSON.parse('{"bg":{"Й":"Y","Ц":"Ts","Щ":"Sht","Ъ":"A","Ь":"Y","й":"y","ц":"ts","щ":"sht","ъ":"a","ь":"y"},"de":{"Ä":"AE","ä":"ae","Ö":"OE","ö":"oe","Ü":"UE","ü":"ue","ß":"ss","%":"prozent","&":"und","|":"oder","∑":"summe","∞":"unendlich","♥":"liebe"},"es":{"%":"por ciento","&":"y","<":"menor que",">":"mayor que","|":"o","¢":"centavos","£":"libras","¤":"moneda","₣":"francos","∑":"suma","∞":"infinito","♥":"amor"},"fr":{"%":"pourcent","&":"et","<":"plus petit",">":"plus grand","|":"ou","¢":"centime","£":"livre","¤":"devise","₣":"franc","∑":"somme","∞":"infini","♥":"amour"},"pt":{"%":"porcento","&":"e","<":"menor",">":"maior","|":"ou","¢":"centavo","∑":"soma","£":"libra","∞":"infinito","♥":"amor"},"uk":{"И":"Y","и":"y","Й":"Y","й":"y","Ц":"Ts","ц":"ts","Х":"Kh","х":"kh","Щ":"Shch","щ":"shch","Г":"H","г":"h"},"vi":{"Đ":"D","đ":"d"},"da":{"Ø":"OE","ø":"oe","Å":"AA","å":"aa","%":"procent","&":"og","|":"eller","$":"dollar","<":"mindre end",">":"større end"},"nb":{"&":"og","Å":"AA","Æ":"AE","Ø":"OE","å":"aa","æ":"ae","ø":"oe"},"it":{"&":"e"},"nl":{"&":"en"},"sv":{"&":"och","Å":"AA","Ä":"AE","Ö":"OE","å":"aa","ä":"ae","ö":"oe"}}');
339
- if (typeof s !== 'string') {
340
- throw new Error('slugify: string argument expected');
341
- }
342
- const replacement = '-';
343
- const trim = true;
344
- const locale = 'en';
345
- let slug = s.normalize().split('')
346
- // replace characters based on charMap
347
- .reduce((result, ch) => {
348
- let appendChar = locale[ch] || charMap[ch] || ch;
349
- if (appendChar === replacement) {
350
- appendChar = ' ';
351
- }
352
- return result + appendChar
353
- // remove not allowed characters
354
- .replace(/[^\w\s$*_+~.()'"!\-:@]+/g, '');
355
- }, '');
356
- slug = slug.trim();
357
- // Replace spaces with replacement character, treating multiple consecutive
358
- // spaces as a single space.
359
- slug = slug.replace(/\s+/g, replacement);
360
- slug = slug.toLowerCase();
361
- return slug;
362
- }
363
- delete(entity) {
364
- return this.http.delete(this.adminEndpoint + entity.id + '/').pipe(map((val) => this.triggerCoreEvent(val, CoreEventType.DELETE)), map(this.handleResponse.bind(this)));
365
- }
366
- }
367
- EntryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntryService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
368
- EntryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntryService, providedIn: 'root' });
369
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntryService, decorators: [{
370
- type: Injectable,
371
- args: [{
372
- providedIn: 'root'
373
- }]
374
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
375
-
376
- class IdentityService {
377
- constructor(http) {
378
- this.http = http;
379
- }
380
- getMe() {
381
- throw new Error('You must provide an implementation for this');
382
- }
383
- }
384
- IdentityService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: IdentityService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
385
- IdentityService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: IdentityService, providedIn: 'root' });
386
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: IdentityService, decorators: [{
387
- type: Injectable,
388
- args: [{
389
- providedIn: 'root'
390
- }]
391
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
392
-
393
- class PrismService {
394
- constructor(platformId) {
395
- this.platformId = platformId;
396
- if (Prism) {
397
- Prism.manual = true;
398
- }
399
- }
400
- highlightAll() {
401
- if (isPlatformBrowser(this.platformId)) {
402
- Prism.highlightAll();
403
- }
404
- }
405
- }
406
- PrismService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: PrismService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
407
- PrismService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: PrismService, providedIn: 'root' });
408
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: PrismService, decorators: [{
409
- type: Injectable,
410
- args: [{
411
- providedIn: 'root'
412
- }]
413
- }], ctorParameters: function () { return [{ type: Object, decorators: [{
414
- type: Inject,
415
- args: [PLATFORM_ID]
416
- }] }]; } });
417
-
418
- class UploadService {
419
- constructor(http) {
420
- this.http = http;
421
- }
422
- get(id) {
423
- return this.http.get(UploadService.status_endpoint.replace('{pk}', id) + '/');
424
- }
425
- }
426
- UploadService.upload_endpoint = '/file_api/uploads/create_image/';
427
- UploadService.status_endpoint = '/file_api/uploads/{pk}/status';
428
- UploadService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: UploadService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
429
- UploadService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: UploadService, providedIn: 'root' });
430
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: UploadService, decorators: [{
431
- type: Injectable,
432
- args: [{
433
- providedIn: 'root'
434
- }]
435
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
436
-
437
- class Upload {
438
- }
439
-
440
- class ViewService extends DjangoRestFrameworkEndpointService {
441
- constructor(http) {
442
- super(http);
443
- this.http = http;
444
- this.endpoint = '/blog_api/views/';
445
- }
446
- }
447
- ViewService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ViewService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
448
- ViewService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ViewService, providedIn: 'root' });
449
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ViewService, decorators: [{
450
- type: Injectable,
451
- args: [{
452
- providedIn: 'root'
453
- }]
454
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
455
-
456
- class InteractionService extends DjangoRestFrameworkEndpointService {
457
- constructor(http) {
458
- super(http);
459
- this.http = http;
460
- this.endpoint = '/blog_api/interactions/';
461
- }
462
- }
463
- InteractionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: InteractionService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
464
- InteractionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: InteractionService, providedIn: 'root' });
465
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: InteractionService, decorators: [{
466
- type: Injectable,
467
- args: [{
468
- providedIn: 'root'
469
- }]
470
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
471
-
472
- class View {
473
- }
474
-
475
- class Interaction {
476
- }
477
-
478
- class VisitorProfileService extends DjangoRestFrameworkEndpointService {
479
- constructor(http, deviceDetectorService) {
480
- super(http);
481
- this.http = http;
482
- this.deviceDetectorService = deviceDetectorService;
483
- this.endpoint = '/blog_api/visitor_profiles/';
484
- }
485
- getVisitorProfile() {
486
- const deviceInfo = this.deviceDetectorService.getDeviceInfo();
487
- const vp = new VisitorProfile();
488
- vp.telemetry = deviceInfo;
489
- vp.name = deviceInfo.os;
490
- vp.family = deviceInfo.browser;
491
- vp.version = deviceInfo.browser_version;
492
- vp.device = deviceInfo.device;
493
- vp.os_version = deviceInfo.os_version;
494
- vp.language = navigator.language;
495
- return vp;
496
- }
497
- }
498
- VisitorProfileService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: VisitorProfileService, deps: [{ token: i1.HttpClient }, { token: i2.DeviceDetectorService }], target: i0.ɵɵFactoryTarget.Injectable });
499
- VisitorProfileService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: VisitorProfileService, providedIn: 'root' });
500
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: VisitorProfileService, decorators: [{
501
- type: Injectable,
502
- args: [{
503
- providedIn: 'root'
504
- }]
505
- }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.DeviceDetectorService }]; } });
506
-
507
- class StaticHtmlService {
508
- constructor(domSanitizer) {
509
- this.domSanitizer = domSanitizer;
510
- }
511
- mapStaticHtml(htmlString, isTrusted) {
512
- return isTrusted ?
513
- htmlString :
514
- this.domSanitizer.sanitize(SecurityContext.HTML, htmlString);
515
- }
516
- }
517
- StaticHtmlService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: StaticHtmlService, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Injectable });
518
- StaticHtmlService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: StaticHtmlService, providedIn: 'root' });
519
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: StaticHtmlService, decorators: [{
520
- type: Injectable,
521
- args: [{
522
- providedIn: 'root'
523
- }]
524
- }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
525
-
526
- class Tag {
527
- constructor(obj) {
528
- this.id = obj.id;
529
- this.label = obj.label;
530
- }
531
- }
532
-
533
- class TagService extends DjangoRestFrameworkEndpointService {
534
- handleResponse(obj) {
535
- return new Tag(obj);
536
- }
537
- handleListResponse(obj) {
538
- const response = obj;
539
- const results = [];
540
- for (let i = 0; i < response.results.length; i++) {
541
- results.push(new Tag(response.results[i]));
542
- }
543
- response.results = results;
544
- return response;
545
- }
546
- constructor(http) {
547
- super(http);
548
- this.http = http;
549
- this.endpoint = '/blog_api/tags/';
550
- }
551
- }
552
- TagService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: TagService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
553
- TagService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: TagService, providedIn: 'root' });
554
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: TagService, decorators: [{
555
- type: Injectable,
556
- args: [{
557
- providedIn: 'root'
558
- }]
559
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
560
-
561
- class EntrySelectorDialogData {
562
- }
563
-
564
- class EntrySelectorDialogComponent {
565
- constructor(dialogRef, data, entryService) {
566
- this.dialogRef = dialogRef;
567
- this.data = data;
568
- this.entryService = entryService;
569
- this.columnsToDisplay = ['title', 'create_date', 'actions'];
570
- }
571
- ngOnInit() {
572
- this.entryService.getUnpublishedEntries().subscribe((next) => {
573
- this.entries = next.results;
574
- });
575
- }
576
- onNoClick() {
577
- this.dialogRef.close();
578
- }
579
- select(entry) {
580
- this.entryService.getUnpublishedById(entry.id).subscribe((entry_new) => {
581
- localStorage.setItem(EntrySelectorDialogComponent.CURRENT_ENTRY, JSON.stringify(entry_new));
582
- entry_new.sort();
583
- this.entryService.currentlyEditedEntry.next(entry_new);
584
- this.dialogRef.close(entry_new.id);
585
- });
586
- }
587
- delete(entry) {
588
- this.entryService.delete(entry).subscribe((response) => {
589
- this.entryService.getUnpublishedEntries().subscribe((next) => {
590
- this.entries = next.results;
591
- });
592
- }, (error) => {
593
- alert('NOT DELETED: ' + error);
594
- });
595
- }
596
- }
597
- EntrySelectorDialogComponent.CURRENT_ENTRY = 'current_entry';
598
- EntrySelectorDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntrySelectorDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: EntryService }], target: i0.ɵɵFactoryTarget.Component });
599
- EntrySelectorDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: EntrySelectorDialogComponent, selector: "app-entry-selector-dialog", ngImport: i0, template: "<h1 mat-dialog-title>Select an Entry to Edit</h1>\n<!--<mat-radio-group aria-label=\"Select an option\">-->\n<!-- <mat-radio-button class=\"option\" value=\"unpublished\">Unpublished</mat-radio-button>-->\n<!-- <mat-radio-button class=\"option\" value=\"published\">Published</mat-radio-button>-->\n<!--</mat-radio-group>-->\n<mat-divider class=\"option-list-divider\"></mat-divider>\n<div mat-dialog-content>\n\n <table mat-table [dataSource]=entries>\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> Id </th>\n <td mat-cell *matCellDef=\"let entry\"> {{entry.id}} </td>\n </ng-container>\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell *matHeaderCellDef> Title </th>\n <td mat-cell *matCellDef=\"let entry\"> {{entry.title}} </td>\n </ng-container>\n <ng-container matColumnDef=\"create_date\">\n <th mat-header-cell *matHeaderCellDef> Created </th>\n <td mat-cell *matCellDef=\"let entry\"> {{entry.create_date}} </td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let entry\">\n <button mat-button color=\"primary\" (click)=\"select(entry)\">Edit</button> | <button mat-button color=\"warn\" (click)=\"delete(entry)\">Delete</button>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"columnsToDisplay\"></tr>\n <tr mat-row *matRowDef=\"let myRowData; columns: columnsToDisplay\"></tr>\n </table>\n <div *ngIf=\"!entries?.length\">There are no unpublished entries</div>\n</div>\n<div mat-dialog-actions>\n <button mat-button (click)=\"onNoClick()\">Cancel</button>\n</div>\n", styles: [".entry-checkbox-container{display:inline-block;width:100%;margin:5px 0}.option-list-divider{margin:10px 0}.option{margin-right:5px}.mat-column-actions{min-width:175px}.mat-column-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:365px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }] });
600
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntrySelectorDialogComponent, decorators: [{
601
- type: Component,
602
- args: [{ selector: 'app-entry-selector-dialog', template: "<h1 mat-dialog-title>Select an Entry to Edit</h1>\n<!--<mat-radio-group aria-label=\"Select an option\">-->\n<!-- <mat-radio-button class=\"option\" value=\"unpublished\">Unpublished</mat-radio-button>-->\n<!-- <mat-radio-button class=\"option\" value=\"published\">Published</mat-radio-button>-->\n<!--</mat-radio-group>-->\n<mat-divider class=\"option-list-divider\"></mat-divider>\n<div mat-dialog-content>\n\n <table mat-table [dataSource]=entries>\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> Id </th>\n <td mat-cell *matCellDef=\"let entry\"> {{entry.id}} </td>\n </ng-container>\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell *matHeaderCellDef> Title </th>\n <td mat-cell *matCellDef=\"let entry\"> {{entry.title}} </td>\n </ng-container>\n <ng-container matColumnDef=\"create_date\">\n <th mat-header-cell *matHeaderCellDef> Created </th>\n <td mat-cell *matCellDef=\"let entry\"> {{entry.create_date}} </td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let entry\">\n <button mat-button color=\"primary\" (click)=\"select(entry)\">Edit</button> | <button mat-button color=\"warn\" (click)=\"delete(entry)\">Delete</button>\n </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"columnsToDisplay\"></tr>\n <tr mat-row *matRowDef=\"let myRowData; columns: columnsToDisplay\"></tr>\n </table>\n <div *ngIf=\"!entries?.length\">There are no unpublished entries</div>\n</div>\n<div mat-dialog-actions>\n <button mat-button (click)=\"onNoClick()\">Cancel</button>\n</div>\n", styles: [".entry-checkbox-container{display:inline-block;width:100%;margin:5px 0}.option-list-divider{margin:10px 0}.option{margin-right:5px}.mat-column-actions{min-width:175px}.mat-column-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:365px}\n"] }]
603
- }], ctorParameters: function () { return [{ type: i1$2.MatDialogRef }, { type: EntrySelectorDialogData, decorators: [{
604
- type: Inject,
605
- args: [MAT_DIALOG_DATA]
606
- }] }, { type: EntryService }]; } });
607
-
608
- class MediaUploadModalComponent {
609
- static getCookie(name) {
610
- const ca = document.cookie.split(';');
611
- const caLen = ca.length;
612
- const cookieName = `${name}=`;
613
- let c;
614
- for (let i = 0; i < caLen; i += 1) {
615
- c = ca[i].replace(/^\s+/g, '');
616
- if (c.indexOf(cookieName) === 0) {
617
- return c.substring(cookieName.length, c.length);
618
- }
619
- }
620
- return '';
621
- }
622
- constructor(dialogRef, uploadService) {
623
- this.dialogRef = dialogRef;
624
- this.uploadService = uploadService;
625
- this.allowedMimeTypes = [
626
- 'image/jpeg',
627
- 'image/gif',
628
- 'image/png',
629
- 'image/jpg',
630
- 'video/mp4',
631
- 'video/webm',
632
- 'video/ogg',
633
- ];
634
- this.uploadUrlKey = 'path_to_file';
635
- this.uploading = false;
636
- }
637
- pollForCompletion() {
638
- this.uploadService.get(this.uploadId).subscribe((response) => {
639
- if (response.processed) {
640
- this.imgLink = response[this.uploadUrlKey];
641
- this.mimeType = response.mime_type;
642
- clearInterval(this.poller);
643
- this.poller = null;
644
- this.uploading = false;
645
- }
646
- });
647
- }
648
- ngOnInit() {
649
- this.uploader = new FileUploader({
650
- url: UploadService.upload_endpoint,
651
- itemAlias: 'file',
652
- authToken: '',
653
- headers: [
654
- { name: 'X-CSRFToken', value: MediaUploadModalComponent.getCookie('csrftoken') },
655
- ],
656
- additionalParameter: { csrf_token: MediaUploadModalComponent.getCookie('csrftoken') },
657
- removeAfterUpload: true,
658
- allowedMimeType: this.allowedMimeTypes,
659
- });
660
- this.uploader.onCompleteItem = (item, response) => {
661
- const responseObj = JSON.parse(response);
662
- this.uploadId = responseObj.id;
663
- this.poller = setInterval(this.pollForCompletion.bind(this), 2000);
664
- };
665
- this.uploader.onWhenAddingFileFailed = (item, filter, options) => {
666
- this.error = 'This file is not a supported mimetype.';
667
- this.uploading = false;
668
- };
669
- if (this.file) {
670
- this.uploader.addToQueue([this.file]);
671
- this.uploader.uploadAll();
672
- this.uploading = true;
673
- }
674
- }
675
- onFileSelected(e) {
676
- this.uploader.uploadAll();
677
- this.uploading = true;
678
- }
679
- buildHost(url) {
680
- return location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '') + url;
681
- }
682
- close() {
683
- this.dialogRef.close();
684
- }
685
- ngOnDestroy() {
686
- if (this.socketSub) {
687
- this.socketSub.complete();
688
- this.socketSub = null;
689
- }
690
- }
691
- blobToFile(theBlob, fileName) {
692
- // A Blob() is almost a File() - it's just missing the two properties below which we will add
693
- theBlob.lastModifiedDate = new Date();
694
- theBlob.name = fileName;
695
- return theBlob;
696
- }
697
- onPaste(e) {
698
- if (e instanceof ClipboardEvent) {
699
- const files = e.clipboardData.files;
700
- if (files) {
701
- if (files.length < 1) {
702
- // const items = e.clipboardData.items;
703
- // for(let i = 0; i < items.length; i++) {
704
- // const item = items[i];
705
- // item.getAsString((text) => {
706
- // try {
707
- // const url = new URL(text);
708
- // if(url) {
709
- // fetch(text)
710
- // .then(res => res.blob()) // Gets the response and returns it as a blob
711
- // .then(blob => {
712
- // const file = this.blobToFile(blob, 'web-created')
713
- // this.uploader.addToQueue([file])
714
- // this.uploader.uploadAll();
715
- // this.uploading = true;
716
- // });
717
- // }
718
- // } catch(e) {
719
- //
720
- // }
721
- // });
722
- // }
723
- }
724
- else if (files.length > 1) {
725
- console.log('Multiple files detected');
726
- }
727
- else {
728
- for (let i = 0; i < files.length; i++) {
729
- this.uploader.addToQueue([files[i]]);
730
- }
731
- this.uploader.uploadAll();
732
- this.uploading = true;
733
- }
734
- }
735
- else {
736
- console.log('Stuff not working');
737
- }
738
- }
739
- }
740
- }
741
- MediaUploadModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: MediaUploadModalComponent, deps: [{ token: i1$2.MatDialogRef }, { token: UploadService }], target: i0.ɵɵFactoryTarget.Component });
742
- MediaUploadModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: MediaUploadModalComponent, selector: "app-media-upload-modal", inputs: { allowedMimeTypes: "allowedMimeTypes", uploadUrlKey: "uploadUrlKey", file: "file" }, host: { listeners: { "document:paste": "onPaste($event)" } }, ngImport: i0, template: "<h1 mat-dialog-title>Upload an Image</h1>\n<!--<mat-radio-group aria-label=\"Select an option\">-->\n<!-- <mat-radio-button class=\"option\" value=\"unpublished\">Unpublished</mat-radio-button>-->\n<!-- <mat-radio-button class=\"option\" value=\"published\">Published</mat-radio-button>-->\n<!--</mat-radio-group>-->\n<mat-divider class=\"option-list-divider\"></mat-divider>\n<div mat-dialog-content>\n <div *ngIf=\"uploading\">\n <fa-icon [icon]=\"'spinner'\" [spin]=\"true\"></fa-icon>\n </div>\n <ng-container *ngIf=\"!imgLink && !uploading\">\n <h4>Select a File</h4>\n <div class=\"input-group\">\n <div class=\"form-group\">\n <!-- <label for=\"import_file\">Choose File</label>-->\n <input type=\"file\" id=\"import_file\"\n *ngIf=\"uploader.queue.length==0 && !uploading\"\n ng2FileSelect\n [uploader]=\"uploader\"\n (onFileSelected)=\"onFileSelected($event)\"\n >\n </div>\n </div>\n <br>\n <h3>Paste a File</h3>\n <p>You can use the paste command to paste any image here</p>\n </ng-container>\n <div *ngIf=\"imgLink\">\n <img *ngIf=\"imgLink\" [src]=\"imgLink\"/>\n </div>\n <div *ngIf=\"error\">\n <div class=\"alert alert-danger\">\n {{error}}\n </div>\n </div>\n</div>\n<div mat-dialog-actions>\n <button mat-button [disabled]=\"!imgLink || uploading\" (click)=\"close()\">Attach</button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i1$3.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }, { kind: "directive", type: i7.FileSelectDirective, selector: "[ng2FileSelect]", inputs: ["uploader"], outputs: ["onFileSelected"] }] });
743
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: MediaUploadModalComponent, decorators: [{
744
- type: Component,
745
- args: [{ selector: 'app-media-upload-modal', template: "<h1 mat-dialog-title>Upload an Image</h1>\n<!--<mat-radio-group aria-label=\"Select an option\">-->\n<!-- <mat-radio-button class=\"option\" value=\"unpublished\">Unpublished</mat-radio-button>-->\n<!-- <mat-radio-button class=\"option\" value=\"published\">Published</mat-radio-button>-->\n<!--</mat-radio-group>-->\n<mat-divider class=\"option-list-divider\"></mat-divider>\n<div mat-dialog-content>\n <div *ngIf=\"uploading\">\n <fa-icon [icon]=\"'spinner'\" [spin]=\"true\"></fa-icon>\n </div>\n <ng-container *ngIf=\"!imgLink && !uploading\">\n <h4>Select a File</h4>\n <div class=\"input-group\">\n <div class=\"form-group\">\n <!-- <label for=\"import_file\">Choose File</label>-->\n <input type=\"file\" id=\"import_file\"\n *ngIf=\"uploader.queue.length==0 && !uploading\"\n ng2FileSelect\n [uploader]=\"uploader\"\n (onFileSelected)=\"onFileSelected($event)\"\n >\n </div>\n </div>\n <br>\n <h3>Paste a File</h3>\n <p>You can use the paste command to paste any image here</p>\n </ng-container>\n <div *ngIf=\"imgLink\">\n <img *ngIf=\"imgLink\" [src]=\"imgLink\"/>\n </div>\n <div *ngIf=\"error\">\n <div class=\"alert alert-danger\">\n {{error}}\n </div>\n </div>\n</div>\n<div mat-dialog-actions>\n <button mat-button [disabled]=\"!imgLink || uploading\" (click)=\"close()\">Attach</button>\n</div>\n" }]
746
- }], ctorParameters: function () { return [{ type: i1$2.MatDialogRef }, { type: UploadService }]; }, propDecorators: { allowedMimeTypes: [{
747
- type: Input
748
- }], uploadUrlKey: [{
749
- type: Input
750
- }], file: [{
751
- type: Input
752
- }], onPaste: [{
753
- type: HostListener,
754
- args: ['document:paste', ['$event']]
755
- }] } });
756
-
757
- class EntryCreatorComponent {
758
- static getCookie(name) {
759
- const ca = document.cookie.split(';');
760
- const caLen = ca.length;
761
- const cookieName = `${name}=`;
762
- let c;
763
- for (let i = 0; i < caLen; i += 1) {
764
- c = ca[i].replace(/^\s+/g, '');
765
- if (c.indexOf(cookieName) === 0) {
766
- return c.substring(cookieName.length, c.length);
767
- }
768
- }
769
- return '';
770
- }
771
- constructor(entryService, tagService, identityService, cdr, dialog) {
772
- this.entryService = entryService;
773
- this.tagService = tagService;
774
- this.identityService = identityService;
775
- this.cdr = cdr;
776
- this.dialog = dialog;
777
- this.ContentType = ContentType;
778
- this.Object = Object;
779
- this.entry = null;
780
- this.separatorKeysCodes = [ENTER, COMMA, TAB];
781
- this.removable = true;
782
- this.all_tags = ['Angular', 'Bash', 'MacOS', 'Typescript', 'NPM', 'Databases'];
783
- this.tagCtrl = new UntypedFormControl();
784
- this.publishDateControl = new UntypedFormControl();
785
- this.selectable = false;
786
- this.scheduling = false;
787
- this.customScheduleTime = '';
788
- this.today = new Date();
789
- this.allowedMimeTypes = [
790
- 'image/jpeg',
791
- 'image/gif',
792
- 'image/png',
793
- 'image/jpg',
794
- 'video/mp4',
795
- 'video/webm',
796
- 'video/ogg',
797
- ];
798
- this.uploadUrlKey = 'path_to_file';
799
- this.uploader = new FileUploader({
800
- url: '/file_api/uploads/create_image/',
801
- itemAlias: 'file',
802
- authToken: '',
803
- headers: [
804
- {
805
- name: 'X-CSRFToken',
806
- value: EntryCreatorComponent.getCookie('csrftoken')
807
- },
808
- ],
809
- additionalParameter: {
810
- 'csrf_token': EntryCreatorComponent.getCookie('csrftoken')
811
- },
812
- removeAfterUpload: true,
813
- allowedMimeType: this.allowedMimeTypes,
814
- });
815
- const scheduledDate = new Date();
816
- this.customScheduleTime = scheduledDate.getHours() + ':' + scheduledDate.getMinutes() + ' AM';
817
- }
818
- _filter(value) {
819
- const filterValue = value.toLowerCase();
820
- return this.all_tags.filter(tag => tag.toLowerCase().indexOf(filterValue) === 0);
821
- }
822
- add(event) {
823
- const input = event.input;
824
- const value = event.value;
825
- // Add our tag
826
- if ((value || '').trim()) {
827
- this.tags.push(value.trim());
828
- }
829
- // Reset the input value
830
- if (input) {
831
- input.value = '';
832
- }
833
- this.tagCtrl.setValue(null);
834
- this.onChange();
835
- }
836
- remove(fruit) {
837
- const index = this.tags.indexOf(fruit);
838
- if (index >= 0) {
839
- this.tags.splice(index, 1);
840
- }
841
- this.onChange();
842
- }
843
- selected(event) {
844
- this.tags.push(event.option.viewValue);
845
- this.tagInput.nativeElement.value = '';
846
- this.tagCtrl.setValue(null);
847
- this.onChange();
848
- }
849
- refreshTags() {
850
- this.tagService.get().subscribe((response) => {
851
- this.all_tags = map$1(response.results, (t) => t.label);
852
- this.filtered_tags = this.tagCtrl.valueChanges.pipe(startWith(null), map((tag) => tag ? this._filter(tag) : this.all_tags.slice()));
853
- });
854
- }
855
- createNewEntry() {
856
- this.entry = new Entry();
857
- this.entry.title = EntryCreatorComponent.DEFAULT_NEW_ENTRY_TITLE;
858
- this.entry.published = false;
859
- this.entry.version = 1;
860
- this.entryService.create(this.entry).subscribe((response) => {
861
- this.entry = response;
862
- this.entry.sort();
863
- setTimeout(() => {
864
- this.entryService.currentlyEditedEntry.next(this.entry);
865
- }, 10);
866
- });
867
- }
868
- ngOnInit() {
869
- this.refreshTags();
870
- this.identityService.getMe().subscribe((me) => {
871
- this.me = me;
872
- });
873
- const savedEntry = localStorage.getItem(EntryCreatorComponent.CURRENT_ENTRY);
874
- if (savedEntry) {
875
- this.entry = new Entry(JSON.parse(savedEntry));
876
- if (this.entry.should_publish_in_future && this.entry.future_publish_date < new Date()) {
877
- this.createNewEntry();
878
- }
879
- this.entry.sort();
880
- if (this.entry.should_publish_in_future) {
881
- // Restore scheduling settings
882
- this.scheduling = true;
883
- let hours = this.entry.future_publish_date.getHours();
884
- let minutes = this.entry.future_publish_date.getMinutes();
885
- const ampm = hours >= 12 ? 'PM' : 'AM';
886
- if (hours >= 12) {
887
- hours = hours % 12;
888
- hours = hours ? hours : 12;
889
- }
890
- minutes = minutes < 10 ? '0' + minutes : minutes;
891
- this.customScheduleTime = hours + ':' + minutes + ' ' + ampm;
892
- }
893
- setTimeout(() => {
894
- this.entryService.currentlyEditedEntry.next(this.entry);
895
- }, 10);
896
- }
897
- else {
898
- this.seeEntries();
899
- }
900
- this.uploader.onCompleteItem = (item, response) => {
901
- // const responseObj = JSON.parse(response)
902
- // this.uploadId = responseObj.id;
903
- };
904
- this.uploader.onWhenAddingFileFailed = (item, uploadFilter, options) => {
905
- // this.error = 'This file is not a supported mimetype.'
906
- // this.uploading = false;
907
- };
908
- this.tags = this.entry.tags;
909
- }
910
- onFileSelected(e) {
911
- this.uploader.uploadAll();
912
- }
913
- startUploader(content) {
914
- const dialogRef = this.dialog.open(MediaUploadModalComponent, {});
915
- dialogRef.componentInstance.allowedMimeTypes = this.allowedMimeTypes;
916
- dialogRef.componentInstance.uploadUrlKey = this.uploadUrlKey;
917
- dialogRef.afterClosed().subscribe(() => {
918
- content.value = dialogRef.componentInstance.imgLink;
919
- content.additional = [];
920
- content.additional.push({ key: Content.KEY_MIMETYPE, value: dialogRef.componentInstance.mimeType });
921
- this.onChange();
922
- });
923
- }
924
- addSection() {
925
- this.entry.sections.push(new Section());
926
- this.onChange();
927
- }
928
- removeSection(section) {
929
- const remove = confirm('Are you sure you want to remove this section?');
930
- if (remove) {
931
- this.entry.sections =
932
- filter(this.entry.sections, (sct) => sct.id !== section.id);
933
- this.onChange();
934
- }
935
- }
936
- addContent(section) {
937
- section.contents.push(new Content());
938
- this.onChange();
939
- }
940
- removeContent(content) {
941
- const remove = confirm('Are you sure you want to remove this content?');
942
- if (remove) {
943
- for (const section of this.entry.sections) {
944
- section.contents = filter(section.contents, (ct) => ct.id !== content.id);
945
- }
946
- this.onChange();
947
- }
948
- }
949
- onChange() {
950
- this.entry.slug = this.entryService.slugify(this.entry.title).toLowerCase();
951
- localStorage.setItem(EntryCreatorComponent.CURRENT_ENTRY, JSON.stringify(this.entry));
952
- this.entry.sort();
953
- this.cdr.detectChanges();
954
- this.entryService.currentlyEditedEntry.next(this.entry);
955
- this.entryService._currentlyEditedEntry = this.entry;
956
- }
957
- resetDate() {
958
- this.entry.create_date = new Date();
959
- this.entry.edit_date = new Date();
960
- this.onChange();
961
- }
962
- startNew() {
963
- const finish = confirm('Are you sure your finished? The JSON and entry displayed will be removed. Make sure you have already copied it.');
964
- if (finish) {
965
- this.entry = new Entry();
966
- this.entry.title = EntryCreatorComponent.DEFAULT_NEW_ENTRY_TITLE;
967
- this.entry.published = false;
968
- this.entry.version = 1;
969
- this.entryService.currentlyEditedEntry.next(this.entry);
970
- localStorage.setItem(EntryCreatorComponent.CURRENT_ENTRY, JSON.stringify(this.entry));
971
- this.entryService.create(this.entry).subscribe((next) => {
972
- });
973
- }
974
- }
975
- seeEntries() {
976
- const dialogRef = this.dialog.open(EntrySelectorDialogComponent, {
977
- width: '800px',
978
- data: { name: 'test', animal: 'test' }
979
- });
980
- dialogRef.afterClosed().subscribe((id) => {
981
- if (id) {
982
- this.entryService.getUnpublishedById(id).subscribe((result) => {
983
- const entry = result;
984
- this.entryService.currentlyEditedEntry.next(entry);
985
- localStorage.setItem(EntryCreatorComponent.CURRENT_ENTRY, JSON.stringify(entry));
986
- this.entry = entry;
987
- });
988
- }
989
- });
990
- }
991
- postPublishCallback() {
992
- this.entryService.currentlyEditedEntry.next(null);
993
- this.entry = null;
994
- this.seeEntries();
995
- }
996
- cancelScheduling() {
997
- this.entry.future_publish_date = null;
998
- this.entry.should_publish_in_future = false;
999
- this.scheduling = false;
1000
- this.onChange();
1001
- }
1002
- exposeScheduling() {
1003
- const scheduledDate = new Date();
1004
- scheduledDate.setDate(scheduledDate.getDate() + 1);
1005
- this.entry.future_publish_date = scheduledDate;
1006
- this.setTime(this.customScheduleTime);
1007
- this.entry.should_publish_in_future = true;
1008
- this.scheduling = true;
1009
- this.onChange();
1010
- }
1011
- publish() {
1012
- const publish = confirm('Are you sure you want to publish? Once an article is published it is available to everyone.');
1013
- if (publish) {
1014
- this.entry.published = true;
1015
- this.entry.publish_date = new Date();
1016
- this.entry.edit_date = new Date();
1017
- this.entryService.updateUnpublishedEntry(this.entry).subscribe(this.postPublishCallback.bind(this));
1018
- }
1019
- }
1020
- delete() {
1021
- const confirmDelete = confirm('Are you sure you want to delete this draft? Once it is deleted it cannot be recovered.');
1022
- if (confirmDelete) {
1023
- this.entryService.delete(this.entry).subscribe(() => {
1024
- this.entry = null;
1025
- this.entryService.currentlyEditedEntry.next(null);
1026
- localStorage.removeItem(EntryCreatorComponent.CURRENT_ENTRY);
1027
- });
1028
- }
1029
- }
1030
- onDateChange() {
1031
- this.entry.future_publish_date.setHours(this.hours);
1032
- this.entry.future_publish_date.setMinutes(this.minutes);
1033
- this.onChange();
1034
- }
1035
- setTime(e) {
1036
- const firstTimeSplit = e.split(' ');
1037
- const secondTimeSplit = firstTimeSplit[0].split(':');
1038
- this.hours = Number(secondTimeSplit[0]);
1039
- this.minutes = Number(secondTimeSplit[1]);
1040
- if (firstTimeSplit[1] === 'PM') {
1041
- this.hours = Number(this.hours) + 12;
1042
- }
1043
- this.entry.future_publish_date.setHours(this.hours);
1044
- this.entry.future_publish_date.setMinutes(this.minutes);
1045
- this.onChange();
1046
- }
1047
- }
1048
- EntryCreatorComponent.CURRENT_ENTRY = 'current_entry';
1049
- EntryCreatorComponent.DEFAULT_NEW_ENTRY_TITLE = 'A New Entry';
1050
- EntryCreatorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntryCreatorComponent, deps: [{ token: EntryService }, { token: TagService }, { token: IdentityService }, { token: i0.ChangeDetectorRef }, { token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
1051
- EntryCreatorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: EntryCreatorComponent, selector: "app-entry-creator", inputs: { allowedMimeTypes: "allowedMimeTypes", uploadUrlKey: "uploadUrlKey" }, viewQueries: [{ propertyName: "tagInput", first: true, predicate: ["tagInput"], descendants: true }, { propertyName: "matAutocomplete", first: true, predicate: ["tagauto"], descendants: true }], ngImport: i0, template: "<div class=\"section creator fields\">\n <form #createForm=\"ngForm\" (change)=\"onChange()\" *ngIf=\"this.entry\">\n <div class=\"form-group\">\n <mat-form-field class=\"full-width\">\n <mat-label>Title</mat-label>\n <input matInput\n [(ngModel)]=\"entry.title\"\n name=\"title\">\n </mat-form-field>\n </div>\n <mat-card class=\"form-section tags\">\n <div>\n <mat-form-field class=\"full-width\" hintLabel=\"Use a comma to seperate different tags\">\n <mat-chip-listbox #tagList aria-label=\"Tags\">\n <mat-chip-option\n *ngFor=\"let tag of tags\"\n [selectable]=\"selectable\"\n [removable]=\"removable\"\n (removed)=\"remove(tag)\">\n {{tag}}\n <mat-icon matChipRemove *ngIf=\"removable\">cancel</mat-icon>\n </mat-chip-option>\n <input\n matInput\n placeholder=\"Tags...\"\n #tagInput\n [formControl]=\"tagCtrl\"\n [matAutocomplete]=\"tagauto\"\n [matChipInputFor]=\"tagList\"\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\n (matChipInputTokenEnd)=\"add($event)\">\n </mat-chip-listbox>\n <mat-autocomplete #tagauto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n <mat-option *ngFor=\"let tag of filtered_tags | async\" [value]=\"tag\">\n {{tag}}\n </mat-option>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n </mat-card>\n <mat-card class=\"form-section\" *ngFor=\"let section of entry.sections\">\n <div>\n <mat-form-field class=\"full-width\">\n <mat-label>Subheading</mat-label>\n <input matInput\n [(ngModel)]=\"section.subheading\"\n name=\"{{section.id}}-subheading\">\n </mat-form-field>\n <div class=\"form-content\" *ngFor=\"let content of section.contents\">\n <div class=\"form-group\">\n <mat-radio-group\n aria-label=\"Select the Content Type\"\n name=\"{{content.id}}-content-type\"\n class=\"radio-group\"\n [(ngModel)]=\"content.type\">\n <mat-radio-button\n *ngFor=\"let value of Object.values(ContentType)\"\n class=\"radio-button\"\n [value]=\"value\">{{value}}\n </mat-radio-button>\n </mat-radio-group>\n </div>\n <ng-container [ngSwitch]=\"content.type\">\n <ng-container *ngSwitchCase=\"ContentType.URL\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>Title</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-title\"\n [(ngModel)]=\"content.title\">\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.TEXT\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <textarea matInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"3\"\n cdkAutosizeMaxRows=\"20\"\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\"\n ></textarea>\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.HTML\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <textarea matInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"3\"\n cdkAutosizeMaxRows=\"20\"\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\"\n ></textarea>\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.CODE\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <textarea matInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"10\"\n cdkAutosizeMaxRows=\"100\"\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\"\n ></textarea>\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.IMAGE\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-source\"\n [(ngModel)]=\"content.value\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>Description</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-description\"\n [(ngModel)]=\"content.description\">\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.MEDIA\">\n <div class=\"full-width\">\n <ng-container *ngIf=\"content.value\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>Description</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-description\"\n [(ngModel)]=\"content.description\">\n </mat-form-field>\n </ng-container>\n <ng-container *ngIf=\"content.additional\">\n <ng-container *ngFor=\"let add of content.additional\">\n <mat-form-field class=\"full-width\">\n <mat-label>{{add.key}}</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-{{add.key}}\"\n [(ngModel)]=\"add.value\"\n [disabled]=\"true\"\n >\n </mat-form-field>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!content.value\">\n <button mat-raised-button (click)=startUploader(content)>Upload</button>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n <button mat-raised-button (click)=removeContent(content)>Remove Content</button>\n <button mat-raised-button (click)=\"addContent(section)\">+ Add Content</button>\n </div>\n <button mat-raised-button (click)=\"removeSection(section)\">Remove Section</button>\n <button mat-raised-button (click)=\"addContent(section)\" *ngIf=\"section.contents.length === 0\">+ Add\n Content\n </button>\n <button mat-raised-button (click)=\"addSection()\">+ Add Section</button>\n </div>\n\n </mat-card>\n <button mat-raised-button (click)=\"addSection()\" *ngIf=\"entry.sections?.length === 0\">+ Add Section</button>\n <button mat-raised-button (click)=\"addSection()\" *ngIf=\"!entry.sections\">+ Add Section</button>\n\n <div class=\"controls\">\n <button mat-raised-button (click)=\"resetDate()\">Reset the Date</button>\n <button mat-raised-button (click)=\"delete()\">Delete</button>\n <button mat-raised-button [disabled]=\"scheduling\" (click)=\"publish()\">Publish</button>\n <button mat-raised-button [disabled]=\"scheduling\" (click)=\"exposeScheduling()\">Schedule</button>\n <button mat-raised-button (click)=\"startNew()\">New</button>\n </div>\n <p *ngIf=\"scheduling\">Publishing is disabled while scheduling is being used.</p>\n\n <mat-card [hidden]=\"!scheduling\">\n <h4>\n Scheduling Options\n </h4>\n\n <div class=\"form-group\">\n <mat-form-field class=\"full-width\">\n <mat-label>Date</mat-label>\n <input\n #futurePublishDate\n matInput\n [matDatepicker]=\"picker\"\n [min]=\"today\"\n (dateInput)=\"onDateChange()\"\n (dateChange)=\"onDateChange()\"\n [(ngModel)]=\"entry.future_publish_date\"\n name=\"future-publish-date\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n #picker></mat-datepicker>\n </mat-form-field>\n\n <mat-label>Time</mat-label>\n <ngx-timepicker-field\n [defaultTime]=\"customScheduleTime\"\n [format]=\"12\"\n [buttonAlign]=\"'left'\"\n (timeChanged)=\"setTime($event)\"\n ></ngx-timepicker-field>\n <p>Times are represented in your local time zone</p>\n </div>\n\n <div mat-dialog-actions>\n <div class=\"controls\">\n <button mat-raised-button (click)=\"cancelScheduling()\">Cancel Scheduling</button>\n </div>\n </div>\n <p>This post will be published as soon as its scheduled date and time arrive. No further action is needed by you. If you do not\n want to use scheduling, you can cancel scheduling and manually publish.</p>\n </mat-card>\n </form>\n <div class=\"controls\">\n <button mat-raised-button (click)=\"seeEntries()\">See Entries</button>\n <button *ngIf=\"!this.entry\" mat-raised-button (click)=\"startNew()\">New</button>\n </div>\n</div>\n", styles: [".creator{min-height:calc(100vh - 100px)}form{padding:20px}.content{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}button{margin:4px}.radio-group{display:flex;flex-direction:column;margin:15px 0}.radio-button{margin:4px}.full-width{width:100%}.content-card{margin:0 0 10px}.form-section{margin-bottom:10px}.form-content:not(:last-child){border-bottom:1px dotted #aaa;padding-bottom:10px}.controls{display:inline-block;width:100%;padding:10px}[hidden]{display:none!important}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i6$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i11.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "directive", type: i12.MatRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i12.MatRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i13.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i14.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i13.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i15.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "component", type: i15.MatChipListbox, selector: "mat-chip-listbox", inputs: ["tabIndex", "multiple", "aria-orientation", "selectable", "compareWith", "required", "value"], outputs: ["change"] }, { kind: "component", type: i15.MatChipOption, selector: "mat-basic-chip-option, mat-chip-option", inputs: ["color", "disabled", "disableRipple", "tabIndex", "selectable", "selected"], outputs: ["selectionChange"] }, { kind: "directive", type: i15.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i16.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i17.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i17.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i17.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i6$2.NgxTimepickerFieldComponent, selector: "ngx-timepicker-field", inputs: ["buttonAlign", "format", "min", "max", "defaultTime", "disabled", "toggleIcon", "clockTheme", "controlOnly", "cancelBtnTmpl", "confirmBtnTmpl"], outputs: ["timeChanged"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }] });
1052
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntryCreatorComponent, decorators: [{
1053
- type: Component,
1054
- args: [{ selector: 'app-entry-creator', template: "<div class=\"section creator fields\">\n <form #createForm=\"ngForm\" (change)=\"onChange()\" *ngIf=\"this.entry\">\n <div class=\"form-group\">\n <mat-form-field class=\"full-width\">\n <mat-label>Title</mat-label>\n <input matInput\n [(ngModel)]=\"entry.title\"\n name=\"title\">\n </mat-form-field>\n </div>\n <mat-card class=\"form-section tags\">\n <div>\n <mat-form-field class=\"full-width\" hintLabel=\"Use a comma to seperate different tags\">\n <mat-chip-listbox #tagList aria-label=\"Tags\">\n <mat-chip-option\n *ngFor=\"let tag of tags\"\n [selectable]=\"selectable\"\n [removable]=\"removable\"\n (removed)=\"remove(tag)\">\n {{tag}}\n <mat-icon matChipRemove *ngIf=\"removable\">cancel</mat-icon>\n </mat-chip-option>\n <input\n matInput\n placeholder=\"Tags...\"\n #tagInput\n [formControl]=\"tagCtrl\"\n [matAutocomplete]=\"tagauto\"\n [matChipInputFor]=\"tagList\"\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\n (matChipInputTokenEnd)=\"add($event)\">\n </mat-chip-listbox>\n <mat-autocomplete #tagauto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n <mat-option *ngFor=\"let tag of filtered_tags | async\" [value]=\"tag\">\n {{tag}}\n </mat-option>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n </mat-card>\n <mat-card class=\"form-section\" *ngFor=\"let section of entry.sections\">\n <div>\n <mat-form-field class=\"full-width\">\n <mat-label>Subheading</mat-label>\n <input matInput\n [(ngModel)]=\"section.subheading\"\n name=\"{{section.id}}-subheading\">\n </mat-form-field>\n <div class=\"form-content\" *ngFor=\"let content of section.contents\">\n <div class=\"form-group\">\n <mat-radio-group\n aria-label=\"Select the Content Type\"\n name=\"{{content.id}}-content-type\"\n class=\"radio-group\"\n [(ngModel)]=\"content.type\">\n <mat-radio-button\n *ngFor=\"let value of Object.values(ContentType)\"\n class=\"radio-button\"\n [value]=\"value\">{{value}}\n </mat-radio-button>\n </mat-radio-group>\n </div>\n <ng-container [ngSwitch]=\"content.type\">\n <ng-container *ngSwitchCase=\"ContentType.URL\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>Title</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-title\"\n [(ngModel)]=\"content.title\">\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.TEXT\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <textarea matInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"3\"\n cdkAutosizeMaxRows=\"20\"\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\"\n ></textarea>\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.HTML\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <textarea matInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"3\"\n cdkAutosizeMaxRows=\"20\"\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\"\n ></textarea>\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.CODE\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <textarea matInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"10\"\n cdkAutosizeMaxRows=\"100\"\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\"\n ></textarea>\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.IMAGE\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-source\"\n [(ngModel)]=\"content.value\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>Description</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-description\"\n [(ngModel)]=\"content.description\">\n </mat-form-field>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.MEDIA\">\n <div class=\"full-width\">\n <ng-container *ngIf=\"content.value\">\n <mat-form-field class=\"full-width\">\n <mat-label>Value</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-value\"\n [(ngModel)]=\"content.value\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>Description</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-description\"\n [(ngModel)]=\"content.description\">\n </mat-form-field>\n </ng-container>\n <ng-container *ngIf=\"content.additional\">\n <ng-container *ngFor=\"let add of content.additional\">\n <mat-form-field class=\"full-width\">\n <mat-label>{{add.key}}</mat-label>\n <input\n matInput\n name=\"{{content.id}}-content-{{add.key}}\"\n [(ngModel)]=\"add.value\"\n [disabled]=\"true\"\n >\n </mat-form-field>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!content.value\">\n <button mat-raised-button (click)=startUploader(content)>Upload</button>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n <button mat-raised-button (click)=removeContent(content)>Remove Content</button>\n <button mat-raised-button (click)=\"addContent(section)\">+ Add Content</button>\n </div>\n <button mat-raised-button (click)=\"removeSection(section)\">Remove Section</button>\n <button mat-raised-button (click)=\"addContent(section)\" *ngIf=\"section.contents.length === 0\">+ Add\n Content\n </button>\n <button mat-raised-button (click)=\"addSection()\">+ Add Section</button>\n </div>\n\n </mat-card>\n <button mat-raised-button (click)=\"addSection()\" *ngIf=\"entry.sections?.length === 0\">+ Add Section</button>\n <button mat-raised-button (click)=\"addSection()\" *ngIf=\"!entry.sections\">+ Add Section</button>\n\n <div class=\"controls\">\n <button mat-raised-button (click)=\"resetDate()\">Reset the Date</button>\n <button mat-raised-button (click)=\"delete()\">Delete</button>\n <button mat-raised-button [disabled]=\"scheduling\" (click)=\"publish()\">Publish</button>\n <button mat-raised-button [disabled]=\"scheduling\" (click)=\"exposeScheduling()\">Schedule</button>\n <button mat-raised-button (click)=\"startNew()\">New</button>\n </div>\n <p *ngIf=\"scheduling\">Publishing is disabled while scheduling is being used.</p>\n\n <mat-card [hidden]=\"!scheduling\">\n <h4>\n Scheduling Options\n </h4>\n\n <div class=\"form-group\">\n <mat-form-field class=\"full-width\">\n <mat-label>Date</mat-label>\n <input\n #futurePublishDate\n matInput\n [matDatepicker]=\"picker\"\n [min]=\"today\"\n (dateInput)=\"onDateChange()\"\n (dateChange)=\"onDateChange()\"\n [(ngModel)]=\"entry.future_publish_date\"\n name=\"future-publish-date\"\n >\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n #picker></mat-datepicker>\n </mat-form-field>\n\n <mat-label>Time</mat-label>\n <ngx-timepicker-field\n [defaultTime]=\"customScheduleTime\"\n [format]=\"12\"\n [buttonAlign]=\"'left'\"\n (timeChanged)=\"setTime($event)\"\n ></ngx-timepicker-field>\n <p>Times are represented in your local time zone</p>\n </div>\n\n <div mat-dialog-actions>\n <div class=\"controls\">\n <button mat-raised-button (click)=\"cancelScheduling()\">Cancel Scheduling</button>\n </div>\n </div>\n <p>This post will be published as soon as its scheduled date and time arrive. No further action is needed by you. If you do not\n want to use scheduling, you can cancel scheduling and manually publish.</p>\n </mat-card>\n </form>\n <div class=\"controls\">\n <button mat-raised-button (click)=\"seeEntries()\">See Entries</button>\n <button *ngIf=\"!this.entry\" mat-raised-button (click)=\"startNew()\">New</button>\n </div>\n</div>\n", styles: [".creator{min-height:calc(100vh - 100px)}form{padding:20px}.content{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}button{margin:4px}.radio-group{display:flex;flex-direction:column;margin:15px 0}.radio-button{margin:4px}.full-width{width:100%}.content-card{margin:0 0 10px}.form-section{margin-bottom:10px}.form-content:not(:last-child){border-bottom:1px dotted #aaa;padding-bottom:10px}.controls{display:inline-block;width:100%;padding:10px}[hidden]{display:none!important}\n"] }]
1055
- }], ctorParameters: function () { return [{ type: EntryService }, { type: TagService }, { type: IdentityService }, { type: i0.ChangeDetectorRef }, { type: i1$2.MatDialog }]; }, propDecorators: { tagInput: [{
1056
- type: ViewChild,
1057
- args: ['tagInput']
1058
- }], matAutocomplete: [{
1059
- type: ViewChild,
1060
- args: ['tagauto']
1061
- }], allowedMimeTypes: [{
1062
- type: Input
1063
- }], uploadUrlKey: [{
1064
- type: Input
1065
- }] } });
1066
-
1067
- class StaticHtmlComponent {
1068
- constructor(staticHtmlService, domSanitizer) {
1069
- this.staticHtmlService = staticHtmlService;
1070
- this.domSanitizer = domSanitizer;
1071
- }
1072
- refreshContent() {
1073
- this.innerHtml = this.domSanitizer.bypassSecurityTrustHtml(this.staticHtmlService.mapStaticHtml(this.value, false));
1074
- }
1075
- ngOnChanges(changes) {
1076
- this.refreshContent();
1077
- }
1078
- ngOnInit() {
1079
- this.refreshContent();
1080
- }
1081
- }
1082
- StaticHtmlComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: StaticHtmlComponent, deps: [{ token: StaticHtmlService }, { token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
1083
- StaticHtmlComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: StaticHtmlComponent, selector: "app-static-html", inputs: { value: "value" }, usesOnChanges: true, ngImport: i0, template: "<div [innerHtml]=\"innerHtml\">\n</div>\n", styles: [""] });
1084
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: StaticHtmlComponent, decorators: [{
1085
- type: Component,
1086
- args: [{ selector: 'app-static-html', template: "<div [innerHtml]=\"innerHtml\">\n</div>\n" }]
1087
- }], ctorParameters: function () { return [{ type: StaticHtmlService }, { type: i1$1.DomSanitizer }]; }, propDecorators: { value: [{
1088
- type: Input
1089
- }] } });
1090
-
1091
- class TimeAgoPipe {
1092
- constructor(changeDetectorRef, ngZone) {
1093
- this.changeDetectorRef = changeDetectorRef;
1094
- this.ngZone = ngZone;
1095
- }
1096
- transform(value) {
1097
- this.removeTimer();
1098
- let d = new Date(value);
1099
- let now = new Date();
1100
- let seconds = Math.round(Math.abs((now.getTime() - d.getTime()) / 1000));
1101
- let timeToUpdate = (Number.isNaN(seconds)) ? 1000 : this.getSecondsUntilUpdate(seconds) * 1000;
1102
- this.timer = this.ngZone.runOutsideAngular(() => {
1103
- if (typeof window !== 'undefined') {
1104
- return window.setTimeout(() => {
1105
- this.ngZone.run(() => this.changeDetectorRef.markForCheck());
1106
- }, timeToUpdate);
1107
- }
1108
- return null;
1109
- });
1110
- let minutes = Math.round(Math.abs(seconds / 60));
1111
- let hours = Math.round(Math.abs(minutes / 60));
1112
- let days = Math.round(Math.abs(hours / 24));
1113
- let months = Math.round(Math.abs(days / 30.416));
1114
- let years = Math.round(Math.abs(days / 365));
1115
- if (Number.isNaN(seconds)) {
1116
- return '';
1117
- }
1118
- else if (seconds <= 45) {
1119
- return 'a few seconds ago';
1120
- }
1121
- else if (seconds <= 90) {
1122
- return 'a minute ago';
1123
- }
1124
- else if (minutes <= 45) {
1125
- return minutes + ' minutes ago';
1126
- }
1127
- else if (minutes <= 90) {
1128
- return 'an hour ago';
1129
- }
1130
- else if (hours <= 22) {
1131
- return hours + ' hours ago';
1132
- }
1133
- else if (hours <= 36) {
1134
- return 'a day ago';
1135
- }
1136
- else if (days <= 25) {
1137
- return days + ' days ago';
1138
- }
1139
- else if (days <= 45) {
1140
- return 'a month ago';
1141
- }
1142
- else if (days <= 345) {
1143
- return months + ' months ago';
1144
- }
1145
- else if (days <= 545) {
1146
- return 'a year ago';
1147
- }
1148
- else { // (days > 545)
1149
- return years + ' years ago';
1150
- }
1151
- }
1152
- ngOnDestroy() {
1153
- this.removeTimer();
1154
- }
1155
- removeTimer() {
1156
- if (this.timer) {
1157
- window.clearTimeout(this.timer);
1158
- this.timer = null;
1159
- }
1160
- }
1161
- getSecondsUntilUpdate(seconds) {
1162
- let min = 60;
1163
- let hr = min * 60;
1164
- let day = hr * 24;
1165
- if (seconds < min) { // less than 1 min, update every 2 secs
1166
- return 2;
1167
- }
1168
- else if (seconds < hr) { // less than an hour, update every 30 secs
1169
- return 30;
1170
- }
1171
- else if (seconds < day) { // less then a day, update every 5 mins
1172
- return 300;
1173
- }
1174
- else { // update every hour
1175
- return 3600;
1176
- }
1177
- }
1178
- }
1179
- TimeAgoPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: TimeAgoPipe, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Pipe });
1180
- TimeAgoPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.1.4", ngImport: i0, type: TimeAgoPipe, name: "timeAgo", pure: false });
1181
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: TimeAgoPipe, decorators: [{
1182
- type: Pipe,
1183
- args: [{
1184
- name: 'timeAgo',
1185
- pure: false
1186
- }]
1187
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }]; } });
1188
-
1189
- class EntryRendererComponent {
1190
- constructor(prismService, ngZone, identityService, commentService, router, entryService) {
1191
- this.prismService = prismService;
1192
- this.ngZone = ngZone;
1193
- this.identityService = identityService;
1194
- this.commentService = commentService;
1195
- this.router = router;
1196
- this.entryService = entryService;
1197
- this.ContentType = ContentType;
1198
- this.comments = [];
1199
- this.commentText = '';
1200
- this.alert = alert;
1201
- this.editMode = false;
1202
- }
1203
- ngOnInit() {
1204
- this.identityService.getMe().subscribe((me) => {
1205
- this.me = me;
1206
- });
1207
- this.commentService.getComments(this.entry.id).subscribe((response) => {
1208
- this.comments = response.results;
1209
- for (const comment of this.comments) {
1210
- comment.date_obj = new Date(comment.created_on);
1211
- }
1212
- });
1213
- }
1214
- ngAfterViewChecked() {
1215
- if (!this.editMode) {
1216
- this.ngZone.runOutsideAngular(() => {
1217
- try {
1218
- this.prismService.highlightAll();
1219
- }
1220
- catch (e) {
1221
- }
1222
- });
1223
- }
1224
- }
1225
- edit(entry) {
1226
- entry.version++;
1227
- entry.published = false;
1228
- delete entry.publish_date;
1229
- this.entryService.create(entry).subscribe((response) => {
1230
- localStorage.setItem(EntryCreatorComponent.CURRENT_ENTRY, JSON.stringify(response));
1231
- this.router.navigateByUrl('create(left-col:create//right-col:create)').then(() => {
1232
- });
1233
- });
1234
- }
1235
- postComment(e) {
1236
- e.preventDefault();
1237
- if (this.commentText !== '') {
1238
- this.commentService.postComment({ entry: this.entry.id, content: this.commentText }).subscribe((comment) => {
1239
- this.comments.push(comment);
1240
- });
1241
- this.commentText = '';
1242
- }
1243
- }
1244
- mediaIsZip(content) {
1245
- let mediaIsZip = false;
1246
- if (content.additional) {
1247
- for (const add of content.additional) {
1248
- if (add.key === Content.KEY_MIMETYPE) {
1249
- if (add.value === 'application/zip') {
1250
- mediaIsZip = true;
1251
- }
1252
- }
1253
- }
1254
- }
1255
- return mediaIsZip;
1256
- }
1257
- approve(comment) {
1258
- comment.approved = !comment.approved;
1259
- this.commentService.patchComment(Object.assign({}, { approved: true }, comment)).subscribe((rComment) => {
1260
- });
1261
- }
1262
- unapprove(comment) {
1263
- comment.approved = !comment.approved;
1264
- this.commentService.patchComment(Object.assign({}, { approved: false }, comment)).subscribe((rComment) => {
1265
- });
1266
- }
1267
- }
1268
- EntryRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntryRendererComponent, deps: [{ token: PrismService }, { token: i0.NgZone }, { token: IdentityService }, { token: CommentService }, { token: i1$4.Router }, { token: EntryService }], target: i0.ɵɵFactoryTarget.Component });
1269
- EntryRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: EntryRendererComponent, selector: "app-entry-renderer", inputs: { entry: "entry", editMode: "editMode" }, ngImport: i0, template: "<div *ngIf=\"entry\">\n <h2>{{entry?.title}}</h2>\n <a *ngIf=\"me?.id === entry?.getProp('author_id')\" href=\"javascript:void(0)\" (click)=\"edit(entry)\"><h4>[Edit]</h4></a>\n <h3>Posted {{entry?.create_date.toString() | timeAgo}} on {{entry?.create_date?.getMonth() + 1}}/{{entry?.create_date?.getDate()}}/{{entry?.create_date?.getFullYear()}}</h3>\n <h5 *ngIf=\"entry?.showEditInformation()\">Article was last edited {{entry?.edit_date.toString() | timeAgo}}</h5>\n <br>\n <p *ngIf=\"entry?.tags?.length > 0\">Tags: <span *ngFor=\"let tag of entry?.tags; let last = last\">{{tag}}<ng-container *ngIf=\"!last\"> |\n </ng-container></span><span *ngIf=\"entry?.views\">, {{entry._friendly_views}} views</span></p>\n <br>\n\n <ng-container *ngFor=\"let section of entry?.sections\">\n <h4>{{section?.subheading}}</h4>\n <ng-container *ngFor=\"let content of section?.contents\">\n <ng-container [ngSwitch]=\"content.type\">\n <ng-container *ngSwitchCase=\"ContentType.CODE\">\n <pre><code class=\"language-ts\">{{content?.value}}</code></pre>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.URL\">\n <a [href]=\"content?.value\" target=\"_blank\">{{content.title}}</a><br>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.IMAGE\">\n <div class=\"restrict\">\n <div class=\"image\">\n <img [src]=\"content?.value\"/>\n </div>\n <div class=\"description\" *ngIf=\"content?.description\">{{content?.description}}</div>\n <div class=\"source\" *ngIf=\"content?.source\">\n <a [href]=\"content?.source\" [target]=\"'_blank'\">Source: {{content?.source}}</a>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"ContentType.MEDIA\">\n <ng-container *ngIf=\"mediaIsZip(content)\">\n <div class=\"download\">\n <a href=\"content?.value\">{{content?.description}}</a>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!mediaIsZip(content)\">\n <div class=\"restrict\">\n <div class=\"image\">\n <img [src]=\"content?.value\"/>\n </div>\n <div class=\"description\" *ngIf=\"content?.description\">{{content?.description}}</div>\n <div class=\"source\" *ngIf=\"content?.source\">\n <a [href]=\"content?.source\" [target]=\"'_blank'\">Source: {{content?.source}}</a>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.HTML\">\n <app-static-html\n [value]=\"content?.value\"\n >\n </app-static-html>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <p>{{content?.value}}</p>\n </ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container>\n <h2>Comments</h2>\n <p *ngIf=\"comments?.length == 0\">There are no comments yet.</p>\n <ng-container *ngIf=\"comments?.length > 0\">\n <div *ngFor=\"let comment of comments\">\n <mat-card style=\"margin-bottom: 20px;\" class=\"restrict\">\n <mat-card-title><img class=\"gravatar\" src=\"{{comment.gravatar_url}} + ?s=30\"> {{comment.user_display_name}}</mat-card-title>\n <mat-card-subtitle>{{comment.date_obj | timeAgo}}</mat-card-subtitle>\n <mat-card-content>\n <p>{{comment.content}}</p>\n <ng-container *ngIf=\"me?.id === entry?.__server_generated_properties?.author_id\">\n <a href=\"javascript:void(0);\" *ngIf=\"!comment?.approved\" (click)=\"approve(comment)\">Approve</a>\n <a href=\"javascript:void(0);\" *ngIf=\"comment?.approved\" (click)=\"unapprove(comment)\">Unapprove</a>\n </ng-container>\n </mat-card-content>\n </mat-card>\n </div>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!me\">\n <a href=\"/signup\">Signup</a> or <a href=\"/login\">login</a> to join the conversation!\n </ng-container>\n <ng-container *ngIf=\"me && !me?.comments_public\">\n <p>Note, your comments will not be public be default. It is possible I will make your comments public, but for now comments are just between you and me.</p>\n </ng-container>\n <ng-container *ngIf=\"me\">\n <h2 style=\"width: 100%;\">Leave a Comment</h2>\n <br>\n <mat-form-field class=\"restrict\" style=\"width: 100%;\" appearance=\"outline\">\n <mat-label>Comment</mat-label>\n <textarea [(ngModel)]=\"commentText\" (keydown.enter)=\"postComment($event)\" matInput></textarea>\n </mat-form-field>\n <br>\n <button (click)=\"postComment($event)\" style=\"text-align: right;\" mat-button>Submit</button>\n </ng-container>\n <div style=\"margin-bottom: 30px;\"></div>\n</div>\n\n", styles: [".image{width:100%;text-align:center;justify-content:center}.source,.description{text-align:center;font-size:12px}.gravatar{margin-right:20px}.smaller{text-size:12px;text-color:gray}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i6$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i8.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i8.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "component", type: StaticHtmlComponent, selector: "app-static-html", inputs: ["value"] }, { kind: "pipe", type: TimeAgoPipe, name: "timeAgo" }] });
1270
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntryRendererComponent, decorators: [{
1271
- type: Component,
1272
- args: [{ selector: 'app-entry-renderer', template: "<div *ngIf=\"entry\">\n <h2>{{entry?.title}}</h2>\n <a *ngIf=\"me?.id === entry?.getProp('author_id')\" href=\"javascript:void(0)\" (click)=\"edit(entry)\"><h4>[Edit]</h4></a>\n <h3>Posted {{entry?.create_date.toString() | timeAgo}} on {{entry?.create_date?.getMonth() + 1}}/{{entry?.create_date?.getDate()}}/{{entry?.create_date?.getFullYear()}}</h3>\n <h5 *ngIf=\"entry?.showEditInformation()\">Article was last edited {{entry?.edit_date.toString() | timeAgo}}</h5>\n <br>\n <p *ngIf=\"entry?.tags?.length > 0\">Tags: <span *ngFor=\"let tag of entry?.tags; let last = last\">{{tag}}<ng-container *ngIf=\"!last\"> |\n </ng-container></span><span *ngIf=\"entry?.views\">, {{entry._friendly_views}} views</span></p>\n <br>\n\n <ng-container *ngFor=\"let section of entry?.sections\">\n <h4>{{section?.subheading}}</h4>\n <ng-container *ngFor=\"let content of section?.contents\">\n <ng-container [ngSwitch]=\"content.type\">\n <ng-container *ngSwitchCase=\"ContentType.CODE\">\n <pre><code class=\"language-ts\">{{content?.value}}</code></pre>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.URL\">\n <a [href]=\"content?.value\" target=\"_blank\">{{content.title}}</a><br>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.IMAGE\">\n <div class=\"restrict\">\n <div class=\"image\">\n <img [src]=\"content?.value\"/>\n </div>\n <div class=\"description\" *ngIf=\"content?.description\">{{content?.description}}</div>\n <div class=\"source\" *ngIf=\"content?.source\">\n <a [href]=\"content?.source\" [target]=\"'_blank'\">Source: {{content?.source}}</a>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"ContentType.MEDIA\">\n <ng-container *ngIf=\"mediaIsZip(content)\">\n <div class=\"download\">\n <a href=\"content?.value\">{{content?.description}}</a>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!mediaIsZip(content)\">\n <div class=\"restrict\">\n <div class=\"image\">\n <img [src]=\"content?.value\"/>\n </div>\n <div class=\"description\" *ngIf=\"content?.description\">{{content?.description}}</div>\n <div class=\"source\" *ngIf=\"content?.source\">\n <a [href]=\"content?.source\" [target]=\"'_blank'\">Source: {{content?.source}}</a>\n </div>\n </div>\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.HTML\">\n <app-static-html\n [value]=\"content?.value\"\n >\n </app-static-html>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <p>{{content?.value}}</p>\n </ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n <ng-container>\n <h2>Comments</h2>\n <p *ngIf=\"comments?.length == 0\">There are no comments yet.</p>\n <ng-container *ngIf=\"comments?.length > 0\">\n <div *ngFor=\"let comment of comments\">\n <mat-card style=\"margin-bottom: 20px;\" class=\"restrict\">\n <mat-card-title><img class=\"gravatar\" src=\"{{comment.gravatar_url}} + ?s=30\"> {{comment.user_display_name}}</mat-card-title>\n <mat-card-subtitle>{{comment.date_obj | timeAgo}}</mat-card-subtitle>\n <mat-card-content>\n <p>{{comment.content}}</p>\n <ng-container *ngIf=\"me?.id === entry?.__server_generated_properties?.author_id\">\n <a href=\"javascript:void(0);\" *ngIf=\"!comment?.approved\" (click)=\"approve(comment)\">Approve</a>\n <a href=\"javascript:void(0);\" *ngIf=\"comment?.approved\" (click)=\"unapprove(comment)\">Unapprove</a>\n </ng-container>\n </mat-card-content>\n </mat-card>\n </div>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!me\">\n <a href=\"/signup\">Signup</a> or <a href=\"/login\">login</a> to join the conversation!\n </ng-container>\n <ng-container *ngIf=\"me && !me?.comments_public\">\n <p>Note, your comments will not be public be default. It is possible I will make your comments public, but for now comments are just between you and me.</p>\n </ng-container>\n <ng-container *ngIf=\"me\">\n <h2 style=\"width: 100%;\">Leave a Comment</h2>\n <br>\n <mat-form-field class=\"restrict\" style=\"width: 100%;\" appearance=\"outline\">\n <mat-label>Comment</mat-label>\n <textarea [(ngModel)]=\"commentText\" (keydown.enter)=\"postComment($event)\" matInput></textarea>\n </mat-form-field>\n <br>\n <button (click)=\"postComment($event)\" style=\"text-align: right;\" mat-button>Submit</button>\n </ng-container>\n <div style=\"margin-bottom: 30px;\"></div>\n</div>\n\n", styles: [".image{width:100%;text-align:center;justify-content:center}.source,.description{text-align:center;font-size:12px}.gravatar{margin-right:20px}.smaller{text-size:12px;text-color:gray}\n"] }]
1273
- }], ctorParameters: function () { return [{ type: PrismService }, { type: i0.NgZone }, { type: IdentityService }, { type: CommentService }, { type: i1$4.Router }, { type: EntryService }]; }, propDecorators: { entry: [{
1274
- type: Input
1275
- }], editMode: [{
1276
- type: Input
1277
- }] } });
1278
-
1279
- class EntrySummaryComponent {
1280
- constructor(router) {
1281
- this.router = router;
1282
- this.ContentType = ContentType;
1283
- }
1284
- ngOnInit() {
1285
- }
1286
- routeTo(entry) {
1287
- this.router.navigate(['/', 'blog', entry.slug]).then(() => {
1288
- });
1289
- }
1290
- }
1291
- EntrySummaryComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntrySummaryComponent, deps: [{ token: i1$4.Router }], target: i0.ɵɵFactoryTarget.Component });
1292
- EntrySummaryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: EntrySummaryComponent, selector: "app-entry-summary", inputs: { entry: "entry" }, ngImport: i0, template: "\n<div class=\"entry section restrict\">\n <h2>{{entry?.title}}</h2>\n <!-- <a href=\"javascript:void(0)\" (click)=\"edit(entry)\"><h6>[Edit]</h6></a>-->\n <h3>Posted {{entry?.create_date.toString() | timeAgo}} on {{entry?.create_date?.getMonth() + 1}}/{{entry?.create_date?.getDate()}}/{{entry?.create_date?.getFullYear()}}</h3>\n <h5 *ngIf=\"entry.showEditInformation()\">Article was last edited {{entry?.edit_date.toString() | timeAgo}}</h5>\n <br>\n\n <ng-container *ngFor=\"let section of entry?.sections.slice(0, 1)\">\n <h4>{{section?.subheading}}</h4>\n <ng-container *ngFor=\"let content of section?.contents.slice(0, 1)\">\n <ng-container [ngSwitch]=\"content.type\">\n <ng-container *ngSwitchCase=\"ContentType.CODE\">\n <pre><code class=\"language-ts\">{{content?.value}}</code></pre>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.URL\">\n <a [href]=\"content?.value\" target=\"_blank\">{{content.title}}</a>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.IMAGE\">\n <div class=\"restrict\">\n <div class=\"image\">\n <img [src]=\"content?.value\"/>\n </div>\n <div class=\"description\" *ngIf=\"content?.description\">{{content?.description}}</div>\n <div class=\"source\" *ngIf=\"content?.source\">\n <a [href]=\"content?.source\" [target]=\"'_blank'\">Source: {{content?.source}}</a>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.MEDIA\">\n <div class=\"restrict\">\n <div class=\"image\">\n <img [src]=\"content?.value\"/>\n </div>\n <div class=\"description\" *ngIf=\"content?.description\">{{content?.description}}</div>\n <div class=\"source\" *ngIf=\"content?.source\">\n <a [href]=\"content?.source\" [target]=\"'_blank'\">Source: {{content?.source}}</a>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.HTML\">\n <app-static-html\n [value]=\"content?.value\"\n >\n </app-static-html>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <p>{{content?.value}}</p>\n </ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <a href=\"javascript:void(0);\" (click)=\"routeTo(entry)\">Read more...</a>\n</div>\n", styles: [".entry{padding:20px;border-bottom:solid 1px rgba(0,0,0,.12)}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: StaticHtmlComponent, selector: "app-static-html", inputs: ["value"] }, { kind: "pipe", type: TimeAgoPipe, name: "timeAgo" }] });
1293
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntrySummaryComponent, decorators: [{
1294
- type: Component,
1295
- args: [{ selector: 'app-entry-summary', template: "\n<div class=\"entry section restrict\">\n <h2>{{entry?.title}}</h2>\n <!-- <a href=\"javascript:void(0)\" (click)=\"edit(entry)\"><h6>[Edit]</h6></a>-->\n <h3>Posted {{entry?.create_date.toString() | timeAgo}} on {{entry?.create_date?.getMonth() + 1}}/{{entry?.create_date?.getDate()}}/{{entry?.create_date?.getFullYear()}}</h3>\n <h5 *ngIf=\"entry.showEditInformation()\">Article was last edited {{entry?.edit_date.toString() | timeAgo}}</h5>\n <br>\n\n <ng-container *ngFor=\"let section of entry?.sections.slice(0, 1)\">\n <h4>{{section?.subheading}}</h4>\n <ng-container *ngFor=\"let content of section?.contents.slice(0, 1)\">\n <ng-container [ngSwitch]=\"content.type\">\n <ng-container *ngSwitchCase=\"ContentType.CODE\">\n <pre><code class=\"language-ts\">{{content?.value}}</code></pre>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.URL\">\n <a [href]=\"content?.value\" target=\"_blank\">{{content.title}}</a>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.IMAGE\">\n <div class=\"restrict\">\n <div class=\"image\">\n <img [src]=\"content?.value\"/>\n </div>\n <div class=\"description\" *ngIf=\"content?.description\">{{content?.description}}</div>\n <div class=\"source\" *ngIf=\"content?.source\">\n <a [href]=\"content?.source\" [target]=\"'_blank'\">Source: {{content?.source}}</a>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.MEDIA\">\n <div class=\"restrict\">\n <div class=\"image\">\n <img [src]=\"content?.value\"/>\n </div>\n <div class=\"description\" *ngIf=\"content?.description\">{{content?.description}}</div>\n <div class=\"source\" *ngIf=\"content?.source\">\n <a [href]=\"content?.source\" [target]=\"'_blank'\">Source: {{content?.source}}</a>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"ContentType.HTML\">\n <app-static-html\n [value]=\"content?.value\"\n >\n </app-static-html>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <p>{{content?.value}}</p>\n </ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <a href=\"javascript:void(0);\" (click)=\"routeTo(entry)\">Read more...</a>\n</div>\n", styles: [".entry{padding:20px;border-bottom:solid 1px rgba(0,0,0,.12)}\n"] }]
1296
- }], ctorParameters: function () { return [{ type: i1$4.Router }]; }, propDecorators: { entry: [{
1297
- type: Input
1298
- }] } });
1299
-
1300
- class JsonRendererComponent {
1301
- constructor(entryService) {
1302
- this.entryService = entryService;
1303
- this.JSON = JSON;
1304
- }
1305
- ngOnInit() {
1306
- this.entryService.currentlyEditedEntry.subscribe((entry) => {
1307
- console.log(entry);
1308
- this.entry = entry;
1309
- });
1310
- }
1311
- }
1312
- JsonRendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: JsonRendererComponent, deps: [{ token: EntryService }], target: i0.ɵɵFactoryTarget.Component });
1313
- JsonRendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: JsonRendererComponent, selector: "app-json-renderer", inputs: { entry: "entry" }, ngImport: i0, template: "<div class=\"section json-render json\">\n <app-entry-renderer [editMode]=\"true\" [entry]=\"entry\"></app-entry-renderer>\n <pre *ngIf=\"entry\">{{JSON.stringify(entry)}}</pre>\n</div>\n", styles: [".json pre{white-space:pre-wrap;word-wrap:anywhere}.json-render{padding:0 20px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: EntryRendererComponent, selector: "app-entry-renderer", inputs: ["entry", "editMode"] }] });
1314
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: JsonRendererComponent, decorators: [{
1315
- type: Component,
1316
- args: [{ selector: 'app-json-renderer', template: "<div class=\"section json-render json\">\n <app-entry-renderer [editMode]=\"true\" [entry]=\"entry\"></app-entry-renderer>\n <pre *ngIf=\"entry\">{{JSON.stringify(entry)}}</pre>\n</div>\n", styles: [".json pre{white-space:pre-wrap;word-wrap:anywhere}.json-render{padding:0 20px}\n"] }]
1317
- }], ctorParameters: function () { return [{ type: EntryService }]; }, propDecorators: { entry: [{
1318
- type: Input
1319
- }] } });
1320
-
1321
- class LandingPageComponent {
1322
- constructor(router, entryService) {
1323
- this.router = router;
1324
- this.entryService = entryService;
1325
- this.JSON = JSON;
1326
- }
1327
- ngOnInit() {
1328
- this.entryService.get().subscribe((response) => {
1329
- this.entries = map$1(response.results.slice(0, 3), (result) => {
1330
- return { id: result.id, entry: new Entry(result) };
1331
- });
1332
- });
1333
- }
1334
- ngOnDestroy() {
1335
- if (this.sourceSub) {
1336
- this.sourceSub.unsubscribe();
1337
- this.sourceSub = null;
1338
- }
1339
- }
1340
- }
1341
- LandingPageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: LandingPageComponent, deps: [{ token: i1$4.Router }, { token: EntryService }], target: i0.ɵɵFactoryTarget.Component });
1342
- LandingPageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: LandingPageComponent, selector: "app-landing-page", ngImport: i0, template: "<div class=\"landing-page\">\n <ng-container *ngFor=\"let entry of entries\">\n <app-entry-summary [entry]=\"entry.entry\"></app-entry-summary>\n </ng-container>\n</div>\n", styles: [".landing-page{min-height:calc(100vh - 100px);max-height:calc(100vh - 100px)}@media screen and (max-height: 560px){.landing-page{max-height:100vh}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: EntrySummaryComponent, selector: "app-entry-summary", inputs: ["entry"] }] });
1343
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: LandingPageComponent, decorators: [{
1344
- type: Component,
1345
- args: [{ selector: 'app-landing-page', template: "<div class=\"landing-page\">\n <ng-container *ngFor=\"let entry of entries\">\n <app-entry-summary [entry]=\"entry.entry\"></app-entry-summary>\n </ng-container>\n</div>\n", styles: [".landing-page{min-height:calc(100vh - 100px);max-height:calc(100vh - 100px)}@media screen and (max-height: 560px){.landing-page{max-height:100vh}}\n"] }]
1346
- }], ctorParameters: function () { return [{ type: i1$4.Router }, { type: EntryService }]; } });
1347
-
1348
- class OutlineViewComponent {
1349
- constructor(entryService) {
1350
- this.entryService = entryService;
1351
- this.Math = Math;
1352
- }
1353
- ngOnInit() {
1354
- this.entryService.currentlyEditedEntry.subscribe((entry) => {
1355
- this.entry = entry;
1356
- });
1357
- }
1358
- sectionDrop(e) {
1359
- const entry = this.entry;
1360
- const diff = e.currentIndex - e.previousIndex;
1361
- entry.sections[e.previousIndex].order = e.currentIndex * 10 + (diff > 0 ? 1 : -1);
1362
- entry.sort();
1363
- this.entryService.currentlyEditedEntry.next(this.entry);
1364
- }
1365
- contentDrop(e, section) {
1366
- const entry = this.entry;
1367
- const diff = e.currentIndex - e.previousIndex;
1368
- section.contents[e.previousIndex].order = e.currentIndex * 10 + (diff > 0 ? 1 : -1);
1369
- entry.sort();
1370
- this.entryService.currentlyEditedEntry.next(this.entry);
1371
- }
1372
- }
1373
- OutlineViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: OutlineViewComponent, deps: [{ token: EntryService }], target: i0.ɵɵFactoryTarget.Component });
1374
- OutlineViewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: OutlineViewComponent, selector: "app-outline-view", ngImport: i0, template: "<div *ngIf=\"entry\" class=\"section outline\">\n <h1 *ngIf=\"entry?.sections?.length === 0\">Outline View</h1>\n <div cdkDropList class=\"sections\" (cdkDropListDropped)=\"sectionDrop($event)\">\n <mat-card class=\"card\" cdkDrag *ngFor=\"let section of entry.sections\">\n <h3>Section {{Math.ceil(section.order / 10) + 1}}</h3>\n {{section.subheading}}\n <div cdkDropList class=\"contents\" (cdkDropListDropped)=\"contentDrop($event, section)\">\n <h3>Contents for {{section.subheading}}</h3>\n <div class=\"content-card\" *ngFor=\"let content of section.contents\" cdkDrag>\n <div class=\"content\">{{content.value}}</div>\n <div class=\"content-placeholder\" *cdkDragPlaceholder></div>\n </div>\n </div>\n </mat-card>\n <div class=\"custom-placeholder\" *cdkDragPlaceholder></div>\n </div>\n</div>\n", styles: [".outline{padding:0 20px}.content{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.card,.content-card{margin:4px;cursor:pointer}.content-card:not(:last-child){border-bottom:1px dotted #aaa}.custom-placeholder{background:#ccc;border:dotted 3px #999;transition:transform .25s cubic-bezier(0,0,.2,1);min-height:60px}.content-placeholder{background:#ccc;border:dotted 3px #999;transition:transform .25s cubic-bezier(0,0,.2,1);min-height:30px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }] });
1375
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: OutlineViewComponent, decorators: [{
1376
- type: Component,
1377
- args: [{ selector: 'app-outline-view', template: "<div *ngIf=\"entry\" class=\"section outline\">\n <h1 *ngIf=\"entry?.sections?.length === 0\">Outline View</h1>\n <div cdkDropList class=\"sections\" (cdkDropListDropped)=\"sectionDrop($event)\">\n <mat-card class=\"card\" cdkDrag *ngFor=\"let section of entry.sections\">\n <h3>Section {{Math.ceil(section.order / 10) + 1}}</h3>\n {{section.subheading}}\n <div cdkDropList class=\"contents\" (cdkDropListDropped)=\"contentDrop($event, section)\">\n <h3>Contents for {{section.subheading}}</h3>\n <div class=\"content-card\" *ngFor=\"let content of section.contents\" cdkDrag>\n <div class=\"content\">{{content.value}}</div>\n <div class=\"content-placeholder\" *cdkDragPlaceholder></div>\n </div>\n </div>\n </mat-card>\n <div class=\"custom-placeholder\" *cdkDragPlaceholder></div>\n </div>\n</div>\n", styles: [".outline{padding:0 20px}.content{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.card,.content-card{margin:4px;cursor:pointer}.content-card:not(:last-child){border-bottom:1px dotted #aaa}.custom-placeholder{background:#ccc;border:dotted 3px #999;transition:transform .25s cubic-bezier(0,0,.2,1);min-height:60px}.content-placeholder{background:#ccc;border:dotted 3px #999;transition:transform .25s cubic-bezier(0,0,.2,1);min-height:30px}\n"] }]
1378
- }], ctorParameters: function () { return [{ type: EntryService }]; } });
1379
-
1380
- class SideNavigationComponent {
1381
- constructor(entryService, router, identityService, renderer) {
1382
- this.entryService = entryService;
1383
- this.router = router;
1384
- this.identityService = identityService;
1385
- this.renderer = renderer;
1386
- this.state = 'out';
1387
- this.entries = [];
1388
- this.entriesByMonthAndYear = [];
1389
- this.searchTerm = "";
1390
- this.doSearch = new EventEmitter();
1391
- this.searchControl = new FormControl('');
1392
- }
1393
- ngOnInit() {
1394
- this.doSearch.pipe(debounceTime(500)).subscribe((result) => {
1395
- this.searchEntries(result);
1396
- });
1397
- this.identityService.getMe().subscribe((identity) => {
1398
- this.identity = identity;
1399
- }, (err) => {
1400
- this.identity = null;
1401
- });
1402
- this.getEntries();
1403
- }
1404
- getEntriesWithUrl(url) {
1405
- this.entryService.getListByUrl(url).subscribe((response) => {
1406
- this.entries = this.entries.concat(map$1(response.results, (result) => {
1407
- return { id: result.id, entry: new Entry(result) };
1408
- }));
1409
- if (response.next) {
1410
- this.getEntriesWithUrl(response.next);
1411
- }
1412
- else {
1413
- this.organizeEntries();
1414
- }
1415
- });
1416
- }
1417
- organizeEntries() {
1418
- this.state = 'out';
1419
- let organizeEntriesFn = () => {
1420
- this.entriesByMonthAndYear = [];
1421
- let newEntries = JSON.parse(JSON.stringify(this.entriesByMonthAndYear));
1422
- for (const entryWrapper of this.entries) {
1423
- const entry = entryWrapper.entry;
1424
- const create_date = new Date(entry.create_date);
1425
- const month = create_date.getMonth();
1426
- const year = create_date.getFullYear();
1427
- const key = month + '/' + year;
1428
- const sort_index = (year * 100) + month;
1429
- const containers = filter(newEntries, (entryContainer) => entryContainer.month_year === key);
1430
- if (containers.length > 0) {
1431
- const container = containers[0];
1432
- const entriesWithId = filter(container.entries, (e) => e.id === entryWrapper.entry.id);
1433
- if (entriesWithId.length === 0) {
1434
- container.entries.push(entry);
1435
- }
1436
- }
1437
- else {
1438
- const newContainer = { month_year: key, month_year_number: sort_index, entries: [entry] };
1439
- newEntries.push(newContainer);
1440
- }
1441
- }
1442
- newEntries.sort((entry_a, entry_b) => {
1443
- return entry_a.month_year_number - entry_b.month_year_number;
1444
- });
1445
- newEntries.reverse();
1446
- let setEntriesFn = () => {
1447
- this.entriesByMonthAndYear = newEntries;
1448
- this.state = 'in';
1449
- };
1450
- setTimeout(setEntriesFn.bind(this), 400);
1451
- };
1452
- setTimeout(organizeEntriesFn.bind(this), 400);
1453
- }
1454
- getEntries() {
1455
- this.entryService.get().subscribe((response) => {
1456
- this.entries = map$1(response.results, (result) => {
1457
- return { id: result.id, entry: new Entry(result) };
1458
- });
1459
- if (response.next) {
1460
- this.getEntriesWithUrl(response.next);
1461
- }
1462
- else {
1463
- this.organizeEntries();
1464
- }
1465
- });
1466
- }
1467
- searchEntries(searchTerm) {
1468
- if (searchTerm !== "") {
1469
- this.entryService.search(searchTerm).subscribe((response) => {
1470
- this.entries = map$1(response.results, (result) => {
1471
- return { id: result.id, entry: new Entry(result) };
1472
- });
1473
- if (response.next) {
1474
- this.getEntriesWithUrl(response.next);
1475
- }
1476
- else {
1477
- this.organizeEntries();
1478
- }
1479
- });
1480
- }
1481
- else {
1482
- this.getEntries();
1483
- }
1484
- }
1485
- render() {
1486
- }
1487
- routeTo(entry) {
1488
- if (!entry) {
1489
- this.router.navigateByUrl('create(left-col:create//right-col:create)').then(() => {
1490
- });
1491
- }
1492
- else {
1493
- this.router.navigate(['/', 'blog', entry.slug]).then(() => {
1494
- // Noop
1495
- });
1496
- }
1497
- }
1498
- getMonthAndYearFromKey(key) {
1499
- let subheading = '';
1500
- const parts = key.split('/');
1501
- switch (Number(parts[0])) {
1502
- case 0:
1503
- subheading += 'January ';
1504
- break;
1505
- case 1:
1506
- subheading += 'February ';
1507
- break;
1508
- case 2:
1509
- subheading += 'March ';
1510
- break;
1511
- case 3:
1512
- subheading += 'April ';
1513
- break;
1514
- case 4:
1515
- subheading += 'May ';
1516
- break;
1517
- case 5:
1518
- subheading += 'June ';
1519
- break;
1520
- case 6:
1521
- subheading += 'July ';
1522
- break;
1523
- case 7:
1524
- subheading += 'August ';
1525
- break;
1526
- case 8:
1527
- subheading += 'September ';
1528
- break;
1529
- case 9:
1530
- subheading += 'October ';
1531
- break;
1532
- case 10:
1533
- subheading += 'November ';
1534
- break;
1535
- case 11:
1536
- subheading += 'December ';
1537
- break;
1538
- default:
1539
- subheading += 'January ';
1540
- }
1541
- subheading += parts[1];
1542
- return subheading;
1543
- }
1544
- ngOnDestroy() {
1545
- if (this.sourceSub) {
1546
- this.sourceSub.unsubscribe();
1547
- this.sourceSub = null;
1548
- }
1549
- }
1550
- onSearchChange(searchValue) {
1551
- this.doSearch.emit(searchValue);
1552
- }
1553
- }
1554
- SideNavigationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: SideNavigationComponent, deps: [{ token: EntryService }, { token: i1$4.Router }, { token: IdentityService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
1555
- SideNavigationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: SideNavigationComponent, selector: "app-side-navigation", viewQueries: [{ propertyName: "divNav", first: true, predicate: ["navcontainer"], descendants: true }], ngImport: i0, template: "<div class=\"sidenav no-scrollbar\">\n <div style=\"margin-top: 20px;\">\n <mat-form-field style=\"width: 100%\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"searchControl\" (ngModelChange)=\"onSearchChange($event)\">\n </mat-form-field>\n </div>\n\n <div #navcontainer class=\"navcontainer\"\n [@sideNavAnimation]=\"state\"\n >\n <mat-nav-list\n *ngFor=\"let container of entriesByMonthAndYear\"\n >\n <h3>{{getMonthAndYearFromKey(container.month_year)}}</h3>\n <a mat-list-item *ngFor=\"let entry of container.entries\" href=\"javascript:void(0)\" (click)=\"routeTo(entry)\">{{entry.title}}</a>\n </mat-nav-list>\n\n </div>\n\n <ng-container *ngIf=\"identity?.id === 1\">\n <h2>Misc</h2>\n\n <mat-nav-list>\n <a mat-list-item href=\"javascript:void(0);\" (click)=\"routeTo(null)\">Create</a>\n </mat-nav-list>\n </ng-container>\n <h3 *ngIf=\"identity\">Logged in as {{identity?.email}}</h3>\n</div>\n\n", styles: [".sidenav{max-height:calc(100vh - 100px)}@media screen and (max-height: 560px){.sidenav{max-height:100vh}}h2,h3{margin-left:10px;justify-content:right}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "component", type: i8$1.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i8$1.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }], animations: [
1556
- trigger('sideNavAnimation', [
1557
- state('in', style({ transform: 'translateX(0%)' })),
1558
- state('out', style({ transform: 'translateX(110%)' })),
1559
- transition('in => out', [
1560
- animate('100ms ease-out', style({ transform: 'translateX(110%)' }))
1561
- ]),
1562
- transition('out => in', [
1563
- animate('100ms ease-in', style({ transform: 'translateX(0%)' }))
1564
- ])
1565
- ]),
1566
- ] });
1567
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: SideNavigationComponent, decorators: [{
1568
- type: Component,
1569
- args: [{ selector: 'app-side-navigation', animations: [
1570
- trigger('sideNavAnimation', [
1571
- state('in', style({ transform: 'translateX(0%)' })),
1572
- state('out', style({ transform: 'translateX(110%)' })),
1573
- transition('in => out', [
1574
- animate('100ms ease-out', style({ transform: 'translateX(110%)' }))
1575
- ]),
1576
- transition('out => in', [
1577
- animate('100ms ease-in', style({ transform: 'translateX(0%)' }))
1578
- ])
1579
- ]),
1580
- ], template: "<div class=\"sidenav no-scrollbar\">\n <div style=\"margin-top: 20px;\">\n <mat-form-field style=\"width: 100%\">\n <mat-label>Search</mat-label>\n <input matInput [formControl]=\"searchControl\" (ngModelChange)=\"onSearchChange($event)\">\n </mat-form-field>\n </div>\n\n <div #navcontainer class=\"navcontainer\"\n [@sideNavAnimation]=\"state\"\n >\n <mat-nav-list\n *ngFor=\"let container of entriesByMonthAndYear\"\n >\n <h3>{{getMonthAndYearFromKey(container.month_year)}}</h3>\n <a mat-list-item *ngFor=\"let entry of container.entries\" href=\"javascript:void(0)\" (click)=\"routeTo(entry)\">{{entry.title}}</a>\n </mat-nav-list>\n\n </div>\n\n <ng-container *ngIf=\"identity?.id === 1\">\n <h2>Misc</h2>\n\n <mat-nav-list>\n <a mat-list-item href=\"javascript:void(0);\" (click)=\"routeTo(null)\">Create</a>\n </mat-nav-list>\n </ng-container>\n <h3 *ngIf=\"identity\">Logged in as {{identity?.email}}</h3>\n</div>\n\n", styles: [".sidenav{max-height:calc(100vh - 100px)}@media screen and (max-height: 560px){.sidenav{max-height:100vh}}h2,h3{margin-left:10px;justify-content:right}\n"] }]
1581
- }], ctorParameters: function () { return [{ type: EntryService }, { type: i1$4.Router }, { type: IdentityService }, { type: i0.Renderer2 }]; }, propDecorators: { divNav: [{
1582
- type: ViewChild,
1583
- args: ['navcontainer', { static: false }]
1584
- }] } });
1585
-
1586
- class MainComponent {
1587
- constructor(router) {
1588
- this.router = router;
1589
- this.loaded = true;
1590
- this.subs = new Subscription();
1591
- this.resizeSubject = new Subject();
1592
- }
1593
- ngOnInit() {
1594
- this.subs.add(this.router.events.subscribe((e) => {
1595
- if (e instanceof NavigationEnd) {
1596
- if (e.urlAfterRedirects.includes('create')) {
1597
- this.showLeftCol = true;
1598
- this.showRightCol = true;
1599
- }
1600
- else {
1601
- this.showLeftCol = true;
1602
- this.showRightCol = false;
1603
- this.innerWidth = window.innerWidth;
1604
- this.collapseLeftColIfTooNarrow();
1605
- }
1606
- }
1607
- }));
1608
- this.subs.add(this.resizeSubject.pipe(debounceTime(100)).subscribe((width) => {
1609
- this.innerWidth = width;
1610
- this.collapseLeftColIfTooNarrow();
1611
- }));
1612
- }
1613
- collapseLeftColIfTooNarrow() {
1614
- this.showLeftCol = this.innerWidth >= 800;
1615
- }
1616
- onResize(event) {
1617
- this.resizeSubject.next(window.innerWidth);
1618
- }
1619
- ngOnDestroy() {
1620
- this.subs.unsubscribe();
1621
- }
1622
- }
1623
- MainComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: MainComponent, deps: [{ token: i1$4.Router }], target: i0.ɵɵFactoryTarget.Component });
1624
- MainComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: MainComponent, selector: "lib-main", host: { listeners: { "window:resize": "onResize($event)" } }, ngImport: i0, template: "<ng-container *ngIf=\"loaded\">\n <div class=\"container\">\n <div class=\"body\">\n <div class=\"container-row\">\n <mat-sidenav-container [autosize]=\"true\">\n <mat-sidenav [(opened)]=\"showLeftCol\" #leftcol opened mode=\"side\" class=\"left no-scrollbar\">\n <router-outlet name=\"left-col\"></router-outlet>\n <button mat-mini-fab color=\"primary\" class=\"fade left-toggle\" *ngIf=\"showLeftCol\" (click)=\"leftcol.toggle()\"> << </button>\n </mat-sidenav>\n <mat-sidenav [(opened)]=\"showRightCol\" #rightcol mode=\"side\" position=\"end\" class=\"right\">\n <button mat-mini-fab color=\"primary\" class=\"fade right-toggle\" *ngIf=\"showRightCol\" (click)=\"rightcol.toggle()\"> >> </button>\n <router-outlet name=\"right-col\"></router-outlet>\n </mat-sidenav>\n <div class=\"middle\">\n <button mat-mini-fab color=\"primary\" class=\"fade left-toggle\" *ngIf=\"!showLeftCol\" (click)=\"leftcol.toggle()\"> >> </button>\n <button mat-mini-fab color=\"primary\" class=\"fade right-toggle\" *ngIf=\"!showRightCol\" (click)=\"rightcol.toggle()\"> << </button>\n <router-outlet></router-outlet>\n </div>\n </mat-sidenav-container>\n </div>\n </div>\n </div>\n</ng-container>\n", styles: ["a{text-decoration:none}.body{flex-grow:1;max-height:calc(100vh - 100px);overflow:scroll}@media screen and (max-height: 560px){.body{max-height:100vh}}.left,.right{min-width:400px;max-width:33vw}.left-toggle{position:fixed;top:50%;left:5px;z-index:100}.right-toggle{position:fixed;top:50%;right:5px;z-index:100}a{margin-right:10px}a:not(:last-child):after{margin-left:10px;content:\"|\"}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$4.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: i3$1.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i3$1.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i4.MatMiniFabButton, selector: "button[mat-mini-fab]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }] });
1625
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: MainComponent, decorators: [{
1626
- type: Component,
1627
- args: [{ selector: 'lib-main', template: "<ng-container *ngIf=\"loaded\">\n <div class=\"container\">\n <div class=\"body\">\n <div class=\"container-row\">\n <mat-sidenav-container [autosize]=\"true\">\n <mat-sidenav [(opened)]=\"showLeftCol\" #leftcol opened mode=\"side\" class=\"left no-scrollbar\">\n <router-outlet name=\"left-col\"></router-outlet>\n <button mat-mini-fab color=\"primary\" class=\"fade left-toggle\" *ngIf=\"showLeftCol\" (click)=\"leftcol.toggle()\"> << </button>\n </mat-sidenav>\n <mat-sidenav [(opened)]=\"showRightCol\" #rightcol mode=\"side\" position=\"end\" class=\"right\">\n <button mat-mini-fab color=\"primary\" class=\"fade right-toggle\" *ngIf=\"showRightCol\" (click)=\"rightcol.toggle()\"> >> </button>\n <router-outlet name=\"right-col\"></router-outlet>\n </mat-sidenav>\n <div class=\"middle\">\n <button mat-mini-fab color=\"primary\" class=\"fade left-toggle\" *ngIf=\"!showLeftCol\" (click)=\"leftcol.toggle()\"> >> </button>\n <button mat-mini-fab color=\"primary\" class=\"fade right-toggle\" *ngIf=\"!showRightCol\" (click)=\"rightcol.toggle()\"> << </button>\n <router-outlet></router-outlet>\n </div>\n </mat-sidenav-container>\n </div>\n </div>\n </div>\n</ng-container>\n", styles: ["a{text-decoration:none}.body{flex-grow:1;max-height:calc(100vh - 100px);overflow:scroll}@media screen and (max-height: 560px){.body{max-height:100vh}}.left,.right{min-width:400px;max-width:33vw}.left-toggle{position:fixed;top:50%;left:5px;z-index:100}.right-toggle{position:fixed;top:50%;right:5px;z-index:100}a{margin-right:10px}a:not(:last-child):after{margin-left:10px;content:\"|\"}\n"] }]
1628
- }], ctorParameters: function () { return [{ type: i1$4.Router }]; }, propDecorators: { onResize: [{
1629
- type: HostListener,
1630
- args: ['window:resize', ['$event']]
1631
- }] } });
1632
-
1633
- class EntryRendererWrapperComponent {
1634
- seeAll(toggle) {
1635
- this.seeAllEntries = toggle;
1636
- }
1637
- constructor(entryService, router, route, viewService, interactionService) {
1638
- this.entryService = entryService;
1639
- this.router = router;
1640
- this.route = route;
1641
- this.viewService = viewService;
1642
- this.interactionService = interactionService;
1643
- this.seeAllEntries = false;
1644
- }
1645
- getEntry() {
1646
- const slug = this.route.snapshot.paramMap.get('slug');
1647
- if (slug) {
1648
- this.entryService.getBySlug(slug).subscribe((response) => {
1649
- this.currentEntry = response;
1650
- const view = new View();
1651
- view.entry = this.currentEntry.id;
1652
- this.viewService.create(view).subscribe((viewResponse) => {
1653
- // Noop
1654
- });
1655
- });
1656
- }
1657
- this.route.queryParams.subscribe(params => {
1658
- const campaign = params['campaign'];
1659
- if (campaign && campaign !== '') {
1660
- const interaction = new Interaction();
1661
- interaction.content = { 'campaign': campaign, slug };
1662
- this.interactionService.create(interaction).subscribe((response) => {
1663
- });
1664
- setTimeout(() => {
1665
- const urlMinsCampaign = this.router.url.replace(new RegExp('.campaign=' + campaign), '');
1666
- this.router.navigateByUrl(urlMinsCampaign);
1667
- }, 0);
1668
- }
1669
- });
1670
- }
1671
- ngOnInit() {
1672
- this.routerSub = this.router.events.subscribe((e) => {
1673
- if (e instanceof NavigationEnd) {
1674
- this.currentEntry = null;
1675
- this.seeAll(false);
1676
- setTimeout(() => {
1677
- this.getEntry();
1678
- }, 10);
1679
- }
1680
- });
1681
- this.getEntry();
1682
- }
1683
- ngOnDestroy() {
1684
- if (this.routerSub) {
1685
- this.routerSub.complete();
1686
- this.routerSub = null;
1687
- }
1688
- }
1689
- }
1690
- EntryRendererWrapperComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntryRendererWrapperComponent, deps: [{ token: EntryService }, { token: i1$4.Router }, { token: i1$4.ActivatedRoute }, { token: ViewService }, { token: InteractionService }], target: i0.ɵɵFactoryTarget.Component });
1691
- EntryRendererWrapperComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: EntryRendererWrapperComponent, selector: "lib-entry-renderer-wrapper", ngImport: i0, template: "<div class=\"rendered-entry section\">\n <app-entry-renderer *ngIf=\"currentEntry\" [entry]=\"currentEntry\"></app-entry-renderer>\n</div>\n", styles: [".rendered-entry{padding:0 20px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: EntryRendererComponent, selector: "app-entry-renderer", inputs: ["entry", "editMode"] }] });
1692
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: EntryRendererWrapperComponent, decorators: [{
1693
- type: Component,
1694
- args: [{ selector: 'lib-entry-renderer-wrapper', template: "<div class=\"rendered-entry section\">\n <app-entry-renderer *ngIf=\"currentEntry\" [entry]=\"currentEntry\"></app-entry-renderer>\n</div>\n", styles: [".rendered-entry{padding:0 20px}\n"] }]
1695
- }], ctorParameters: function () { return [{ type: EntryService }, { type: i1$4.Router }, { type: i1$4.ActivatedRoute }, { type: ViewService }, { type: InteractionService }]; } });
1696
-
1697
- class LinkyPipe {
1698
- transform(value, options) {
1699
- return Autolinker.link(value, Object.assign({}, options, { newWindow: true, stripPrefix: false }));
1700
- }
1701
- }
1702
- LinkyPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: LinkyPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1703
- LinkyPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.1.4", ngImport: i0, type: LinkyPipe, name: "linky" });
1704
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: LinkyPipe, decorators: [{
1705
- type: Pipe,
1706
- args: [{ name: 'linky' }]
1707
- }] });
1708
-
1709
- const routes = [
1710
- { path: '', component: SideNavigationComponent, outlet: 'left-col' },
1711
- {
1712
- path: 'landing',
1713
- component: MainComponent
1714
- },
1715
- { path: 'blog/:slug', component: EntryRendererWrapperComponent },
1716
- { path: 'create', component: EntryCreatorComponent },
1717
- { path: 'create', component: OutlineViewComponent, outlet: 'left-col' },
1718
- { path: 'create', component: JsonRendererComponent, outlet: 'right-col' },
1719
- { path: '', redirectTo: '/landing', pathMatch: 'full' },
1720
- { path: '**', redirectTo: '/404error' }
1721
- ];
1722
- class Routes {
1723
- constructor() {
1724
- this.routes = routes;
1725
- }
1726
- }
1727
-
1728
- class SchedulePublishDialogData {
1729
- }
1730
-
1731
- class SchedulePublishDialogComponent {
1732
- constructor(dialogRef, data) {
1733
- this.dialogRef = dialogRef;
1734
- this.data = data;
1735
- }
1736
- ngOnInit() {
1737
- }
1738
- onNoClick() {
1739
- }
1740
- onYesClick() {
1741
- this.dialogRef.close('test');
1742
- }
1743
- }
1744
- SchedulePublishDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: SchedulePublishDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
1745
- SchedulePublishDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.4", type: SchedulePublishDialogComponent, selector: "lib-schedule-publish-dialog", ngImport: i0, template: "<h1 mat-dialog-title>Select a Date and Time to Schedule This Post</h1>\n<!--<mat-radio-group aria-label=\"Select an option\">-->\n<!-- <mat-radio-button class=\"option\" value=\"unpublished\">Unpublished</mat-radio-button>-->\n<!-- <mat-radio-button class=\"option\" value=\"published\">Published</mat-radio-button>-->\n<!--</mat-radio-group>-->\n<p>Date</p>\n<mat-form-field appearance=\"fill\">\n <mat-label>Choose a date</mat-label>\n <input matInput [matDatepicker]=\"picker\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n</mat-form-field>\n<p>Time</p>\n<input [ngxTimepicker]=\"timepicker\" readonly>\n<ngx-material-timepicker #timepicker></ngx-material-timepicker>\n<div mat-dialog-actions>\n <button mat-button (click)=\"onNoClick()\">Cancel</button>\n <button mat-button (click)=\"onYesClick()\" cdkFocusInitial>Schedule Publish</button>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i17.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i17.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i17.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i6$2.NgxMaterialTimepickerComponent, selector: "ngx-material-timepicker", inputs: ["ESC", "hoursOnly", "ngxMaterialTimepickerTheme", "format", "minutesGap", "cancelBtnTmpl", "editableHintTmpl", "confirmBtnTmpl", "enableKeyboardInput", "preventOverlayClick", "disableAnimation", "appendToInput", "defaultTime", "timepickerClass", "theme", "min", "max"], outputs: ["timeSet", "opened", "closed", "hourSelected", "timeChanged"] }, { kind: "directive", type: i6$2.TimepickerDirective, selector: "[ngxTimepicker]", inputs: ["format", "value", "min", "max", "ngxTimepicker", "disabled", "disableClick"] }] });
1746
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: SchedulePublishDialogComponent, decorators: [{
1747
- type: Component,
1748
- args: [{ selector: 'lib-schedule-publish-dialog', template: "<h1 mat-dialog-title>Select a Date and Time to Schedule This Post</h1>\n<!--<mat-radio-group aria-label=\"Select an option\">-->\n<!-- <mat-radio-button class=\"option\" value=\"unpublished\">Unpublished</mat-radio-button>-->\n<!-- <mat-radio-button class=\"option\" value=\"published\">Published</mat-radio-button>-->\n<!--</mat-radio-group>-->\n<p>Date</p>\n<mat-form-field appearance=\"fill\">\n <mat-label>Choose a date</mat-label>\n <input matInput [matDatepicker]=\"picker\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n</mat-form-field>\n<p>Time</p>\n<input [ngxTimepicker]=\"timepicker\" readonly>\n<ngx-material-timepicker #timepicker></ngx-material-timepicker>\n<div mat-dialog-actions>\n <button mat-button (click)=\"onNoClick()\">Cancel</button>\n <button mat-button (click)=\"onYesClick()\" cdkFocusInitial>Schedule Publish</button>\n</div>\n" }]
1749
- }], ctorParameters: function () { return [{ type: i1$2.MatDialogRef }, { type: SchedulePublishDialogData, decorators: [{
1750
- type: Inject,
1751
- args: [MAT_DIALOG_DATA]
1752
- }] }]; } });
1753
-
1754
- class CoreModule {
1755
- constructor(library) {
1756
- this.library = library;
1757
- this.library.addIcons(faSpinner);
1758
- }
1759
- }
1760
- CoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: CoreModule, deps: [{ token: i1$3.FaIconLibrary }], target: i0.ɵɵFactoryTarget.NgModule });
1761
- CoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.4", ngImport: i0, type: CoreModule, declarations: [EntryRendererComponent,
1762
- EntryCreatorComponent,
1763
- LandingPageComponent,
1764
- SideNavigationComponent,
1765
- OutlineViewComponent,
1766
- JsonRendererComponent,
1767
- EntrySummaryComponent,
1768
- EntrySelectorDialogComponent,
1769
- MediaUploadModalComponent,
1770
- TimeAgoPipe,
1771
- LinkyPipe,
1772
- StaticHtmlComponent,
1773
- MainComponent,
1774
- EntryRendererWrapperComponent,
1775
- SchedulePublishDialogComponent], imports: [CommonModule,
1776
- RouterModule,
1777
- FormsModule,
1778
- ReactiveFormsModule,
1779
- DragDropModule,
1780
- MatCardModule,
1781
- MatSidenavModule,
1782
- MatButtonModule,
1783
- MatInputModule,
1784
- MatListModule,
1785
- MatRadioModule,
1786
- MatDialogModule,
1787
- MatCheckboxModule,
1788
- MatDividerModule,
1789
- MatAutocompleteModule,
1790
- MatChipsModule,
1791
- MatIconModule,
1792
- MatDatepickerModule,
1793
- MatNativeDateModule,
1794
- MatTableModule,
1795
- FontAwesomeModule,
1796
- FileUploadModule,
1797
- NgxMaterialTimepickerModule], exports: [EntryRendererComponent,
1798
- EntryCreatorComponent,
1799
- LandingPageComponent,
1800
- SideNavigationComponent,
1801
- OutlineViewComponent,
1802
- JsonRendererComponent,
1803
- EntrySummaryComponent,
1804
- EntrySelectorDialogComponent,
1805
- MediaUploadModalComponent,
1806
- TimeAgoPipe,
1807
- LinkyPipe,
1808
- StaticHtmlComponent,
1809
- MainComponent,
1810
- EntryRendererWrapperComponent] });
1811
- CoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: CoreModule, providers: [
1812
- CommentService,
1813
- EntryService,
1814
- UploadService,
1815
- PrismService,
1816
- IdentityService,
1817
- DjangoRestFrameworkEndpointService,
1818
- TagService,
1819
- ], imports: [CommonModule,
1820
- RouterModule,
1821
- FormsModule,
1822
- ReactiveFormsModule,
1823
- DragDropModule,
1824
- MatCardModule,
1825
- MatSidenavModule,
1826
- MatButtonModule,
1827
- MatInputModule,
1828
- MatListModule,
1829
- MatRadioModule,
1830
- MatDialogModule,
1831
- MatCheckboxModule,
1832
- MatDividerModule,
1833
- MatAutocompleteModule,
1834
- MatChipsModule,
1835
- MatIconModule,
1836
- MatDatepickerModule,
1837
- MatNativeDateModule,
1838
- MatTableModule,
1839
- FontAwesomeModule,
1840
- FileUploadModule,
1841
- NgxMaterialTimepickerModule] });
1842
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: CoreModule, decorators: [{
1843
- type: NgModule,
1844
- args: [{
1845
- declarations: [
1846
- EntryRendererComponent,
1847
- EntryCreatorComponent,
1848
- LandingPageComponent,
1849
- SideNavigationComponent,
1850
- OutlineViewComponent,
1851
- JsonRendererComponent,
1852
- EntrySummaryComponent,
1853
- EntrySelectorDialogComponent,
1854
- MediaUploadModalComponent,
1855
- TimeAgoPipe,
1856
- LinkyPipe,
1857
- StaticHtmlComponent,
1858
- MainComponent,
1859
- EntryRendererWrapperComponent,
1860
- SchedulePublishDialogComponent,
1861
- ],
1862
- imports: [
1863
- CommonModule,
1864
- RouterModule,
1865
- FormsModule,
1866
- ReactiveFormsModule,
1867
- DragDropModule,
1868
- MatCardModule,
1869
- MatSidenavModule,
1870
- MatButtonModule,
1871
- MatInputModule,
1872
- MatListModule,
1873
- MatRadioModule,
1874
- MatDialogModule,
1875
- MatCheckboxModule,
1876
- MatDividerModule,
1877
- MatAutocompleteModule,
1878
- MatChipsModule,
1879
- MatIconModule,
1880
- MatDatepickerModule,
1881
- MatNativeDateModule,
1882
- MatTableModule,
1883
- FontAwesomeModule,
1884
- FileUploadModule,
1885
- NgxMaterialTimepickerModule,
1886
- ],
1887
- providers: [
1888
- CommentService,
1889
- EntryService,
1890
- UploadService,
1891
- PrismService,
1892
- IdentityService,
1893
- DjangoRestFrameworkEndpointService,
1894
- TagService,
1895
- ],
1896
- exports: [
1897
- EntryRendererComponent,
1898
- EntryCreatorComponent,
1899
- LandingPageComponent,
1900
- SideNavigationComponent,
1901
- OutlineViewComponent,
1902
- JsonRendererComponent,
1903
- EntrySummaryComponent,
1904
- EntrySelectorDialogComponent,
1905
- MediaUploadModalComponent,
1906
- TimeAgoPipe,
1907
- LinkyPipe,
1908
- StaticHtmlComponent,
1909
- MainComponent,
1910
- EntryRendererWrapperComponent,
1911
- ]
1912
- }]
1913
- }], ctorParameters: function () { return [{ type: i1$3.FaIconLibrary }]; } });
1914
-
1915
- /*
1916
- * Public API Surface of core
1917
- */
1918
-
1919
- /**
1920
- * Generated bundle index. Do not edit.
1921
- */
1922
-
1923
- export { Base, CommentService, Content, ContentType, CoreEvent, CoreEventType, CoreModule, DjangoRestFrameworkEndpointService, Entry, EntryCreatorComponent, EntryRendererComponent, EntryRendererWrapperComponent, EntrySelectorDialogComponent, EntryService, EntrySummaryComponent, Guid, IdentityService, Interaction, InteractionService, JsonRendererComponent, LandingPageComponent, LinkyPipe, ListResponse, MainComponent, MediaUploadModalComponent, OutlineViewComponent, PrismService, Routes, Section, SideNavigationComponent, StaticHtmlComponent, StaticHtmlService, TagService, TimeAgoPipe, Upload, UploadService, View, ViewService, VisitorProfile, VisitorProfileService };
1924
- //# sourceMappingURL=thecodeblogs-blog.mjs.map