@thecodeblogs/blog 0.11.7 → 0.13.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 (134) hide show
  1. package/esm2020/lib/components/entry-creator/entry-creator.component.mjs +347 -0
  2. package/esm2020/lib/components/entry-renderer/entry-renderer.component.mjs +108 -0
  3. package/esm2020/lib/components/entry-renderer-wrapper/entry-renderer-wrapper.component.mjs +75 -0
  4. package/esm2020/lib/components/entry-selector-dialog/entry-selector-dialog-data.mjs +3 -0
  5. package/esm2020/lib/components/entry-selector-dialog/entry-selector-dialog.component.mjs +45 -0
  6. package/esm2020/lib/components/entry-summary/entry-summary.component.mjs +28 -0
  7. package/esm2020/lib/components/json-renderer/json-renderer.component.mjs +26 -0
  8. package/esm2020/lib/components/landing-page/landing-page.component.mjs +35 -0
  9. package/esm2020/lib/components/main/main.component.mjs +56 -0
  10. package/esm2020/lib/components/media-upload-modal/media-upload-modal.component.mjs +160 -0
  11. package/esm2020/lib/components/outline-view/outline-view.component.mjs +40 -0
  12. package/esm2020/lib/components/schedule-publish-dialog/schedule-publish-dialog-data.mjs +3 -0
  13. package/esm2020/lib/components/schedule-publish-dialog/schedule-publish-dialog.component.mjs +33 -0
  14. package/esm2020/lib/components/side-navigation/side-navigation.component.mjs +151 -0
  15. package/esm2020/lib/components/static-html/static-html.component.mjs +28 -0
  16. package/esm2020/lib/core.module.mjs +207 -0
  17. package/esm2020/lib/data/base.mjs +7 -0
  18. package/esm2020/lib/data/content-type.mjs +10 -0
  19. package/esm2020/lib/data/content.mjs +5 -0
  20. package/esm2020/lib/data/core-event-type.enum.mjs +7 -0
  21. package/esm2020/lib/data/core-event.mjs +7 -0
  22. package/esm2020/lib/data/entry.mjs +80 -0
  23. package/esm2020/lib/data/guid.mjs +12 -0
  24. package/esm2020/lib/data/identity.mjs +2 -0
  25. package/esm2020/lib/data/list-response.mjs +3 -0
  26. package/esm2020/lib/data/section.mjs +11 -0
  27. package/esm2020/lib/data/tag.mjs +7 -0
  28. package/esm2020/lib/data/visitor-profile.mjs +3 -0
  29. package/esm2020/lib/pipes/LinkyPipe.mjs +15 -0
  30. package/esm2020/lib/pipes/TimeAgoPipe.mjs +100 -0
  31. package/esm2020/lib/routing/routes.mjs +25 -0
  32. package/esm2020/lib/services/analytics/interaction.service.mjs +20 -0
  33. package/esm2020/lib/services/analytics/view.service.mjs +20 -0
  34. package/esm2020/lib/services/comment.service.mjs +28 -0
  35. package/esm2020/lib/services/django-rest-framework-endpoint.service.mjs +50 -0
  36. package/esm2020/lib/services/entry.service.mjs +73 -0
  37. package/esm2020/lib/services/identity.service.mjs +20 -0
  38. package/esm2020/lib/services/interaction.mjs +3 -0
  39. package/esm2020/lib/services/prism.service.mjs +39 -0
  40. package/esm2020/lib/services/static-html.service.mjs +22 -0
  41. package/esm2020/lib/services/tag.service.mjs +33 -0
  42. package/esm2020/lib/services/upload.mjs +3 -0
  43. package/esm2020/lib/services/upload.service.mjs +22 -0
  44. package/esm2020/lib/services/view.mjs +3 -0
  45. package/esm2020/lib/services/visitor-profile.service.mjs +35 -0
  46. package/esm2020/public-api.mjs +45 -0
  47. package/esm2020/thecodeblogs-blog.mjs +5 -0
  48. package/fesm2015/thecodeblogs-blog.mjs +1826 -0
  49. package/fesm2015/thecodeblogs-blog.mjs.map +1 -0
  50. package/fesm2020/thecodeblogs-blog.mjs +1820 -0
  51. package/fesm2020/thecodeblogs-blog.mjs.map +1 -0
  52. package/lib/components/entry-creator/entry-creator.component.d.ts +3 -0
  53. package/lib/components/entry-renderer/entry-renderer.component.d.ts +3 -0
  54. package/lib/components/entry-renderer-wrapper/entry-renderer-wrapper.component.d.ts +3 -0
  55. package/lib/components/entry-selector-dialog/entry-selector-dialog.component.d.ts +3 -0
  56. package/lib/components/entry-summary/entry-summary.component.d.ts +3 -0
  57. package/lib/components/json-renderer/json-renderer.component.d.ts +3 -0
  58. package/lib/components/landing-page/landing-page.component.d.ts +3 -0
  59. package/lib/components/main/main.component.d.ts +3 -0
  60. package/lib/components/media-upload-modal/media-upload-modal.component.d.ts +3 -0
  61. package/lib/components/outline-view/outline-view.component.d.ts +3 -0
  62. package/lib/components/schedule-publish-dialog/schedule-publish-dialog.component.d.ts +3 -0
  63. package/lib/components/side-navigation/side-navigation.component.d.ts +3 -0
  64. package/lib/components/static-html/static-html.component.d.ts +3 -0
  65. package/lib/core.module.d.ts +40 -0
  66. package/lib/pipes/LinkyPipe.d.ts +3 -0
  67. package/lib/pipes/TimeAgoPipe.d.ts +3 -0
  68. package/lib/services/analytics/interaction.service.d.ts +3 -0
  69. package/lib/services/analytics/view.service.d.ts +3 -0
  70. package/lib/services/comment.service.d.ts +3 -0
  71. package/lib/services/django-rest-framework-endpoint.service.d.ts +3 -0
  72. package/lib/services/entry.service.d.ts +3 -0
  73. package/lib/services/identity.service.d.ts +3 -0
  74. package/lib/services/prism.service.d.ts +3 -0
  75. package/lib/services/static-html.service.d.ts +3 -0
  76. package/lib/services/tag.service.d.ts +3 -0
  77. package/lib/services/upload.service.d.ts +3 -0
  78. package/lib/services/visitor-profile.service.d.ts +3 -0
  79. package/package.json +36 -24
  80. package/thecodeblogs-blog.d.ts +1 -3
  81. package/bundles/thecodeblogs-blog.umd.js +0 -2279
  82. package/bundles/thecodeblogs-blog.umd.js.map +0 -1
  83. package/bundles/thecodeblogs-blog.umd.min.js +0 -17
  84. package/bundles/thecodeblogs-blog.umd.min.js.map +0 -1
  85. package/esm2015/lib/components/entry-creator/entry-creator.component.js +0 -336
  86. package/esm2015/lib/components/entry-renderer/entry-renderer.component.js +0 -108
  87. package/esm2015/lib/components/entry-renderer-wrapper/entry-renderer-wrapper.component.js +0 -79
  88. package/esm2015/lib/components/entry-selector-dialog/entry-selector-dialog-data.js +0 -3
  89. package/esm2015/lib/components/entry-selector-dialog/entry-selector-dialog.component.js +0 -41
  90. package/esm2015/lib/components/entry-summary/entry-summary.component.js +0 -29
  91. package/esm2015/lib/components/json-renderer/json-renderer.component.js +0 -29
  92. package/esm2015/lib/components/landing-page/landing-page.component.js +0 -37
  93. package/esm2015/lib/components/main/main.component.js +0 -55
  94. package/esm2015/lib/components/media-upload-modal/media-upload-modal.component.js +0 -155
  95. package/esm2015/lib/components/outline-view/outline-view.component.js +0 -40
  96. package/esm2015/lib/components/schedule-publish-dialog/schedule-publish-dialog-data.js +0 -3
  97. package/esm2015/lib/components/schedule-publish-dialog/schedule-publish-dialog.component.js +0 -28
  98. package/esm2015/lib/components/side-navigation/side-navigation.component.js +0 -154
  99. package/esm2015/lib/components/static-html/static-html.component.js +0 -33
  100. package/esm2015/lib/core.module.js +0 -125
  101. package/esm2015/lib/data/base.js +0 -7
  102. package/esm2015/lib/data/content-type.js +0 -10
  103. package/esm2015/lib/data/content.js +0 -5
  104. package/esm2015/lib/data/core-event-type.enum.js +0 -7
  105. package/esm2015/lib/data/core-event.js +0 -7
  106. package/esm2015/lib/data/entry.js +0 -80
  107. package/esm2015/lib/data/guid.js +0 -12
  108. package/esm2015/lib/data/identity.js +0 -2
  109. package/esm2015/lib/data/list-response.js +0 -3
  110. package/esm2015/lib/data/section.js +0 -11
  111. package/esm2015/lib/data/tag.js +0 -7
  112. package/esm2015/lib/data/visitor-profile.js +0 -3
  113. package/esm2015/lib/pipes/LinkyPipe.js +0 -11
  114. package/esm2015/lib/pipes/TimeAgoPipe.js +0 -100
  115. package/esm2015/lib/routing/routes.js +0 -25
  116. package/esm2015/lib/services/analytics/interaction.service.js +0 -22
  117. package/esm2015/lib/services/analytics/view.service.js +0 -22
  118. package/esm2015/lib/services/comment.service.js +0 -30
  119. package/esm2015/lib/services/django-rest-framework-endpoint.service.js +0 -52
  120. package/esm2015/lib/services/entry.service.js +0 -74
  121. package/esm2015/lib/services/identity.service.js +0 -22
  122. package/esm2015/lib/services/interaction.js +0 -3
  123. package/esm2015/lib/services/prism.service.js +0 -37
  124. package/esm2015/lib/services/static-html.service.js +0 -24
  125. package/esm2015/lib/services/tag.service.js +0 -35
  126. package/esm2015/lib/services/upload.js +0 -3
  127. package/esm2015/lib/services/upload.service.js +0 -24
  128. package/esm2015/lib/services/view.js +0 -3
  129. package/esm2015/lib/services/visitor-profile.service.js +0 -39
  130. package/esm2015/public-api.js +0 -45
  131. package/esm2015/thecodeblogs-blog.js +0 -8
  132. package/fesm2015/thecodeblogs-blog.js +0 -1786
  133. package/fesm2015/thecodeblogs-blog.js.map +0 -1
  134. package/thecodeblogs-blog.metadata.json +0 -1
@@ -1,1786 +0,0 @@
1
- import { orderBy, map as map$1, filter } from 'lodash';
2
- import { ɵɵdefineInjectable, ɵɵinject, Injectable, EventEmitter, PLATFORM_ID, Inject, SecurityContext, Component, Input, HostListener, ChangeDetectorRef, ViewChild, NgZone, Pipe, NgModule } from '@angular/core';
3
- import { HttpClient, HttpParams } from '@angular/common/http';
4
- import { map, debounceTime, startWith } from 'rxjs/operators';
5
- import { Subject, Subscription } from 'rxjs';
6
- import { isPlatformBrowser, CommonModule } from '@angular/common';
7
- import 'clipboard';
8
- import 'prismjs';
9
- import 'prismjs/plugins/toolbar/prism-toolbar';
10
- import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard';
11
- import 'prismjs/components/prism-css';
12
- import 'prismjs/components/prism-javascript';
13
- import 'prismjs/components/prism-java';
14
- import 'prismjs/components/prism-markup';
15
- import 'prismjs/components/prism-typescript';
16
- import 'prismjs/components/prism-sass';
17
- import 'prismjs/components/prism-scss';
18
- import { DeviceDetectorService } from 'ngx-device-detector';
19
- import { DomSanitizer } from '@angular/platform-browser';
20
- import { ENTER, COMMA, TAB } from '@angular/cdk/keycodes';
21
- import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogModule } from '@angular/material/dialog';
22
- import { FileUploader, FileUploadModule } from 'ng2-file-upload';
23
- import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
24
- import { Router, NavigationEnd, ActivatedRoute, RouterModule } from '@angular/router';
25
- import Autolinker from 'autolinker';
26
- import { DragDropModule } from '@angular/cdk/drag-drop';
27
- import { MatDividerModule } from '@angular/material/divider';
28
- import { MatCardModule } from '@angular/material/card';
29
- import { MatSidenavModule } from '@angular/material/sidenav';
30
- import { MatButtonModule } from '@angular/material/button';
31
- import { MatInputModule } from '@angular/material/input';
32
- import { MatListModule } from '@angular/material/list';
33
- import { MatRadioModule } from '@angular/material/radio';
34
- import { MatCheckboxModule } from '@angular/material/checkbox';
35
- import { MatAutocompleteModule } from '@angular/material/autocomplete';
36
- import { MatChipsModule } from '@angular/material/chips';
37
- import { MatIconModule } from '@angular/material/icon';
38
- import { MatNativeDateModule } from '@angular/material/core';
39
- import { MatDatepickerModule } from '@angular/material/datepicker';
40
- import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
41
- import { faSpinner } from '@fortawesome/free-solid-svg-icons';
42
- import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker';
43
-
44
- class Guid {
45
- newGuid() {
46
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
47
- // tslint:disable-next-line:no-bitwise
48
- const r = Math.random() * 16 | 0,
49
- // tslint:disable-next-line:triple-equals no-bitwise
50
- v = c == 'x' ? r : (r & 0x3 | 0x8);
51
- return v.toString(16);
52
- });
53
- }
54
- }
55
-
56
- class Base {
57
- constructor() {
58
- this.id = new Guid().newGuid();
59
- }
60
- }
61
-
62
- var ContentType;
63
- (function (ContentType) {
64
- ContentType["TEXT"] = "text";
65
- ContentType["URL"] = "url";
66
- ContentType["CODE"] = "code";
67
- ContentType["IMAGE"] = "image";
68
- ContentType["MEDIA"] = "media";
69
- ContentType["HTML"] = "html";
70
- })(ContentType || (ContentType = {}));
71
-
72
- class Content extends Base {
73
- }
74
- Content.KEY_MIMETYPE = 'mimeType';
75
-
76
- const slugify = require('slugify');
77
- class Entry extends Base {
78
- constructor(init) {
79
- super();
80
- this.should_publish_in_future = false;
81
- Object.assign(this, init);
82
- if (!this.create_date) {
83
- this.create_date = new Date();
84
- }
85
- else {
86
- this.create_date = new Date(this.create_date);
87
- }
88
- if (!this.edit_date) {
89
- this.edit_date = new Date();
90
- }
91
- else {
92
- this.edit_date = new Date(this.edit_date);
93
- }
94
- if (this.publish_date) {
95
- this.publish_date = new Date(this.publish_date);
96
- }
97
- if (this.future_publish_date) {
98
- this.future_publish_date = new Date(this.future_publish_date);
99
- }
100
- if (!this.version) {
101
- this.version = 1;
102
- }
103
- if (!this.tags) {
104
- this.tags = [];
105
- }
106
- if (this.views) {
107
- if (this.views < 10) {
108
- this._friendly_views = 'Less than ten';
109
- }
110
- else if (10 < this.views && this.views < 100) {
111
- this._friendly_views = 'Around one hundred';
112
- }
113
- else {
114
- this._friendly_views = this.views.toString();
115
- }
116
- }
117
- if (!this.sections) {
118
- this.sections = [];
119
- }
120
- // For entries that existed before this variable was introduced, the server will return undefined. If this
121
- // stays undefined, it will violate the null constraints on the DB, so this code checks for both null
122
- // and undefined and then populates the value accordingly
123
- if (typeof (this.should_publish_in_future) === 'undefined' || this.should_publish_in_future === null) {
124
- this.should_publish_in_future = false;
125
- }
126
- }
127
- sort() {
128
- this.sections = orderBy(this.sections, ({ order }) => Number(order), ['asc']);
129
- for (let i = 0; i < this.sections.length; i++) {
130
- this.sections[i].order = i * 10;
131
- }
132
- for (const section of this.sections) {
133
- section.contents = orderBy(section.contents, ({ order }) => Number(order), ['asc']);
134
- for (let i = 0; i < section.contents.length; i++) {
135
- section.contents[i].order = i * 10;
136
- }
137
- }
138
- }
139
- showEditInformation() {
140
- // @ts-ignore
141
- const difference = Math.floor((this.create_date - this.edit_date) / (1000 * 60 * 60 * 24));
142
- return (difference > 1 || difference < -1);
143
- }
144
- getProp(prop) {
145
- if (this.__server_generated_properties) {
146
- return this.__server_generated_properties[prop];
147
- }
148
- else {
149
- return '';
150
- }
151
- }
152
- }
153
-
154
- class ListResponse {
155
- }
156
-
157
- class Section extends Base {
158
- constructor() {
159
- super();
160
- if (!this.order) {
161
- this.order = -1;
162
- }
163
- this.contents = [];
164
- }
165
- }
166
-
167
- class CoreEvent {
168
- constructor(data, type) {
169
- this.data = data;
170
- this.type = type;
171
- }
172
- }
173
-
174
- var CoreEventType;
175
- (function (CoreEventType) {
176
- CoreEventType["UPDATE"] = "update";
177
- CoreEventType["CREATE"] = "create";
178
- CoreEventType["DELETE"] = "delete";
179
- })(CoreEventType || (CoreEventType = {}));
180
-
181
- class VisitorProfile {
182
- }
183
-
184
- class CommentService {
185
- constructor(http) {
186
- this.http = http;
187
- this.endpoint = '/blog_api/comments/';
188
- this.adminEndpoint = '/blog_api/admin/comments/';
189
- }
190
- getComments(entry) {
191
- return this.http.get(this.endpoint, { params: { entry } });
192
- }
193
- postComment(comment) {
194
- return this.http.post(this.endpoint, comment, { params: { entry: comment.entry } });
195
- }
196
- patchComment(comment) {
197
- return this.http.patch(this.adminEndpoint + '/' + comment.id + '/', comment);
198
- }
199
- }
200
- CommentService.ɵprov = ɵɵdefineInjectable({ factory: function CommentService_Factory() { return new CommentService(ɵɵinject(HttpClient)); }, token: CommentService, providedIn: "root" });
201
- CommentService.decorators = [
202
- { type: Injectable, args: [{
203
- providedIn: 'root'
204
- },] }
205
- ];
206
- CommentService.ctorParameters = () => [
207
- { type: HttpClient }
208
- ];
209
-
210
- class DjangoRestFrameworkEndpointService {
211
- constructor(http) {
212
- this.http = http;
213
- this.events = new EventEmitter();
214
- this.endpoint = '';
215
- }
216
- triggerCoreEvent(obj, type) {
217
- this.events.next(new CoreEvent(obj, type));
218
- return obj;
219
- }
220
- handleResponse(obj) {
221
- return obj;
222
- }
223
- handleListResponse(obj) {
224
- return obj;
225
- }
226
- get() {
227
- return this.http.get(this.endpoint).pipe(map(this.handleListResponse.bind(this)));
228
- }
229
- getById(id) {
230
- return this.http.get(this.endpoint + id + '/').pipe(map(this.handleResponse.bind(this)));
231
- }
232
- create(entity) {
233
- return this.http.post(this.endpoint + '/', entity).pipe(map((val) => this.triggerCoreEvent(val, CoreEventType.CREATE)), map(this.handleResponse.bind(this)));
234
- }
235
- delete(entity) {
236
- return this.http.delete(this.endpoint + entity.id + '/').pipe(map((val) => this.triggerCoreEvent(val, CoreEventType.DELETE)), map(this.handleResponse.bind(this)));
237
- }
238
- update(entity) {
239
- return this.http.patch(this.endpoint + entity.id + '/', entity).pipe(map((val) => this.triggerCoreEvent(val, CoreEventType.UPDATE)), map(this.handleResponse.bind(this)));
240
- }
241
- getListByUrl(url) {
242
- return this.http.get(url).pipe(map(this.handleListResponse.bind(this)));
243
- }
244
- }
245
- DjangoRestFrameworkEndpointService.ɵprov = ɵɵdefineInjectable({ factory: function DjangoRestFrameworkEndpointService_Factory() { return new DjangoRestFrameworkEndpointService(ɵɵinject(HttpClient)); }, token: DjangoRestFrameworkEndpointService, providedIn: "root" });
246
- DjangoRestFrameworkEndpointService.decorators = [
247
- { type: Injectable, args: [{
248
- providedIn: 'root'
249
- },] }
250
- ];
251
- DjangoRestFrameworkEndpointService.ctorParameters = () => [
252
- { type: HttpClient }
253
- ];
254
-
255
- class EntryService extends DjangoRestFrameworkEndpointService {
256
- constructor(http) {
257
- super(http);
258
- this.http = http;
259
- this.endpoint = '/blog_api/entries/';
260
- this.adminEndpoint = '/blog_api/admin/entries/';
261
- this.currentlyEditedEntry = new Subject();
262
- this.sub = this.currentlyEditedEntry.pipe(debounceTime(3000)).subscribe((e) => {
263
- e.edit_date = new Date();
264
- const params = new HttpParams().set('published', JSON.stringify(false)).set('defunct', JSON.stringify(false));
265
- this.http.patch(this.adminEndpoint + e.id + '/', e, { params }).pipe(map(this.handleResponse.bind(this))).subscribe((response) => {
266
- this.triggerCoreEvent(response, CoreEventType.UPDATE);
267
- console.log('Synced ' + e.id + '...');
268
- }, (err) => {
269
- console.log('Error encountered syncing ' + e.id + ', trying to create...');
270
- this.http.post(this.adminEndpoint, e).pipe(map(this.handleResponse)).subscribe((response) => {
271
- this.triggerCoreEvent(response, CoreEventType.CREATE);
272
- console.log('Created ' + e.id + '...');
273
- }, (createErr) => {
274
- console.log('Error creating ' + e.id);
275
- });
276
- });
277
- });
278
- }
279
- handleResponse(obj) {
280
- return new Entry(obj);
281
- }
282
- handleListResponse(obj) {
283
- const response = obj;
284
- const results = [];
285
- for (const result of response.results) {
286
- results.push(new Entry(result));
287
- }
288
- response.results = results;
289
- return response;
290
- }
291
- get() {
292
- return this.http.get(this.endpoint).pipe(map(this.handleListResponse.bind(this)));
293
- }
294
- getUnpublishedEntries() {
295
- const params = new HttpParams().set('published', JSON.stringify(false)).set('defunct', JSON.stringify(false));
296
- return this.http.get(this.adminEndpoint, { params });
297
- }
298
- getBySlug(slug) {
299
- return this.http.get(this.endpoint + slug + '/by_slug/').pipe(map(this.handleResponse.bind(this)));
300
- }
301
- getUnpublishedById(id) {
302
- const params = new HttpParams().set('published', JSON.stringify(false)).set('defunct', JSON.stringify(false));
303
- return this.http.get(this.adminEndpoint + id, { params }).pipe(map(this.handleResponse.bind(this)));
304
- }
305
- updateUnpublishedEntry(entry) {
306
- const params = new HttpParams().set('published', JSON.stringify(false)).set('defunct', JSON.stringify(false));
307
- return this.http.patch(this.adminEndpoint + entry.id + '/', entry, { params }).pipe(map((val) => this.triggerCoreEvent(val, CoreEventType.UPDATE)), map(this.handleResponse.bind(this)));
308
- }
309
- }
310
- EntryService.ɵprov = ɵɵdefineInjectable({ factory: function EntryService_Factory() { return new EntryService(ɵɵinject(HttpClient)); }, token: EntryService, providedIn: "root" });
311
- EntryService.decorators = [
312
- { type: Injectable, args: [{
313
- providedIn: 'root'
314
- },] }
315
- ];
316
- EntryService.ctorParameters = () => [
317
- { type: HttpClient }
318
- ];
319
-
320
- class IdentityService {
321
- constructor(http) {
322
- this.http = http;
323
- }
324
- getMe() {
325
- throw new Error('You must provide an implementation for this');
326
- }
327
- }
328
- IdentityService.ɵprov = ɵɵdefineInjectable({ factory: function IdentityService_Factory() { return new IdentityService(ɵɵinject(HttpClient)); }, token: IdentityService, providedIn: "root" });
329
- IdentityService.decorators = [
330
- { type: Injectable, args: [{
331
- providedIn: 'root'
332
- },] }
333
- ];
334
- IdentityService.ctorParameters = () => [
335
- { type: HttpClient }
336
- ];
337
-
338
- class PrismService {
339
- constructor(platformId) {
340
- this.platformId = platformId;
341
- if (Prism) {
342
- Prism.manual = true;
343
- }
344
- }
345
- highlightAll() {
346
- if (isPlatformBrowser(this.platformId)) {
347
- Prism.highlightAll();
348
- }
349
- }
350
- }
351
- PrismService.ɵprov = ɵɵdefineInjectable({ factory: function PrismService_Factory() { return new PrismService(ɵɵinject(PLATFORM_ID)); }, token: PrismService, providedIn: "root" });
352
- PrismService.decorators = [
353
- { type: Injectable, args: [{
354
- providedIn: 'root'
355
- },] }
356
- ];
357
- PrismService.ctorParameters = () => [
358
- { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }
359
- ];
360
-
361
- class UploadService {
362
- constructor(http) {
363
- this.http = http;
364
- }
365
- get(id) {
366
- return this.http.get(UploadService.status_endpoint.replace('{pk}', id) + '/');
367
- }
368
- }
369
- UploadService.upload_endpoint = '/file_api/uploads/create_image/';
370
- UploadService.status_endpoint = '/file_api/uploads/{pk}/status';
371
- UploadService.ɵprov = ɵɵdefineInjectable({ factory: function UploadService_Factory() { return new UploadService(ɵɵinject(HttpClient)); }, token: UploadService, providedIn: "root" });
372
- UploadService.decorators = [
373
- { type: Injectable, args: [{
374
- providedIn: 'root'
375
- },] }
376
- ];
377
- UploadService.ctorParameters = () => [
378
- { type: HttpClient }
379
- ];
380
-
381
- class Upload {
382
- }
383
-
384
- class ViewService extends DjangoRestFrameworkEndpointService {
385
- constructor(http) {
386
- super(http);
387
- this.http = http;
388
- this.endpoint = '/blog_api/views/';
389
- }
390
- }
391
- ViewService.ɵprov = ɵɵdefineInjectable({ factory: function ViewService_Factory() { return new ViewService(ɵɵinject(HttpClient)); }, token: ViewService, providedIn: "root" });
392
- ViewService.decorators = [
393
- { type: Injectable, args: [{
394
- providedIn: 'root'
395
- },] }
396
- ];
397
- ViewService.ctorParameters = () => [
398
- { type: HttpClient }
399
- ];
400
-
401
- class InteractionService extends DjangoRestFrameworkEndpointService {
402
- constructor(http) {
403
- super(http);
404
- this.http = http;
405
- this.endpoint = '/blog_api/interactions/';
406
- }
407
- }
408
- InteractionService.ɵprov = ɵɵdefineInjectable({ factory: function InteractionService_Factory() { return new InteractionService(ɵɵinject(HttpClient)); }, token: InteractionService, providedIn: "root" });
409
- InteractionService.decorators = [
410
- { type: Injectable, args: [{
411
- providedIn: 'root'
412
- },] }
413
- ];
414
- InteractionService.ctorParameters = () => [
415
- { type: HttpClient }
416
- ];
417
-
418
- class View {
419
- }
420
-
421
- class Interaction {
422
- }
423
-
424
- class VisitorProfileService extends DjangoRestFrameworkEndpointService {
425
- constructor(http, deviceDetectorService) {
426
- super(http);
427
- this.http = http;
428
- this.deviceDetectorService = deviceDetectorService;
429
- this.endpoint = '/blog_api/visitor_profiles/';
430
- }
431
- getVisitorProfile() {
432
- const deviceInfo = this.deviceDetectorService.getDeviceInfo();
433
- const vp = new VisitorProfile();
434
- vp.telemetry = deviceInfo;
435
- vp.name = deviceInfo.os;
436
- vp.family = deviceInfo.browser;
437
- vp.version = deviceInfo.browser_version;
438
- vp.device = deviceInfo.device;
439
- vp.os_version = deviceInfo.os_version;
440
- vp.language = navigator.language;
441
- return vp;
442
- }
443
- }
444
- VisitorProfileService.ɵprov = ɵɵdefineInjectable({ factory: function VisitorProfileService_Factory() { return new VisitorProfileService(ɵɵinject(HttpClient), ɵɵinject(DeviceDetectorService)); }, token: VisitorProfileService, providedIn: "root" });
445
- VisitorProfileService.decorators = [
446
- { type: Injectable, args: [{
447
- providedIn: 'root'
448
- },] }
449
- ];
450
- VisitorProfileService.ctorParameters = () => [
451
- { type: HttpClient },
452
- { type: DeviceDetectorService }
453
- ];
454
-
455
- class StaticHtmlService {
456
- constructor(domSanitizer) {
457
- this.domSanitizer = domSanitizer;
458
- }
459
- mapStaticHtml(htmlString, isTrusted) {
460
- return isTrusted ?
461
- htmlString :
462
- this.domSanitizer.sanitize(SecurityContext.HTML, htmlString);
463
- }
464
- }
465
- StaticHtmlService.ɵprov = ɵɵdefineInjectable({ factory: function StaticHtmlService_Factory() { return new StaticHtmlService(ɵɵinject(DomSanitizer)); }, token: StaticHtmlService, providedIn: "root" });
466
- StaticHtmlService.decorators = [
467
- { type: Injectable, args: [{
468
- providedIn: 'root'
469
- },] }
470
- ];
471
- StaticHtmlService.ctorParameters = () => [
472
- { type: DomSanitizer }
473
- ];
474
-
475
- class Tag {
476
- constructor(obj) {
477
- this.id = obj.id;
478
- this.label = obj.label;
479
- }
480
- }
481
-
482
- class TagService extends DjangoRestFrameworkEndpointService {
483
- constructor(http) {
484
- super(http);
485
- this.http = http;
486
- this.endpoint = '/blog_api/tags/';
487
- }
488
- handleResponse(obj) {
489
- return new Tag(obj);
490
- }
491
- handleListResponse(obj) {
492
- const response = obj;
493
- const results = [];
494
- for (let i = 0; i < response.results.length; i++) {
495
- results.push(new Tag(response.results[i]));
496
- }
497
- response.results = results;
498
- return response;
499
- }
500
- }
501
- TagService.ɵprov = ɵɵdefineInjectable({ factory: function TagService_Factory() { return new TagService(ɵɵinject(HttpClient)); }, token: TagService, providedIn: "root" });
502
- TagService.decorators = [
503
- { type: Injectable, args: [{
504
- providedIn: 'root'
505
- },] }
506
- ];
507
- TagService.ctorParameters = () => [
508
- { type: HttpClient }
509
- ];
510
-
511
- class EntrySelectorDialogData {
512
- }
513
-
514
- class EntrySelectorDialogComponent {
515
- constructor(dialogRef, data, entryService) {
516
- this.dialogRef = dialogRef;
517
- this.data = data;
518
- this.entryService = entryService;
519
- }
520
- ngOnInit() {
521
- this.entryService.getUnpublishedEntries().subscribe((next) => {
522
- this.entries = next.results;
523
- });
524
- }
525
- onNoClick() {
526
- this.dialogRef.close();
527
- }
528
- onYesClick() {
529
- this.entryService.getUnpublishedById(this.selectedId).subscribe((entry) => {
530
- localStorage.setItem(EntrySelectorDialogComponent.CURRENT_ENTRY, JSON.stringify(entry));
531
- entry.sort();
532
- this.entryService.currentlyEditedEntry.next(entry);
533
- this.dialogRef.close();
534
- });
535
- }
536
- }
537
- EntrySelectorDialogComponent.CURRENT_ENTRY = 'current_entry';
538
- EntrySelectorDialogComponent.decorators = [
539
- { type: Component, args: [{
540
- selector: 'app-entry-selector-dialog',
541
- 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 <mat-radio-group [(ngModel)]=\"selectedId\">\n <mat-radio-button *ngFor=\"let entry of entries\" class=\"option\" [value]=\"entry.id\">{{entry.title}}</mat-radio-button>\n </mat-radio-group>\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 <button mat-button (click)=\"onYesClick()\" [mat-dialog-close]=\"this.selectedId\" cdkFocusInitial>Edit Selected Entry</button>\n</div>\n",
542
- styles: [".entry-checkbox-container{display:inline-block;margin:5px 0;width:100%}.option-list-divider{margin:10px 0}.option{margin-right:5px}"]
543
- },] }
544
- ];
545
- EntrySelectorDialogComponent.ctorParameters = () => [
546
- { type: MatDialogRef },
547
- { type: EntrySelectorDialogData, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] },
548
- { type: EntryService }
549
- ];
550
-
551
- class MediaUploadModalComponent {
552
- constructor(dialogRef, uploadService) {
553
- this.dialogRef = dialogRef;
554
- this.uploadService = uploadService;
555
- this.allowedMimeTypes = [
556
- 'image/jpeg',
557
- 'image/gif',
558
- 'image/png',
559
- 'image/jpg',
560
- 'video/mp4',
561
- 'video/webm',
562
- 'video/ogg',
563
- ];
564
- this.uploadUrlKey = 'path_to_file';
565
- this.uploading = false;
566
- }
567
- static getCookie(name) {
568
- const ca = document.cookie.split(';');
569
- const caLen = ca.length;
570
- const cookieName = `${name}=`;
571
- let c;
572
- for (let i = 0; i < caLen; i += 1) {
573
- c = ca[i].replace(/^\s+/g, '');
574
- if (c.indexOf(cookieName) === 0) {
575
- return c.substring(cookieName.length, c.length);
576
- }
577
- }
578
- return '';
579
- }
580
- pollForCompletion() {
581
- this.uploadService.get(this.uploadId).subscribe((response) => {
582
- if (response.processed) {
583
- this.imgLink = response[this.uploadUrlKey];
584
- this.mimeType = response.mime_type;
585
- clearInterval(this.poller);
586
- this.poller = null;
587
- this.uploading = false;
588
- }
589
- });
590
- }
591
- ngOnInit() {
592
- this.uploader = new FileUploader({
593
- url: UploadService.upload_endpoint,
594
- itemAlias: 'file',
595
- authToken: '',
596
- headers: [
597
- { name: 'X-CSRFToken', value: MediaUploadModalComponent.getCookie('csrftoken') },
598
- ],
599
- additionalParameter: { csrf_token: MediaUploadModalComponent.getCookie('csrftoken') },
600
- removeAfterUpload: true,
601
- allowedMimeType: this.allowedMimeTypes,
602
- });
603
- this.uploader.onCompleteItem = (item, response) => {
604
- const responseObj = JSON.parse(response);
605
- this.uploadId = responseObj.id;
606
- this.poller = setInterval(this.pollForCompletion.bind(this), 2000);
607
- };
608
- this.uploader.onWhenAddingFileFailed = (item, filter, options) => {
609
- this.error = 'This file is not a supported mimetype.';
610
- this.uploading = false;
611
- };
612
- if (this.file) {
613
- this.uploader.addToQueue([this.file]);
614
- this.uploader.uploadAll();
615
- this.uploading = true;
616
- }
617
- }
618
- onFileSelected(e) {
619
- this.uploader.uploadAll();
620
- this.uploading = true;
621
- }
622
- buildHost(url) {
623
- return location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '') + url;
624
- }
625
- close() {
626
- this.dialogRef.close();
627
- }
628
- ngOnDestroy() {
629
- if (this.socketSub) {
630
- this.socketSub.complete();
631
- this.socketSub = null;
632
- }
633
- }
634
- blobToFile(theBlob, fileName) {
635
- // A Blob() is almost a File() - it's just missing the two properties below which we will add
636
- theBlob.lastModifiedDate = new Date();
637
- theBlob.name = fileName;
638
- return theBlob;
639
- }
640
- onPaste(e) {
641
- if (e instanceof ClipboardEvent) {
642
- const files = e.clipboardData.files;
643
- if (files) {
644
- if (files.length < 1) {
645
- // const items = e.clipboardData.items;
646
- // for(let i = 0; i < items.length; i++) {
647
- // const item = items[i];
648
- // item.getAsString((text) => {
649
- // try {
650
- // const url = new URL(text);
651
- // if(url) {
652
- // fetch(text)
653
- // .then(res => res.blob()) // Gets the response and returns it as a blob
654
- // .then(blob => {
655
- // const file = this.blobToFile(blob, 'web-created')
656
- // this.uploader.addToQueue([file])
657
- // this.uploader.uploadAll();
658
- // this.uploading = true;
659
- // });
660
- // }
661
- // } catch(e) {
662
- //
663
- // }
664
- // });
665
- // }
666
- }
667
- else if (files.length > 1) {
668
- console.log('Multiple files detected');
669
- }
670
- else {
671
- for (let i = 0; i < files.length; i++) {
672
- this.uploader.addToQueue([files[i]]);
673
- }
674
- this.uploader.uploadAll();
675
- this.uploading = true;
676
- }
677
- }
678
- else {
679
- console.log('Stuff not working');
680
- }
681
- }
682
- }
683
- }
684
- MediaUploadModalComponent.decorators = [
685
- { type: Component, args: [{
686
- selector: 'app-media-upload-modal',
687
- 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",
688
- styles: [""]
689
- },] }
690
- ];
691
- MediaUploadModalComponent.ctorParameters = () => [
692
- { type: MatDialogRef },
693
- { type: UploadService }
694
- ];
695
- MediaUploadModalComponent.propDecorators = {
696
- allowedMimeTypes: [{ type: Input }],
697
- uploadUrlKey: [{ type: Input }],
698
- file: [{ type: Input }],
699
- onPaste: [{ type: HostListener, args: ['document:paste', ['$event'],] }]
700
- };
701
-
702
- const slugify$1 = require('slugify');
703
- class EntryCreatorComponent {
704
- constructor(entryService, tagService, identityService, cdr, dialog) {
705
- this.entryService = entryService;
706
- this.tagService = tagService;
707
- this.identityService = identityService;
708
- this.cdr = cdr;
709
- this.dialog = dialog;
710
- this.ContentType = ContentType;
711
- this.Object = Object;
712
- this.entry = new Entry();
713
- this.separatorKeysCodes = [ENTER, COMMA, TAB];
714
- this.removable = true;
715
- this.all_tags = ['Angular', 'Bash', 'MacOS', 'Typescript', 'NPM', 'Databases'];
716
- this.tagCtrl = new FormControl();
717
- this.publishDateControl = new FormControl();
718
- this.selectable = false;
719
- this.scheduling = false;
720
- this.customScheduleTime = '';
721
- this.today = new Date();
722
- this.allowedMimeTypes = [
723
- 'image/jpeg',
724
- 'image/gif',
725
- 'image/png',
726
- 'image/jpg',
727
- 'video/mp4',
728
- 'video/webm',
729
- 'video/ogg',
730
- ];
731
- this.uploadUrlKey = 'path_to_file';
732
- this.uploader = new FileUploader({
733
- url: '/file_api/uploads/create_image/',
734
- itemAlias: 'file',
735
- authToken: '',
736
- headers: [
737
- {
738
- name: 'X-CSRFToken',
739
- value: EntryCreatorComponent.getCookie('csrftoken')
740
- },
741
- ],
742
- additionalParameter: {
743
- 'csrf_token': EntryCreatorComponent.getCookie('csrftoken')
744
- },
745
- removeAfterUpload: true,
746
- allowedMimeType: this.allowedMimeTypes,
747
- });
748
- const scheduledDate = new Date();
749
- this.customScheduleTime = scheduledDate.getHours() + ':' + scheduledDate.getMinutes() + ' AM';
750
- }
751
- static getCookie(name) {
752
- const ca = document.cookie.split(';');
753
- const caLen = ca.length;
754
- const cookieName = `${name}=`;
755
- let c;
756
- for (let i = 0; i < caLen; i += 1) {
757
- c = ca[i].replace(/^\s+/g, '');
758
- if (c.indexOf(cookieName) === 0) {
759
- return c.substring(cookieName.length, c.length);
760
- }
761
- }
762
- return '';
763
- }
764
- _filter(value) {
765
- const filterValue = value.toLowerCase();
766
- return this.all_tags.filter(tag => tag.toLowerCase().indexOf(filterValue) === 0);
767
- }
768
- add(event) {
769
- const input = event.input;
770
- const value = event.value;
771
- // Add our tag
772
- if ((value || '').trim()) {
773
- this.tags.push(value.trim());
774
- }
775
- // Reset the input value
776
- if (input) {
777
- input.value = '';
778
- }
779
- this.tagCtrl.setValue(null);
780
- this.onChange();
781
- }
782
- remove(fruit) {
783
- const index = this.tags.indexOf(fruit);
784
- if (index >= 0) {
785
- this.tags.splice(index, 1);
786
- }
787
- this.onChange();
788
- }
789
- selected(event) {
790
- this.tags.push(event.option.viewValue);
791
- this.tagInput.nativeElement.value = '';
792
- this.tagCtrl.setValue(null);
793
- this.onChange();
794
- }
795
- refreshTags() {
796
- this.tagService.get().subscribe((response) => {
797
- this.all_tags = map$1(response.results, (t) => t.label);
798
- this.filtered_tags = this.tagCtrl.valueChanges.pipe(startWith(null), map((tag) => tag ? this._filter(tag) : this.all_tags.slice()));
799
- });
800
- }
801
- createNewEntry() {
802
- this.entry = new Entry();
803
- this.entry.title = EntryCreatorComponent.DEFAULT_NEW_ENTRY_TITLE;
804
- this.entry.published = false;
805
- this.entry.version = 1;
806
- this.entryService.create(this.entry).subscribe((response) => {
807
- this.entry = response;
808
- this.entry.sort();
809
- setTimeout(() => {
810
- this.entryService.currentlyEditedEntry.next(this.entry);
811
- }, 10);
812
- });
813
- }
814
- ngOnInit() {
815
- this.refreshTags();
816
- this.identityService.getMe().subscribe((me) => {
817
- this.me = me;
818
- });
819
- const savedEntry = localStorage.getItem(EntryCreatorComponent.CURRENT_ENTRY);
820
- if (savedEntry) {
821
- this.entry = new Entry(JSON.parse(savedEntry));
822
- if (this.entry.should_publish_in_future && this.entry.future_publish_date < new Date()) {
823
- this.createNewEntry();
824
- }
825
- this.entry.sort();
826
- if (this.entry.should_publish_in_future) {
827
- // Restore scheduling settings
828
- this.scheduling = true;
829
- let hours = this.entry.future_publish_date.getHours();
830
- let minutes = this.entry.future_publish_date.getMinutes();
831
- const ampm = hours >= 12 ? 'PM' : 'AM';
832
- if (hours >= 12) {
833
- hours = hours % 12;
834
- hours = hours ? hours : 12;
835
- }
836
- minutes = minutes < 10 ? '0' + minutes : minutes;
837
- this.customScheduleTime = hours + ':' + minutes + ' ' + ampm;
838
- }
839
- setTimeout(() => {
840
- this.entryService.currentlyEditedEntry.next(this.entry);
841
- }, 10);
842
- }
843
- else {
844
- this.createNewEntry();
845
- }
846
- this.uploader.onCompleteItem = (item, response) => {
847
- // const responseObj = JSON.parse(response)
848
- // this.uploadId = responseObj.id;
849
- };
850
- this.uploader.onWhenAddingFileFailed = (item, uploadFilter, options) => {
851
- // this.error = 'This file is not a supported mimetype.'
852
- // this.uploading = false;
853
- };
854
- this.tags = this.entry.tags;
855
- }
856
- onFileSelected(e) {
857
- this.uploader.uploadAll();
858
- }
859
- startUploader(content) {
860
- const dialogRef = this.dialog.open(MediaUploadModalComponent, {});
861
- dialogRef.componentInstance.allowedMimeTypes = this.allowedMimeTypes;
862
- dialogRef.componentInstance.uploadUrlKey = this.uploadUrlKey;
863
- dialogRef.afterClosed().subscribe(() => {
864
- content.value = dialogRef.componentInstance.imgLink;
865
- content.additional = [];
866
- content.additional.push({ key: Content.KEY_MIMETYPE, value: dialogRef.componentInstance.mimeType });
867
- this.onChange();
868
- });
869
- }
870
- addSection() {
871
- this.entry.sections.push(new Section());
872
- this.onChange();
873
- }
874
- removeSection(section) {
875
- const remove = confirm('Are you sure you want to remove this section?');
876
- if (remove) {
877
- this.entry.sections =
878
- filter(this.entry.sections, (sct) => sct.id !== section.id);
879
- this.onChange();
880
- }
881
- }
882
- addContent(section) {
883
- section.contents.push(new Content());
884
- this.onChange();
885
- }
886
- removeContent(content) {
887
- const remove = confirm('Are you sure you want to remove this content?');
888
- if (remove) {
889
- for (const section of this.entry.sections) {
890
- section.contents = filter(section.contents, (ct) => ct.id !== content.id);
891
- }
892
- this.onChange();
893
- }
894
- }
895
- onChange() {
896
- this.entry.slug = slugify$1(this.entry.title).toLowerCase();
897
- localStorage.setItem(EntryCreatorComponent.CURRENT_ENTRY, JSON.stringify(this.entry));
898
- this.entry.sort();
899
- this.cdr.detectChanges();
900
- this.entryService.currentlyEditedEntry.next(this.entry);
901
- this.entryService._currentlyEditedEntry = this.entry;
902
- }
903
- resetDate() {
904
- this.entry.create_date = new Date();
905
- this.entry.edit_date = new Date();
906
- this.onChange();
907
- }
908
- startNew() {
909
- const finish = confirm('Are you sure your finished? The JSON and entry displayed will be removed. Make sure you have already copied it.');
910
- if (finish) {
911
- this.entry = new Entry();
912
- this.entry.title = EntryCreatorComponent.DEFAULT_NEW_ENTRY_TITLE;
913
- this.entry.published = false;
914
- this.entry.version = 1;
915
- this.entryService.currentlyEditedEntry.next(this.entry);
916
- localStorage.setItem(EntryCreatorComponent.CURRENT_ENTRY, JSON.stringify(this.entry));
917
- this.entryService.create(this.entry).subscribe((next) => {
918
- });
919
- }
920
- }
921
- seeEntries() {
922
- const dialogRef = this.dialog.open(EntrySelectorDialogComponent, {
923
- width: '500px',
924
- data: { name: 'test', animal: 'test' }
925
- });
926
- dialogRef.afterClosed().subscribe((id) => {
927
- if (id) {
928
- this.entryService.getUnpublishedById(id).subscribe((result) => {
929
- const entry = result;
930
- this.entryService.currentlyEditedEntry.next(entry);
931
- localStorage.setItem(EntryCreatorComponent.CURRENT_ENTRY, JSON.stringify(entry));
932
- this.entry = entry;
933
- });
934
- }
935
- });
936
- }
937
- postPublishCallback() {
938
- this.entry = new Entry();
939
- this.entry.title = EntryCreatorComponent.DEFAULT_NEW_ENTRY_TITLE;
940
- this.entry.published = false;
941
- this.entry.version = 1;
942
- this.entryService.currentlyEditedEntry.next(this.entry);
943
- localStorage.setItem(EntryCreatorComponent.CURRENT_ENTRY, JSON.stringify(this.entry));
944
- this.entryService.create(this.entry).subscribe((next) => {
945
- this.tags = [];
946
- this.refreshTags();
947
- });
948
- }
949
- cancelScheduling() {
950
- this.entry.future_publish_date = null;
951
- this.entry.should_publish_in_future = false;
952
- this.scheduling = false;
953
- this.onChange();
954
- }
955
- exposeScheduling() {
956
- const scheduledDate = new Date();
957
- scheduledDate.setDate(scheduledDate.getDate() + 1);
958
- this.entry.future_publish_date = scheduledDate;
959
- this.setTime(this.customScheduleTime);
960
- this.entry.should_publish_in_future = true;
961
- this.scheduling = true;
962
- this.onChange();
963
- }
964
- publish() {
965
- const publish = confirm('Are you sure you want to publish? Once an article is published it is available to everyone.');
966
- if (publish) {
967
- this.entry.published = true;
968
- this.entry.publish_date = new Date();
969
- this.entry.edit_date = new Date();
970
- this.entryService.updateUnpublishedEntry(this.entry).subscribe(this.postPublishCallback.bind(this));
971
- }
972
- }
973
- delete() {
974
- const confirmDelete = confirm('Are you sure you want to delete this draft? Once it is deleted it cannot be recovered.');
975
- if (confirmDelete) {
976
- this.entryService.delete(this.entry).subscribe(() => {
977
- this.entry = null;
978
- });
979
- }
980
- }
981
- onDateChange() {
982
- this.entry.future_publish_date.setHours(this.hours);
983
- this.entry.future_publish_date.setMinutes(this.minutes);
984
- this.onChange();
985
- }
986
- setTime(e) {
987
- const firstTimeSplit = e.split(' ');
988
- const secondTimeSplit = firstTimeSplit[0].split(':');
989
- this.hours = Number(secondTimeSplit[0]);
990
- this.minutes = Number(secondTimeSplit[1]);
991
- if (firstTimeSplit[1] === 'PM') {
992
- this.hours = Number(this.hours) + 12;
993
- }
994
- this.entry.future_publish_date.setHours(this.hours);
995
- this.entry.future_publish_date.setMinutes(this.minutes);
996
- this.onChange();
997
- }
998
- }
999
- EntryCreatorComponent.CURRENT_ENTRY = 'current_entry';
1000
- EntryCreatorComponent.DEFAULT_NEW_ENTRY_TITLE = 'A New Entry';
1001
- EntryCreatorComponent.decorators = [
1002
- { type: Component, args: [{
1003
- selector: 'app-entry-creator',
1004
- 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-list #tagList aria-label=\"Tags\">\n <mat-chip\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>\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-list>\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",
1005
- styles: [".creator{min-height:calc(100vh - 100px)}form{padding:20px}.content{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}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;padding:10px;width:100%}[hidden]{display:none!important}"]
1006
- },] }
1007
- ];
1008
- EntryCreatorComponent.ctorParameters = () => [
1009
- { type: EntryService },
1010
- { type: TagService },
1011
- { type: IdentityService },
1012
- { type: ChangeDetectorRef },
1013
- { type: MatDialog }
1014
- ];
1015
- EntryCreatorComponent.propDecorators = {
1016
- tagInput: [{ type: ViewChild, args: ['tagInput',] }],
1017
- matAutocomplete: [{ type: ViewChild, args: ['tagauto',] }],
1018
- allowedMimeTypes: [{ type: Input }],
1019
- uploadUrlKey: [{ type: Input }]
1020
- };
1021
-
1022
- class EntryRendererComponent {
1023
- constructor(prismService, ngZone, identityService, commentService, router, entryService) {
1024
- this.prismService = prismService;
1025
- this.ngZone = ngZone;
1026
- this.identityService = identityService;
1027
- this.commentService = commentService;
1028
- this.router = router;
1029
- this.entryService = entryService;
1030
- this.ContentType = ContentType;
1031
- this.comments = [];
1032
- this.commentText = '';
1033
- this.alert = alert;
1034
- this.editMode = false;
1035
- }
1036
- ngOnInit() {
1037
- this.identityService.getMe().subscribe((me) => {
1038
- this.me = me;
1039
- });
1040
- this.commentService.getComments(this.entry.id).subscribe((response) => {
1041
- this.comments = response.results;
1042
- for (const comment of this.comments) {
1043
- comment.date_obj = new Date(comment.created_on);
1044
- }
1045
- });
1046
- }
1047
- ngAfterViewChecked() {
1048
- if (!this.editMode) {
1049
- this.ngZone.runOutsideAngular(() => {
1050
- try {
1051
- this.prismService.highlightAll();
1052
- }
1053
- catch (e) {
1054
- }
1055
- });
1056
- }
1057
- }
1058
- edit(entry) {
1059
- entry.version++;
1060
- entry.published = false;
1061
- delete entry.publish_date;
1062
- this.entryService.create(entry).subscribe((response) => {
1063
- localStorage.setItem(EntryCreatorComponent.CURRENT_ENTRY, JSON.stringify(response));
1064
- this.router.navigateByUrl('create(left-col:create//right-col:create)').then(() => {
1065
- });
1066
- });
1067
- }
1068
- postComment(e) {
1069
- e.preventDefault();
1070
- if (this.commentText !== '') {
1071
- this.commentService.postComment({ entry: this.entry.id, content: this.commentText }).subscribe((comment) => {
1072
- this.comments.push(comment);
1073
- });
1074
- this.commentText = '';
1075
- }
1076
- }
1077
- mediaIsZip(content) {
1078
- let mediaIsZip = false;
1079
- if (content.additional) {
1080
- for (const add of content.additional) {
1081
- if (add.key === Content.KEY_MIMETYPE) {
1082
- if (add.value === 'application/zip') {
1083
- mediaIsZip = true;
1084
- }
1085
- }
1086
- }
1087
- }
1088
- return mediaIsZip;
1089
- }
1090
- approve(comment) {
1091
- comment.approved = !comment.approved;
1092
- this.commentService.patchComment(Object.assign({}, { approved: true }, comment)).subscribe((rComment) => {
1093
- });
1094
- }
1095
- unapprove(comment) {
1096
- comment.approved = !comment.approved;
1097
- this.commentService.patchComment(Object.assign({}, { approved: false }, comment)).subscribe((rComment) => {
1098
- });
1099
- }
1100
- }
1101
- EntryRendererComponent.decorators = [
1102
- { type: Component, args: [{
1103
- selector: 'app-entry-renderer',
1104
- template: "<div>\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",
1105
- styles: [".image{justify-content:center;text-align:center;width:100%}.description,.source{font-size:12px;text-align:center}.gravatar{margin-right:20px}.smaller{text-color:grey;text-size:12px}"]
1106
- },] }
1107
- ];
1108
- EntryRendererComponent.ctorParameters = () => [
1109
- { type: PrismService },
1110
- { type: NgZone },
1111
- { type: IdentityService },
1112
- { type: CommentService },
1113
- { type: Router },
1114
- { type: EntryService }
1115
- ];
1116
- EntryRendererComponent.propDecorators = {
1117
- entry: [{ type: Input }],
1118
- editMode: [{ type: Input }]
1119
- };
1120
-
1121
- class EntrySummaryComponent {
1122
- constructor(router) {
1123
- this.router = router;
1124
- this.ContentType = ContentType;
1125
- }
1126
- ngOnInit() {
1127
- }
1128
- routeTo(entry) {
1129
- this.router.navigate(['/', 'blog', entry.slug]).then(() => {
1130
- });
1131
- }
1132
- }
1133
- EntrySummaryComponent.decorators = [
1134
- { type: Component, args: [{
1135
- selector: 'app-entry-summary',
1136
- 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",
1137
- styles: [".entry{border-bottom:1px solid rgba(0,0,0,.12);padding:20px}"]
1138
- },] }
1139
- ];
1140
- EntrySummaryComponent.ctorParameters = () => [
1141
- { type: Router }
1142
- ];
1143
- EntrySummaryComponent.propDecorators = {
1144
- entry: [{ type: Input }]
1145
- };
1146
-
1147
- class JsonRendererComponent {
1148
- constructor(entryService) {
1149
- this.entryService = entryService;
1150
- this.JSON = JSON;
1151
- this.entry = new Entry();
1152
- }
1153
- ngOnInit() {
1154
- this.entryService.currentlyEditedEntry.subscribe((entry) => {
1155
- this.entry = entry;
1156
- });
1157
- }
1158
- }
1159
- JsonRendererComponent.decorators = [
1160
- { type: Component, args: [{
1161
- selector: 'app-json-renderer',
1162
- template: "<div class=\"section json-render json\">\n <app-entry-renderer [editMode]=\"true\" [entry]=\"entry\"></app-entry-renderer>\n <pre>{{JSON.stringify(entry)}}</pre>\n</div>\n",
1163
- styles: [".json pre{white-space:pre-wrap;word-wrap:anywhere}.json-render{padding:0 20px}"]
1164
- },] }
1165
- ];
1166
- JsonRendererComponent.ctorParameters = () => [
1167
- { type: EntryService }
1168
- ];
1169
- JsonRendererComponent.propDecorators = {
1170
- entry: [{ type: Input }]
1171
- };
1172
-
1173
- class LandingPageComponent {
1174
- constructor(router, entryService) {
1175
- this.router = router;
1176
- this.entryService = entryService;
1177
- this.JSON = JSON;
1178
- }
1179
- ngOnInit() {
1180
- this.entryService.get().subscribe((response) => {
1181
- this.entries = map$1(response.results.slice(0, 3), (result) => {
1182
- return { id: result.id, entry: new Entry(result) };
1183
- });
1184
- });
1185
- }
1186
- ngOnDestroy() {
1187
- if (this.sourceSub) {
1188
- this.sourceSub.unsubscribe();
1189
- this.sourceSub = null;
1190
- }
1191
- }
1192
- }
1193
- LandingPageComponent.decorators = [
1194
- { type: Component, args: [{
1195
- selector: 'app-landing-page',
1196
- 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",
1197
- styles: [".landing-page{max-height:calc(100vh - 100px);min-height:calc(100vh - 100px)}@media screen and (max-height:560px){.landing-page{max-height:100vh}}"]
1198
- },] }
1199
- ];
1200
- LandingPageComponent.ctorParameters = () => [
1201
- { type: Router },
1202
- { type: EntryService }
1203
- ];
1204
-
1205
- class OutlineViewComponent {
1206
- constructor(entryService) {
1207
- this.entryService = entryService;
1208
- this.entry = new Entry();
1209
- this.Math = Math;
1210
- }
1211
- ngOnInit() {
1212
- this.entryService.currentlyEditedEntry.subscribe((entry) => {
1213
- this.entry = entry;
1214
- });
1215
- }
1216
- sectionDrop(e) {
1217
- const entry = this.entry;
1218
- const diff = e.currentIndex - e.previousIndex;
1219
- entry.sections[e.previousIndex].order = e.currentIndex * 10 + (diff > 0 ? 1 : -1);
1220
- entry.sort();
1221
- this.entryService.currentlyEditedEntry.next(this.entry);
1222
- }
1223
- contentDrop(e, section) {
1224
- const entry = this.entry;
1225
- const diff = e.currentIndex - e.previousIndex;
1226
- section.contents[e.previousIndex].order = e.currentIndex * 10 + (diff > 0 ? 1 : -1);
1227
- entry.sort();
1228
- this.entryService.currentlyEditedEntry.next(this.entry);
1229
- }
1230
- }
1231
- OutlineViewComponent.decorators = [
1232
- { type: Component, args: [{
1233
- selector: 'app-outline-view',
1234
- template: "<div 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",
1235
- styles: [".outline{padding:0 20px}.content{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.card,.content-card{cursor:pointer;margin:4px}.content-card:not(:last-child){border-bottom:1px dotted #aaa}.custom-placeholder{min-height:60px}.content-placeholder,.custom-placeholder{background:#ccc;border:3px dotted #999;transition:transform .25s cubic-bezier(0,0,.2,1)}.content-placeholder{min-height:30px}"]
1236
- },] }
1237
- ];
1238
- OutlineViewComponent.ctorParameters = () => [
1239
- { type: EntryService }
1240
- ];
1241
-
1242
- class SideNavigationComponent {
1243
- constructor(entryService, router, identityService) {
1244
- this.entryService = entryService;
1245
- this.router = router;
1246
- this.identityService = identityService;
1247
- this.entries = [];
1248
- this.entriesByMonthAndYear = [];
1249
- }
1250
- ngOnInit() {
1251
- this.identityService.getMe().subscribe((identity) => {
1252
- this.identity = identity;
1253
- }, (err) => {
1254
- this.identity = null;
1255
- });
1256
- this.getEntries();
1257
- }
1258
- getEntriesWithUrl(url) {
1259
- this.entryService.getListByUrl(url).subscribe((response) => {
1260
- this.entries = this.entries.concat(map$1(response.results, (result) => {
1261
- return { id: result.id, entry: new Entry(result) };
1262
- }));
1263
- if (response.next) {
1264
- this.getEntriesWithUrl(response.next);
1265
- }
1266
- else {
1267
- this.organizeEntries();
1268
- }
1269
- });
1270
- }
1271
- organizeEntries() {
1272
- for (const entryWrapper of this.entries) {
1273
- const entry = entryWrapper.entry;
1274
- const create_date = new Date(entry.create_date);
1275
- const month = create_date.getMonth();
1276
- const year = create_date.getFullYear();
1277
- const key = month + '/' + year;
1278
- const sort_index = (year * 100) + month;
1279
- const containers = filter(this.entriesByMonthAndYear, (entryContainer) => entryContainer.month_year === key);
1280
- if (containers.length > 0) {
1281
- const container = containers[0];
1282
- const entriesWithId = filter(container.entries, (e) => e.id === entryWrapper.entry.id);
1283
- if (entriesWithId.length === 0) {
1284
- container.entries.push(entry);
1285
- }
1286
- }
1287
- else {
1288
- const newContainer = { month_year: key, month_year_number: sort_index, entries: [entry] };
1289
- this.entriesByMonthAndYear.push(newContainer);
1290
- }
1291
- }
1292
- this.entriesByMonthAndYear.sort((entry_a, entry_b) => {
1293
- return entry_a.month_year_number - entry_b.month_year_number;
1294
- });
1295
- this.entriesByMonthAndYear.reverse();
1296
- }
1297
- getEntries() {
1298
- this.entryService.get().subscribe((response) => {
1299
- this.entries = map$1(response.results, (result) => {
1300
- return { id: result.id, entry: new Entry(result) };
1301
- });
1302
- if (response.next) {
1303
- this.getEntriesWithUrl(response.next);
1304
- }
1305
- else {
1306
- this.organizeEntries();
1307
- }
1308
- });
1309
- }
1310
- render() {
1311
- }
1312
- routeTo(entry) {
1313
- if (!entry) {
1314
- this.router.navigateByUrl('create(left-col:create//right-col:create)').then(() => {
1315
- });
1316
- }
1317
- else {
1318
- this.router.navigate(['/', 'blog', entry.slug]).then(() => {
1319
- // Noop
1320
- });
1321
- }
1322
- }
1323
- getMonthAndYearFromKey(key) {
1324
- let subheading = '';
1325
- const parts = key.split('/');
1326
- switch (Number(parts[0])) {
1327
- case 0:
1328
- subheading += 'January ';
1329
- break;
1330
- case 1:
1331
- subheading += 'February ';
1332
- break;
1333
- case 2:
1334
- subheading += 'March ';
1335
- break;
1336
- case 3:
1337
- subheading += 'April ';
1338
- break;
1339
- case 4:
1340
- subheading += 'May ';
1341
- break;
1342
- case 5:
1343
- subheading += 'June ';
1344
- break;
1345
- case 6:
1346
- subheading += 'July ';
1347
- break;
1348
- case 7:
1349
- subheading += 'August ';
1350
- break;
1351
- case 8:
1352
- subheading += 'September ';
1353
- break;
1354
- case 9:
1355
- subheading += 'October ';
1356
- break;
1357
- case 10:
1358
- subheading += 'November ';
1359
- break;
1360
- case 11:
1361
- subheading += 'December ';
1362
- break;
1363
- default:
1364
- subheading += 'January ';
1365
- }
1366
- subheading += parts[1];
1367
- return subheading;
1368
- }
1369
- ngOnDestroy() {
1370
- if (this.sourceSub) {
1371
- this.sourceSub.unsubscribe();
1372
- this.sourceSub = null;
1373
- }
1374
- }
1375
- }
1376
- SideNavigationComponent.decorators = [
1377
- { type: Component, args: [{
1378
- selector: 'app-side-navigation',
1379
- template: "<div class=\"sidenav no-scrollbar\">\n <mat-nav-list *ngFor=\"let container of entriesByMonthAndYear\">\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 <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",
1380
- styles: [".sidenav{max-height:calc(100vh - 100px)}@media screen and (max-height:560px){.sidenav{max-height:100vh}}h2,h3{justify-content:right;margin-left:10px}"]
1381
- },] }
1382
- ];
1383
- SideNavigationComponent.ctorParameters = () => [
1384
- { type: EntryService },
1385
- { type: Router },
1386
- { type: IdentityService }
1387
- ];
1388
-
1389
- class StaticHtmlComponent {
1390
- constructor(staticHtmlService, domSanitizer) {
1391
- this.staticHtmlService = staticHtmlService;
1392
- this.domSanitizer = domSanitizer;
1393
- }
1394
- refreshContent() {
1395
- this.innerHtml = this.domSanitizer.bypassSecurityTrustHtml(this.staticHtmlService.mapStaticHtml(this.value, false));
1396
- }
1397
- ngOnChanges(changes) {
1398
- this.refreshContent();
1399
- }
1400
- ngOnInit() {
1401
- this.refreshContent();
1402
- }
1403
- }
1404
- StaticHtmlComponent.decorators = [
1405
- { type: Component, args: [{
1406
- selector: 'app-static-html',
1407
- template: "<div [innerHtml]=\"innerHtml\">\n</div>\n",
1408
- styles: [""]
1409
- },] }
1410
- ];
1411
- StaticHtmlComponent.ctorParameters = () => [
1412
- { type: StaticHtmlService },
1413
- { type: DomSanitizer }
1414
- ];
1415
- StaticHtmlComponent.propDecorators = {
1416
- value: [{ type: Input }]
1417
- };
1418
-
1419
- class MainComponent {
1420
- constructor(router) {
1421
- this.router = router;
1422
- this.loaded = true;
1423
- this.subs = new Subscription();
1424
- this.resizeSubject = new Subject();
1425
- }
1426
- ngOnInit() {
1427
- this.subs.add(this.router.events.subscribe((e) => {
1428
- if (e instanceof NavigationEnd) {
1429
- if (e.urlAfterRedirects.includes('create')) {
1430
- this.showLeftCol = true;
1431
- this.showRightCol = true;
1432
- }
1433
- else {
1434
- this.showLeftCol = true;
1435
- this.showRightCol = false;
1436
- this.innerWidth = window.innerWidth;
1437
- this.collapseLeftColIfTooNarrow();
1438
- }
1439
- }
1440
- }));
1441
- this.subs.add(this.resizeSubject.pipe(debounceTime(100)).subscribe((width) => {
1442
- this.innerWidth = width;
1443
- this.collapseLeftColIfTooNarrow();
1444
- }));
1445
- }
1446
- collapseLeftColIfTooNarrow() {
1447
- this.showLeftCol = this.innerWidth >= 800;
1448
- }
1449
- onResize(event) {
1450
- this.resizeSubject.next(window.innerWidth);
1451
- }
1452
- ngOnDestroy() {
1453
- this.subs.unsubscribe();
1454
- }
1455
- }
1456
- MainComponent.decorators = [
1457
- { type: Component, args: [{
1458
- selector: 'lib-main',
1459
- 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",
1460
- 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{max-width:33vw;min-width:400px}.left-toggle{left:5px}.left-toggle,.right-toggle{position:fixed;top:50%;z-index:100}.right-toggle{right:5px}a{margin-right:10px;&:not(:last-child):after{content:\"|\";margin-left:10px}}"]
1461
- },] }
1462
- ];
1463
- MainComponent.ctorParameters = () => [
1464
- { type: Router }
1465
- ];
1466
- MainComponent.propDecorators = {
1467
- onResize: [{ type: HostListener, args: ['window:resize', ['$event'],] }]
1468
- };
1469
-
1470
- class EntryRendererWrapperComponent {
1471
- constructor(entryService, router, route, viewService, interactionService) {
1472
- this.entryService = entryService;
1473
- this.router = router;
1474
- this.route = route;
1475
- this.viewService = viewService;
1476
- this.interactionService = interactionService;
1477
- this.seeAllEntries = false;
1478
- }
1479
- seeAll(toggle) {
1480
- this.seeAllEntries = toggle;
1481
- }
1482
- getEntry() {
1483
- const slug = this.route.snapshot.paramMap.get('slug');
1484
- if (slug) {
1485
- this.entryService.getBySlug(slug).subscribe((response) => {
1486
- this.currentEntry = response;
1487
- const view = new View();
1488
- view.entry = this.currentEntry.id;
1489
- this.viewService.create(view).subscribe((viewResponse) => {
1490
- // Noop
1491
- });
1492
- });
1493
- }
1494
- this.route.queryParams.subscribe(params => {
1495
- const campaign = params['campaign'];
1496
- if (campaign && campaign !== '') {
1497
- const interaction = new Interaction();
1498
- interaction.content = { 'campaign': campaign, slug };
1499
- this.interactionService.create(interaction).subscribe((response) => {
1500
- });
1501
- setTimeout(() => {
1502
- const urlMinsCampaign = this.router.url.replace(new RegExp('.campaign=' + campaign), '');
1503
- this.router.navigateByUrl(urlMinsCampaign);
1504
- }, 0);
1505
- }
1506
- });
1507
- }
1508
- ngOnInit() {
1509
- this.routerSub = this.router.events.subscribe((e) => {
1510
- if (e instanceof NavigationEnd) {
1511
- this.currentEntry = null;
1512
- this.seeAll(false);
1513
- setTimeout(() => {
1514
- this.getEntry();
1515
- }, 10);
1516
- }
1517
- });
1518
- this.getEntry();
1519
- }
1520
- ngOnDestroy() {
1521
- if (this.routerSub) {
1522
- this.routerSub.complete();
1523
- this.routerSub = null;
1524
- }
1525
- }
1526
- }
1527
- EntryRendererWrapperComponent.decorators = [
1528
- { type: Component, args: [{
1529
- selector: 'lib-entry-renderer-wrapper',
1530
- template: "<div class=\"rendered-entry section\">\n <app-entry-renderer *ngIf=\"currentEntry\" [entry]=\"currentEntry\"></app-entry-renderer>\n</div>\n",
1531
- styles: [".rendered-entry{padding:0 20px}"]
1532
- },] }
1533
- ];
1534
- EntryRendererWrapperComponent.ctorParameters = () => [
1535
- { type: EntryService },
1536
- { type: Router },
1537
- { type: ActivatedRoute },
1538
- { type: ViewService },
1539
- { type: InteractionService }
1540
- ];
1541
-
1542
- class LinkyPipe {
1543
- transform(value, options) {
1544
- return Autolinker.link(value, Object.assign({}, options, { newWindow: true, stripPrefix: false }));
1545
- }
1546
- }
1547
- LinkyPipe.decorators = [
1548
- { type: Pipe, args: [{ name: 'linky' },] }
1549
- ];
1550
-
1551
- class TimeAgoPipe {
1552
- constructor(changeDetectorRef, ngZone) {
1553
- this.changeDetectorRef = changeDetectorRef;
1554
- this.ngZone = ngZone;
1555
- }
1556
- transform(value) {
1557
- this.removeTimer();
1558
- let d = new Date(value);
1559
- let now = new Date();
1560
- let seconds = Math.round(Math.abs((now.getTime() - d.getTime()) / 1000));
1561
- let timeToUpdate = (Number.isNaN(seconds)) ? 1000 : this.getSecondsUntilUpdate(seconds) * 1000;
1562
- this.timer = this.ngZone.runOutsideAngular(() => {
1563
- if (typeof window !== 'undefined') {
1564
- return window.setTimeout(() => {
1565
- this.ngZone.run(() => this.changeDetectorRef.markForCheck());
1566
- }, timeToUpdate);
1567
- }
1568
- return null;
1569
- });
1570
- let minutes = Math.round(Math.abs(seconds / 60));
1571
- let hours = Math.round(Math.abs(minutes / 60));
1572
- let days = Math.round(Math.abs(hours / 24));
1573
- let months = Math.round(Math.abs(days / 30.416));
1574
- let years = Math.round(Math.abs(days / 365));
1575
- if (Number.isNaN(seconds)) {
1576
- return '';
1577
- }
1578
- else if (seconds <= 45) {
1579
- return 'a few seconds ago';
1580
- }
1581
- else if (seconds <= 90) {
1582
- return 'a minute ago';
1583
- }
1584
- else if (minutes <= 45) {
1585
- return minutes + ' minutes ago';
1586
- }
1587
- else if (minutes <= 90) {
1588
- return 'an hour ago';
1589
- }
1590
- else if (hours <= 22) {
1591
- return hours + ' hours ago';
1592
- }
1593
- else if (hours <= 36) {
1594
- return 'a day ago';
1595
- }
1596
- else if (days <= 25) {
1597
- return days + ' days ago';
1598
- }
1599
- else if (days <= 45) {
1600
- return 'a month ago';
1601
- }
1602
- else if (days <= 345) {
1603
- return months + ' months ago';
1604
- }
1605
- else if (days <= 545) {
1606
- return 'a year ago';
1607
- }
1608
- else { // (days > 545)
1609
- return years + ' years ago';
1610
- }
1611
- }
1612
- ngOnDestroy() {
1613
- this.removeTimer();
1614
- }
1615
- removeTimer() {
1616
- if (this.timer) {
1617
- window.clearTimeout(this.timer);
1618
- this.timer = null;
1619
- }
1620
- }
1621
- getSecondsUntilUpdate(seconds) {
1622
- let min = 60;
1623
- let hr = min * 60;
1624
- let day = hr * 24;
1625
- if (seconds < min) { // less than 1 min, update every 2 secs
1626
- return 2;
1627
- }
1628
- else if (seconds < hr) { // less than an hour, update every 30 secs
1629
- return 30;
1630
- }
1631
- else if (seconds < day) { // less then a day, update every 5 mins
1632
- return 300;
1633
- }
1634
- else { // update every hour
1635
- return 3600;
1636
- }
1637
- }
1638
- }
1639
- TimeAgoPipe.decorators = [
1640
- { type: Pipe, args: [{
1641
- name: 'timeAgo',
1642
- pure: false
1643
- },] }
1644
- ];
1645
- TimeAgoPipe.ctorParameters = () => [
1646
- { type: ChangeDetectorRef },
1647
- { type: NgZone }
1648
- ];
1649
-
1650
- const routes = [
1651
- { path: '', component: SideNavigationComponent, outlet: 'left-col' },
1652
- {
1653
- path: 'landing',
1654
- component: MainComponent
1655
- },
1656
- { path: 'blog/:slug', component: EntryRendererWrapperComponent },
1657
- { path: 'create', component: EntryCreatorComponent },
1658
- { path: 'create', component: OutlineViewComponent, outlet: 'left-col' },
1659
- { path: 'create', component: JsonRendererComponent, outlet: 'right-col' },
1660
- { path: '', redirectTo: '/landing', pathMatch: 'full' },
1661
- { path: '**', redirectTo: '/404error' }
1662
- ];
1663
- class Routes {
1664
- constructor() {
1665
- this.routes = routes;
1666
- }
1667
- }
1668
-
1669
- class SchedulePublishDialogData {
1670
- }
1671
-
1672
- class SchedulePublishDialogComponent {
1673
- constructor(dialogRef, data) {
1674
- this.dialogRef = dialogRef;
1675
- this.data = data;
1676
- }
1677
- ngOnInit() {
1678
- }
1679
- onNoClick() {
1680
- }
1681
- onYesClick() {
1682
- this.dialogRef.close('test');
1683
- }
1684
- }
1685
- SchedulePublishDialogComponent.decorators = [
1686
- { type: Component, args: [{
1687
- selector: 'lib-schedule-publish-dialog',
1688
- 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",
1689
- styles: [""]
1690
- },] }
1691
- ];
1692
- SchedulePublishDialogComponent.ctorParameters = () => [
1693
- { type: MatDialogRef },
1694
- { type: SchedulePublishDialogData, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
1695
- ];
1696
-
1697
- class CoreModule {
1698
- constructor(library) {
1699
- this.library = library;
1700
- this.library.addIcons(faSpinner);
1701
- }
1702
- }
1703
- CoreModule.decorators = [
1704
- { type: NgModule, args: [{
1705
- declarations: [
1706
- EntryRendererComponent,
1707
- EntryCreatorComponent,
1708
- LandingPageComponent,
1709
- SideNavigationComponent,
1710
- OutlineViewComponent,
1711
- JsonRendererComponent,
1712
- EntrySummaryComponent,
1713
- EntrySelectorDialogComponent,
1714
- MediaUploadModalComponent,
1715
- TimeAgoPipe,
1716
- LinkyPipe,
1717
- StaticHtmlComponent,
1718
- MainComponent,
1719
- EntryRendererWrapperComponent,
1720
- SchedulePublishDialogComponent,
1721
- ],
1722
- imports: [
1723
- CommonModule,
1724
- RouterModule,
1725
- FormsModule,
1726
- ReactiveFormsModule,
1727
- DragDropModule,
1728
- MatCardModule,
1729
- MatSidenavModule,
1730
- MatButtonModule,
1731
- MatInputModule,
1732
- MatListModule,
1733
- MatRadioModule,
1734
- MatDialogModule,
1735
- MatCheckboxModule,
1736
- MatDividerModule,
1737
- MatAutocompleteModule,
1738
- MatChipsModule,
1739
- MatIconModule,
1740
- MatDatepickerModule,
1741
- MatNativeDateModule,
1742
- FontAwesomeModule,
1743
- FileUploadModule,
1744
- NgxMaterialTimepickerModule,
1745
- ],
1746
- providers: [
1747
- CommentService,
1748
- EntryService,
1749
- UploadService,
1750
- PrismService,
1751
- IdentityService,
1752
- DjangoRestFrameworkEndpointService,
1753
- TagService,
1754
- ],
1755
- exports: [
1756
- EntryRendererComponent,
1757
- EntryCreatorComponent,
1758
- LandingPageComponent,
1759
- SideNavigationComponent,
1760
- OutlineViewComponent,
1761
- JsonRendererComponent,
1762
- EntrySummaryComponent,
1763
- EntrySelectorDialogComponent,
1764
- MediaUploadModalComponent,
1765
- TimeAgoPipe,
1766
- LinkyPipe,
1767
- StaticHtmlComponent,
1768
- MainComponent,
1769
- EntryRendererWrapperComponent,
1770
- ]
1771
- },] }
1772
- ];
1773
- CoreModule.ctorParameters = () => [
1774
- { type: FaIconLibrary }
1775
- ];
1776
-
1777
- /*
1778
- * Public API Surface of core
1779
- */
1780
-
1781
- /**
1782
- * Generated bundle index. Do not edit.
1783
- */
1784
-
1785
- 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, EntrySelectorDialogData as ɵa, SchedulePublishDialogComponent as ɵb, SchedulePublishDialogData as ɵc };
1786
- //# sourceMappingURL=thecodeblogs-blog.js.map