@sumaris-net/ngx-components 18.13.0 → 18.14.1

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 (38) hide show
  1. package/doc/changelog.md +4 -0
  2. package/doc/feed/feed-en.json +26 -0
  3. package/doc/feed/feed-fr.json +26 -0
  4. package/esm2022/public_api.mjs +9 -1
  5. package/esm2022/src/app/core/home/home.mjs +13 -12
  6. package/esm2022/src/app/core/home/home.module.mjs +7 -3
  7. package/esm2022/src/app/core/services/local-settings.service.mjs +3 -2
  8. package/esm2022/src/app/core/services/network.service.mjs +12 -1
  9. package/esm2022/src/app/social/feed/discourse/discourse-feed.service.mjs +179 -0
  10. package/esm2022/src/app/social/feed/discourse/discourse.model.mjs +2 -0
  11. package/esm2022/src/app/social/feed/discourse/discourse.utils.mjs +168 -0
  12. package/esm2022/src/app/social/feed/feed.component.mjs +121 -0
  13. package/esm2022/src/app/social/feed/feed.directive.mjs +151 -0
  14. package/esm2022/src/app/social/feed/feed.model.mjs +68 -0
  15. package/esm2022/src/app/social/feed/feed.module.mjs +22 -0
  16. package/esm2022/src/app/social/feed/feed.service.mjs +3 -0
  17. package/esm2022/src/environments/environment.class.mjs +2 -1
  18. package/esm2022/src/environments/environment.mjs +10 -1
  19. package/fesm2022/sumaris-net.ngx-components.mjs +681 -8
  20. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  21. package/package.json +1 -1
  22. package/public_api.d.ts +8 -0
  23. package/src/app/core/home/home.d.ts +1 -1
  24. package/src/app/core/home/home.module.d.ts +2 -1
  25. package/src/app/core/services/local-settings.service.d.ts +1 -0
  26. package/src/app/core/services/network.service.d.ts +1 -0
  27. package/src/app/social/feed/discourse/discourse-feed.service.d.ts +55 -0
  28. package/src/app/social/feed/discourse/discourse.model.d.ts +7 -0
  29. package/src/app/social/feed/discourse/discourse.utils.d.ts +44 -0
  30. package/src/app/social/feed/feed.component.d.ts +39 -0
  31. package/src/app/social/feed/feed.directive.d.ts +32 -0
  32. package/src/app/social/feed/feed.model.d.ts +69 -0
  33. package/src/app/social/feed/feed.module.d.ts +11 -0
  34. package/src/app/social/feed/feed.service.d.ts +13 -0
  35. package/src/assets/i18n/en-US.json +5 -1
  36. package/src/assets/i18n/en.json +5 -0
  37. package/src/assets/i18n/fr.json +5 -0
  38. package/src/environments/environment.class.d.ts +8 -0
@@ -0,0 +1,168 @@
1
+ import DiscourseAPI from 'discourse2';
2
+ import { Promise } from '@rx-angular/cdk/zone-less/browser';
3
+ import { JsonFeedUtils } from '../feed.model';
4
+ import { UrlUtils } from '../../../shared/file/url.utils';
5
+ import { isEmptyArray, isNotNil } from '../../../shared/functions';
6
+ import { DateUtils } from '../../../shared/dates';
7
+ export class DiscourseUtils {
8
+ static _logPrefix = '[discourse-utils]';
9
+ static removeJsonExtension = JsonFeedUtils.removeJsonExtension;
10
+ static isDiscourseObject(json) {
11
+ return this.isDiscourseTopic(json) || this.isDiscourseCategory(json);
12
+ }
13
+ static isDiscourseTopic(json) {
14
+ return (json && !!json.post_stream?.posts && json.fancy_title && json.slug && json.details?.created_by && true) || false;
15
+ }
16
+ static isDiscourseCategory(json) {
17
+ return (json && json.topic_list?.topics && json.posters && true) || false;
18
+ }
19
+ static getDiscourseBaseUrl(url) {
20
+ return UrlUtils.getRootUrl(url);
21
+ }
22
+ static isDiscourseCategoryUrl(url) {
23
+ const baseUrl = this.getDiscourseBaseUrl(url);
24
+ return baseUrl && url.substring(baseUrl.length).match(/^\/c\//);
25
+ }
26
+ static extractCategoryIdFromUrl(url) {
27
+ const match = this.removeJsonExtension(url).match(/\/(\d+)$/);
28
+ return match ? parseInt(match[1], 10) : null;
29
+ }
30
+ static extractCategorySlugFromUrl(url) {
31
+ const match = this.removeJsonExtension(url).match(/\/c\/([\w/-]+)\/\d+$/);
32
+ return match ? match[1] : null;
33
+ }
34
+ static extractTopicIdFromUrl(url) {
35
+ const match = url.match(/\/(\d+)(?:$|\/)/) || url.match(/\/(\d+)\.json$/);
36
+ return match ? parseInt(match[1], 10) : null;
37
+ }
38
+ static getLanguageFromTitle(title) {
39
+ if (!title)
40
+ return '';
41
+ const match = title.match('\\s\\(([a-z]{2}(?:-[A-Z]{2})?)\\)$');
42
+ return match && match[1];
43
+ }
44
+ static async getFeedsByUrl(url, opts) {
45
+ try {
46
+ // Check a category
47
+ if (DiscourseUtils.isDiscourseCategoryUrl(url)) {
48
+ console.debug(`${this._logPrefix}Detected a Discourse category at: ${url}`);
49
+ return this.getFeedsByCategoryUrl(url, opts);
50
+ }
51
+ // Or a topic
52
+ else {
53
+ const post = await this.getFeedByTopicUrl(url, opts);
54
+ return post ? [post] : [];
55
+ }
56
+ }
57
+ catch (err) {
58
+ console.error(`${this._logPrefix}`, err);
59
+ return [];
60
+ }
61
+ }
62
+ static async getFeedsByCategoryUrl(url, opts) {
63
+ const categoryId = this.extractCategoryIdFromUrl(url);
64
+ const categorySlug = this.extractCategorySlugFromUrl(url);
65
+ const baseUrl = this.getDiscourseBaseUrl(url);
66
+ const api = opts?.api ?? new DiscourseAPI(baseUrl);
67
+ const category = await api.listCategoryTopics({ id: categoryId, slug: categorySlug });
68
+ const topics = (category?.topic_list?.topics || []).filter((topic) => {
69
+ const topicLocale = this.getLanguageFromTitle(topic.fancy_title);
70
+ return (topic.pinned &&
71
+ topic.visible &&
72
+ // Keep same locale, if exists
73
+ (!topicLocale || !opts?.locale || topicLocale === opts.locale));
74
+ });
75
+ const posts = (await Promise.all(topics.map(async (t) => {
76
+ const topic = await api.getTopic({ id: t.id.toString() });
77
+ // Ignore 'About' topics
78
+ if (topic.tags.includes('about-category'))
79
+ return undefined;
80
+ const posts = this.filterRecentPosts(topic.post_stream.posts, opts);
81
+ if (isEmptyArray(posts))
82
+ return undefined;
83
+ return this.toFeed(posts, topic, url, opts);
84
+ }))).filter(isNotNil);
85
+ if (isEmptyArray(posts)) {
86
+ console.warn(`${this._logPrefix}No recent post found on category #${categoryId}`);
87
+ }
88
+ return posts;
89
+ }
90
+ static async getFeedByTopicUrl(url, opts) {
91
+ const topicId = this.extractTopicIdFromUrl(url);
92
+ if (!topicId) {
93
+ console.error(`${this._logPrefix}Invalid URL`);
94
+ return undefined;
95
+ }
96
+ const api = opts?.api ?? new DiscourseAPI(this.getDiscourseBaseUrl(url));
97
+ const topic = await api.getTopic({ id: topicId.toString() });
98
+ // Ignore about category
99
+ if (topic.tags?.includes('about-category'))
100
+ return undefined;
101
+ const posts = this.filterRecentPosts(topic.post_stream.posts, opts);
102
+ if (isEmptyArray(posts)) {
103
+ console.warn(`${this._logPrefix}No recent posts found in topic #${topicId}`);
104
+ return undefined;
105
+ }
106
+ return this.toFeed(posts, topic, url, opts);
107
+ }
108
+ static filterRecentPosts(posts, opts) {
109
+ const maxAgeInMonths = opts?.maxAgeInMonths ?? JsonFeedUtils.DEFAULT_MAX_POST_AGE_IN_MONTHS;
110
+ if (maxAgeInMonths <= 0)
111
+ return posts; // Accept all
112
+ const minDate = maxAgeInMonths > 0 ? DateUtils.moment().subtract(maxAgeInMonths, 'month').startOf('day').utc() : undefined;
113
+ return (posts || []).filter((post) => post && DateUtils.moment(post.created_at).isSameOrAfter(minDate));
114
+ }
115
+ static toFeed(posts, topic, url, opts) {
116
+ const baseUrl = this.getDiscourseBaseUrl(url);
117
+ const title = this.cleanTitle(topic.fancy_title ?? topic.title);
118
+ const items = (posts || []).map((post) => this.toFeedItem(post, topic, url, opts));
119
+ const firstItem = items?.[0];
120
+ if (firstItem)
121
+ firstItem.title = title;
122
+ const authorName = topic?.details?.created_by && (topic.details.created_by.name || topic.details.created_by.username);
123
+ const authorAvatar = baseUrl + topic.details.created_by.avatar_template.replace('{size}', '48');
124
+ return {
125
+ version: JsonFeedUtils.VERSION_1_1,
126
+ feed_url: url,
127
+ title: this.cleanTitle(topic.fancy_title),
128
+ expired: topic.archived,
129
+ authors: [
130
+ {
131
+ name: authorName,
132
+ avatar: authorAvatar,
133
+ },
134
+ ],
135
+ items,
136
+ tag_template: baseUrl + '/tag/{tag}',
137
+ };
138
+ }
139
+ static toFeedItem(post, topic, url, opts) {
140
+ const baseUrl = this.getDiscourseBaseUrl(url);
141
+ url = post.post_url ? baseUrl + post.post_url : url;
142
+ const id = post.post_url ? baseUrl + post.post_url : post.id;
143
+ const html = JsonFeedUtils.truncateHtml(post.cooked, opts);
144
+ const truncated = html?.length !== post.cooked?.length;
145
+ const authorName = post.name || post.username;
146
+ const authorAvatar = baseUrl + (post.avatar_template.replace('{size}', '48') ?? topic.details.last_poster.avatar_template.replace('{size}', '48'));
147
+ return {
148
+ id,
149
+ url,
150
+ authors: [
151
+ {
152
+ name: authorName,
153
+ avatar: authorAvatar,
154
+ },
155
+ ],
156
+ content_html: html,
157
+ date_published: post.created_at,
158
+ tags: topic.tags,
159
+ truncated,
160
+ };
161
+ }
162
+ static cleanTitle(title) {
163
+ if (!title)
164
+ return undefined;
165
+ return title.replace(/\s\([a-z]{2}(:?-[A-Z]{2})?\)$/, '');
166
+ }
167
+ }
168
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY291cnNlLnV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zb2NpYWwvZmVlZC9kaXNjb3Vyc2UvZGlzY291cnNlLnV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sWUFBWSxNQUFNLFlBQVksQ0FBQztBQUN0QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDNUQsT0FBTyxFQUEwQixhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzFELE9BQU8sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRWxELE1BQU0sT0FBZ0IsY0FBYztJQUNsQyxNQUFNLENBQUMsVUFBVSxHQUFHLG1CQUFtQixDQUFDO0lBRXhDLE1BQU0sQ0FBQyxtQkFBbUIsR0FBRyxhQUFhLENBQUMsbUJBQW1CLENBQUM7SUFFL0QsTUFBTSxDQUFDLGlCQUFpQixDQUFDLElBQVM7UUFDaEMsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBbUM7UUFDekQsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsVUFBVSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQztJQUMzSCxDQUFDO0lBRUQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLElBQXNDO1FBQy9E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QVcsQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ2hJLE9BQXFCO1lBQ25CLEVBQUU7WUFDRixHQUFHO1lBQ0gsT0FBTyxFQUFFO2dCQUNQO29CQUNFLElBQUksRUFBRSxVQUFVO29CQUNoQixNQUFNLEVBQUUsWUFBWTtpQkFDckI7YUFDRjtZQUNELFlBQVksRUFBRSxJQUFJO1lBQ2xCLGNBQWMsRUFBRSxJQUFJLENBQUMsVUFBVTtZQUMvQixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7WUFDaEIsU0FBUztTQUNWLENBQUM7SUFDSixDQUFDO0lBRUQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFhO1FBQzdCLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFDN0IsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLCtCQUErQixFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzVELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgRGlzY291cnNlQVBJIGZyb20gJ2Rpc2NvdXJzZTInO1xuaW1wb3J0IHsgUHJvbWlzZSB9IGZyb20gJ0ByeC1hbmd1bGFyL2Nkay96b25lLWxlc3MvYnJvd3Nlcic7XG5pbXBvcnQgeyBKc29uRmVlZCwgSnNvbkZlZWRJdGVtLCBKc29uRmVlZFV0aWxzIH0gZnJvbSAnLi4vZmVlZC5tb2RlbCc7XG5pbXBvcnQgeyBEaXNjb3Vyc2VDYXRlZ29yeSwgRGlzY291cnNlQ2F0ZWdvcnlUb3BpYywgRGlzY291cnNlUG9zdCwgRGlzY291cnNlVG9waWMgfSBmcm9tICcuL2Rpc2NvdXJzZS5tb2RlbCc7XG5pbXBvcnQgeyBVcmxVdGlscyB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC9maWxlL3VybC51dGlscyc7XG5pbXBvcnQgeyBpc0VtcHR5QXJyYXksIGlzTm90TmlsIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5pbXBvcnQgeyBEYXRlVXRpbHMgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZGF0ZXMnO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRGlzY291cnNlVXRpbHMge1xuICBzdGF0aWMgX2xvZ1ByZWZpeCA9ICdbZGlzY291cnNlLXV0aWxzXSc7XG5cbiAgc3RhdGljIHJlbW92ZUpzb25FeHRlbnNpb24gPSBKc29uRmVlZFV0aWxzLnJlbW92ZUpzb25FeHRlbnNpb247XG5cbiAgc3RhdGljIGlzRGlzY291cnNlT2JqZWN0KGpzb246IGFueSk6IGpzb24gaXMgRGlzY291cnNlVG9waWMgfCBEaXNjb3Vyc2VDYXRlZ29yeSB7XG4gICAgcmV0dXJuIHRoaXMuaXNEaXNjb3Vyc2VUb3BpYyhqc29uKSB8fCB0aGlzLmlzRGlzY291cnNlQ2F0ZWdvcnkoanNvbik7XG4gIH1cblxuICBzdGF0aWMgaXNEaXNjb3Vyc2VUb3BpYyhqc29uOiBhbnkgfCBQYXJ0aWFsPERpc2NvdXJzZVRvcGljPik6IGpzb24gaXMgRGlzY291cnNlVG9waWMge1xuICAgIHJldHVybiAoanNvbiAmJiAhIWpzb24ucG9zdF9zdHJlYW0/LnBvc3RzICYmIGpzb24uZmFuY3lfdGl0bGUgJiYganNvbi5zbHVnICYmIGpzb24uZGV0YWlscz8uY3JlYXRlZF9ieSAmJiB0cnVlKSB8fCBmYWxzZTtcbiAgfVxuXG4gIHN0YXRpYyBpc0Rpc2NvdXJzZUNhdGVnb3J5KGpzb246IGFueSB8IFBhcnRpYWw8RGlzY291cnNlQ2F0ZWdvcnk+KToganNvbiBpcyBEaXNjb3Vyc2VDYXRlZ29yeSB7XG4gICAgcmV0dXJuIChqc29uICYmIGpzb24udG9waWNfbGlzdD8udG9waWNzICYmIGpzb24ucG9zdGVycyAmJiB0cnVlKSB8fCBmYWxzZTtcbiAgfVxuXG4gIHN0YXRpYyBnZXREaXNjb3Vyc2VCYXNlVXJsKHVybDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIFVybFV0aWxzLmdldFJvb3RVcmwodXJsKTtcbiAgfVxuXG4gIHN0YXRpYyBpc0Rpc2NvdXJzZUNhdGVnb3J5VXJsKHVybDogc3RyaW5nKSB7XG4gICAgY29uc3QgYmFzZVVybCA9IHRoaXMuZ2V0RGlzY291cnNlQmFzZVVybCh1cmwpO1xuICAgIHJldHVybiBiYXNlVXJsICYmIHVybC5zdWJzdHJpbmcoYmFzZVVybC5sZW5ndGgpLm1hdGNoKC9eXFwvY1xcLy8pO1xuICB9XG5cbiAgc3RhdGljIGV4dHJhY3RDYXRlZ29yeUlkRnJvbVVybCh1cmw6IHN0cmluZykge1xuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5yZW1vdmVKc29uRXh0ZW5zaW9uKHVybCkubWF0Y2goL1xcLyhcXGQrKSQvKTtcbiAgICByZXR1cm4gbWF0Y2ggPyBwYXJzZUludChtYXRjaFsxXSwgMTApIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBleHRyYWN0Q2F0ZWdvcnlTbHVnRnJvbVVybCh1cmw6IHN0cmluZykge1xuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5yZW1vdmVKc29uRXh0ZW5zaW9uKHVybCkubWF0Y2goL1xcL2NcXC8oW1xcdy8tXSspXFwvXFxkKyQvKTtcbiAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXSA6IG51bGw7XG4gIH1cblxuICBzdGF0aWMgZXh0cmFjdFRvcGljSWRGcm9tVXJsKHVybDogc3RyaW5nKSB7XG4gICAgY29uc3QgbWF0Y2ggPSB1cmwubWF0Y2goL1xcLyhcXGQrKSg/OiR8XFwvKS8pIHx8IHVybC5tYXRjaCgvXFwvKFxcZCspXFwuanNvbiQvKTtcbiAgICByZXR1cm4gbWF0Y2ggPyBwYXJzZUludChtYXRjaFsxXSwgMTApIDogbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBnZXRMYW5ndWFnZUZyb21UaXRsZSh0aXRsZTogc3RyaW5nKSB7XG4gICAgaWYgKCF0aXRsZSkgcmV0dXJuICcnO1xuXG4gICAgY29uc3QgbWF0Y2ggPSB0aXRsZS5tYXRjaCgnXFxcXHNcXFxcKChbYS16XXsyfSg/Oi1bQS1aXXsyfSk/KVxcXFwpJCcpO1xuICAgIHJldHVybiBtYXRjaCAmJiBtYXRjaFsxXTtcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBnZXRGZWVkc0J5VXJsKFxuICAgIHVybDogc3RyaW5nLFxuICAgIG9wdHM/OiB7IGFwaT86IERpc2NvdXJzZUFQSTsgbG9jYWxlPzogc3RyaW5nOyBtYXhBZ2VJbk1vbnRocz86IG51bWJlcjsgbWF4Q29udGVudExlbmd0aD86IG51bWJlciB9XG4gICk6IFByb21pc2U8SnNvbkZlZWRbXT4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBDaGVjayBhIGNhdGVnb3J5XG4gICAgICBpZiAoRGlzY291cnNlVXRpbHMuaXNEaXNjb3Vyc2VDYXRlZ29yeVVybCh1cmwpKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoYCR7dGhpcy5fbG9nUHJlZml4fURldGVjdGVkIGEgRGlzY291cnNlIGNhdGVnb3J5IGF0OiAke3VybH1gKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RmVlZHNCeUNhdGVnb3J5VXJsKHVybCwgb3B0cyk7XG4gICAgICB9XG5cbiAgICAgIC8vIE9yIGEgdG9waWNcbiAgICAgIGVsc2Uge1xuICAgICAgICBjb25zdCBwb3N0ID0gYXdhaXQgdGhpcy5nZXRGZWVkQnlUb3BpY1VybCh1cmwsIG9wdHMpO1xuICAgICAgICByZXR1cm4gcG9zdCA/IFtwb3N0XSA6IFtdO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcihgJHt0aGlzLl9sb2dQcmVmaXh9YCwgZXJyKTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgZ2V0RmVlZHNCeUNhdGVnb3J5VXJsKFxuICAgIHVybDogc3RyaW5nLFxuICAgIG9wdHM/OiB7IGFwaT86IERpc2NvdXJzZUFQSTsgbG9jYWxlPzogc3RyaW5nOyBtYXhBZ2VJbk1vbnRocz86IG51bWJlcjsgbWF4Q29udGVudExlbmd0aD86IG51bWJlciB9XG4gICk6IFByb21pc2U8SnNvbkZlZWRbXT4ge1xuICAgIGNvbnN0IGNhdGVnb3J5SWQgPSB0aGlzLmV4dHJhY3RDYXRlZ29yeUlkRnJvbVVybCh1cmwpO1xuICAgIGNvbnN0IGNhdGVnb3J5U2x1ZyA9IHRoaXMuZXh0cmFjdENhdGVnb3J5U2x1Z0Zyb21VcmwodXJsKTtcbiAgICBjb25zdCBiYXNlVXJsID0gdGhpcy5nZXREaXNjb3Vyc2VCYXNlVXJsKHVybCk7XG4gICAgY29uc3QgYXBpID0gb3B0cz8uYXBpID8/IG5ldyBEaXNjb3Vyc2VBUEkoYmFzZVVybCk7XG4gICAgY29uc3QgY2F0ZWdvcnk6IERpc2NvdXJzZUNhdGVnb3J5ID0gYXdhaXQgYXBpLmxpc3RDYXRlZ29yeVRvcGljcyh7IGlkOiBjYXRlZ29yeUlkLCBzbHVnOiBjYXRlZ29yeVNsdWcgfSk7XG5cbiAgICBjb25zdCB0b3BpY3MgPSAoY2F0ZWdvcnk/LnRvcGljX2xpc3Q/LnRvcGljcyB8fCBbXSkuZmlsdGVyKCh0b3BpYzogRGlzY291cnNlQ2F0ZWdvcnlUb3BpYykgPT4ge1xuICAgICAgY29uc3QgdG9waWNMb2NhbGUgPSB0aGlzLmdldExhbmd1YWdlRnJvbVRpdGxlKHRvcGljLmZhbmN5X3RpdGxlKTtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIHRvcGljLnBpbm5lZCAmJlxuICAgICAgICB0b3BpYy52aXNpYmxlICYmXG4gICAgICAgIC8vIEtlZXAgc2FtZSBsb2NhbGUsIGlmIGV4aXN0c1xuICAgICAgICAoIXRvcGljTG9jYWxlIHx8ICFvcHRzPy5sb2NhbGUgfHwgdG9waWNMb2NhbGUgPT09IG9wdHMubG9jYWxlKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHBvc3RzID0gKFxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIHRvcGljcy5tYXAoYXN5bmMgKHQpID0+IHtcbiAgICAgICAgICBjb25zdCB0b3BpYzogRGlzY291cnNlVG9waWMgPSBhd2FpdCBhcGkuZ2V0VG9waWMoeyBpZDogdC5pZC50b1N0cmluZygpIH0pO1xuXG4gICAgICAgICAgLy8gSWdub3JlICdBYm91dCcgdG9waWNzXG4gICAgICAgICAgaWYgKHRvcGljLnRhZ3MuaW5jbHVkZXMoJ2Fib3V0LWNhdGVnb3J5JykpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICBjb25zdCBwb3N0cyA9IHRoaXMuZmlsdGVyUmVjZW50UG9zdHModG9waWMucG9zdF9zdHJlYW0ucG9zdHMsIG9wdHMpO1xuICAgICAgICAgIGlmIChpc0VtcHR5QXJyYXkocG9zdHMpKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgIHJldHVybiB0aGlzLnRvRmVlZChwb3N0cywgdG9waWMsIHVybCwgb3B0cyk7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgKS5maWx0ZXIoaXNOb3ROaWwpO1xuXG4gICAgaWYgKGlzRW1wdHlBcnJheShwb3N0cykpIHtcbiAgICAgIGNvbnNvbGUud2FybihgJHt0aGlzLl9sb2dQcmVmaXh9Tm8gcmVjZW50IHBvc3QgZm91bmQgb24gY2F0ZWdvcnkgIyR7Y2F0ZWdvcnlJZH1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcG9zdHM7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgZ2V0RmVlZEJ5VG9waWNVcmwoXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgb3B0cz86IHsgbG9jYWxlPzogc3RyaW5nOyBtYXhBZ2VJbk1vbnRocz86IG51bWJlcjsgbWF4Q29udGVudExlbmd0aD86IG51bWJlcjtcbiAgICAgIC8vIEludGVybmFsIHVzYWdlXG4gICAgICBhcGk/OiBEaXNjb3Vyc2VBUEk7XG4gICAgfVxuICApOiBQcm9taXNlPEpzb25GZWVkPiB7XG4gICAgY29uc3QgdG9waWNJZCA9IHRoaXMuZXh0cmFjdFRvcGljSWRGcm9tVXJsKHVybCk7XG4gICAgaWYgKCF0b3BpY0lkKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGAke3RoaXMuX2xvZ1ByZWZpeH1JbnZhbGlkIFVSTGApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3QgYXBpID0gb3B0cz8uYXBpID8/IG5ldyBEaXNjb3Vyc2VBUEkodGhpcy5nZXREaXNjb3Vyc2VCYXNlVXJsKHVybCkpO1xuICAgIGNvbnN0IHRvcGljID0gYXdhaXQgYXBpLmdldFRvcGljKHsgaWQ6IHRvcGljSWQudG9TdHJpbmcoKSB9KTtcblxuICAgIC8vIElnbm9yZSBhYm91dCBjYXRlZ29yeVxuICAgIGlmICh0b3BpYy50YWdzPy5pbmNsdWRlcygnYWJvdXQtY2F0ZWdvcnknKSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IHBvc3RzID0gdGhpcy5maWx0ZXJSZWNlbnRQb3N0cyh0b3BpYy5wb3N0X3N0cmVhbS5wb3N0cywgb3B0cyk7XG5cbiAgICBpZiAoaXNFbXB0eUFycmF5KHBvc3RzKSkge1xuICAgICAgY29uc29sZS53YXJuKGAke3RoaXMuX2xvZ1ByZWZpeH1ObyByZWNlbnQgcG9zdHMgZm91bmQgaW4gdG9waWMgIyR7dG9waWNJZH1gKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMudG9GZWVkKHBvc3RzLCB0b3BpYywgdXJsLCBvcHRzKTtcbiAgfVxuXG4gIHN0YXRpYyBmaWx0ZXJSZWNlbnRQb3N0cyhwb3N0czogRGlzY291cnNlUG9zdFtdLCBvcHRzPzogeyBtYXhBZ2VJbk1vbnRocz86IG51bWJlciB9KTogRGlzY291cnNlUG9zdFtdIHtcbiAgICBjb25zdCBtYXhBZ2VJbk1vbnRocyA9IG9wdHM/Lm1heEFnZUluTW9udGhzID8/IEpzb25GZWVkVXRpbHMuREVGQVVMVF9NQVhfUE9TVF9BR0VfSU5fTU9OVEhTO1xuICAgIGlmIChtYXhBZ2VJbk1vbnRocyA8PSAwKSByZXR1cm4gcG9zdHM7IC8vIEFjY2VwdCBhbGxcblxuICAgIGNvbnN0IG1pbkRhdGUgPSBtYXhBZ2VJbk1vbnRocyA+IDAgPyBEYXRlVXRpbHMubW9tZW50KCkuc3VidHJhY3QobWF4QWdlSW5Nb250aHMsICdtb250aCcpLnN0YXJ0T2YoJ2RheScpLnV0YygpIDogdW5kZWZpbmVkO1xuICAgIHJldHVybiAocG9zdHMgfHwgW10pLmZpbHRlcigocG9zdCkgPT4gcG9zdCAmJiBEYXRlVXRpbHMubW9tZW50KHBvc3QuY3JlYXRlZF9hdCkuaXNTYW1lT3JBZnRlcihtaW5EYXRlKSk7XG4gIH1cblxuICBzdGF0aWMgdG9GZWVkKHBvc3RzOiBEaXNjb3Vyc2VQb3N0W10sIHRvcGljOiBEaXNjb3Vyc2VUb3BpYywgdXJsOiBzdHJpbmcsIG9wdHM/OiB7IG1heENvbnRlbnRMZW5ndGg/OiBudW1iZXIgfSk6IEpzb25GZWVkIHtcbiAgICBjb25zdCBiYXNlVXJsID0gdGhpcy5nZXREaXNjb3Vyc2VCYXNlVXJsKHVybCk7XG4gICAgY29uc3QgdGl0bGUgPSB0aGlzLmNsZWFuVGl0bGUodG9waWMuZmFuY3lfdGl0bGUgPz8gdG9waWMudGl0bGUpO1xuICAgIGNvbnN0IGl0ZW1zID0gKHBvc3RzIHx8IFtdKS5tYXAoKHBvc3QpID0+IHRoaXMudG9GZWVkSXRlbShwb3N0LCB0b3BpYywgdXJsLCBvcHRzKSk7XG4gICAgY29uc3QgZmlyc3RJdGVtID0gaXRlbXM/LlswXTtcbiAgICBpZiAoZmlyc3RJdGVtKSBmaXJzdEl0ZW0udGl0bGUgPSB0aXRsZTtcbiAgICBjb25zdCBhdXRob3JOYW1lID0gdG9waWM/LmRldGFpbHM/LmNyZWF0ZWRfYnkgJiYgKHRvcGljLmRldGFpbHMuY3JlYXRlZF9ieS5uYW1lIHx8IHRvcGljLmRldGFpbHMuY3JlYXRlZF9ieS51c2VybmFtZSk7XG4gICAgY29uc3QgYXV0aG9yQXZhdGFyID0gYmFzZVVybCArIHRvcGljLmRldGFpbHMuY3JlYXRlZF9ieS5hdmF0YXJfdGVtcGxhdGUucmVwbGFjZSgne3NpemV9JywgJzQ4Jyk7XG4gICAgcmV0dXJuIDxKc29uRmVlZD57XG4gICAgICB2ZXJzaW9uOiBKc29uRmVlZFV0aWxzLlZFUlNJT05fMV8xLFxuICAgICAgZmVlZF91cmw6IHVybCxcbiAgICAgIHRpdGxlOiB0aGlzLmNsZWFuVGl0bGUodG9waWMuZmFuY3lfdGl0bGUpLFxuICAgICAgZXhwaXJlZDogdG9waWMuYXJjaGl2ZWQsXG4gICAgICBhdXRob3JzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBhdXRob3JOYW1lLFxuICAgICAgICAgIGF2YXRhcjogYXV0aG9yQXZhdGFyLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGl0ZW1zLFxuICAgICAgdGFnX3RlbXBsYXRlOiBiYXNlVXJsICsgJy90YWcve3RhZ30nLFxuICAgIH07XG4gIH1cblxuICBzdGF0aWMgdG9GZWVkSXRlbShwb3N0OiBEaXNjb3Vyc2VQb3N0LCB0b3BpYzogRGlzY291cnNlVG9waWMsIHVybDogc3RyaW5nLCBvcHRzPzogeyBtYXhDb250ZW50TGVuZ3RoPzogbnVtYmVyIH0pOiBKc29uRmVlZEl0ZW0ge1xuICAgIGNvbnN0IGJhc2VVcmwgPSB0aGlzLmdldERpc2NvdXJzZUJhc2VVcmwodXJsKTtcbiAgICB1cmwgPSBwb3N0LnBvc3RfdXJsID8gYmFzZVVybCArIHBvc3QucG9zdF91cmwgOiB1cmw7XG4gICAgY29uc3QgaWQgPSBwb3N0LnBvc3RfdXJsID8gYmFzZVVybCArIHBvc3QucG9zdF91cmwgOiBwb3N0LmlkO1xuICAgIGNvbnN0IGh0bWwgPSBKc29uRmVlZFV0aWxzLnRydW5jYXRlSHRtbChwb3N0LmNvb2tlZCwgb3B0cyk7XG4gICAgY29uc3QgdHJ1bmNhdGVkID0gaHRtbD8ubGVuZ3RoICE9PSBwb3N0LmNvb2tlZD8ubGVuZ3RoO1xuICAgIGNvbnN0IGF1dGhvck5hbWUgPSBwb3N0Lm5hbWUgfHwgcG9zdC51c2VybmFtZTtcbiAgICBjb25zdCBhdXRob3JBdmF0YXIgPVxuICAgICAgYmFzZVVybCArIChwb3N0LmF2YXRhcl90ZW1wbGF0ZS5yZXBsYWNlKCd7c2l6ZX0nLCAnNDgnKSA/PyB0b3BpYy5kZXRhaWxzLmxhc3RfcG9zdGVyLmF2YXRhcl90ZW1wbGF0ZS5yZXBsYWNlKCd7c2l6ZX0nLCAnNDgnKSk7XG4gICAgcmV0dXJuIDxKc29uRmVlZEl0ZW0+e1xuICAgICAgaWQsXG4gICAgICB1cmwsXG4gICAgICBhdXRob3JzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBhdXRob3JOYW1lLFxuICAgICAgICAgIGF2YXRhcjogYXV0aG9yQXZhdGFyLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGNvbnRlbnRfaHRtbDogaHRtbCxcbiAgICAgIGRhdGVfcHVibGlzaGVkOiBwb3N0LmNyZWF0ZWRfYXQsXG4gICAgICB0YWdzOiB0b3BpYy50YWdzLFxuICAgICAgdHJ1bmNhdGVkLFxuICAgIH07XG4gIH1cblxuICBzdGF0aWMgY2xlYW5UaXRsZSh0aXRsZTogc3RyaW5nKSB7XG4gICAgaWYgKCF0aXRsZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICByZXR1cm4gdGl0bGUucmVwbGFjZSgvXFxzXFwoW2Etel17Mn0oOj8tW0EtWl17Mn0pP1xcKSQvLCAnJyk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,121 @@
1
+ import { __decorate } from "tslib";
2
+ import { Component, Inject, inject, Input, Optional } from '@angular/core';
3
+ import { RxState } from '@rx-angular/state';
4
+ import { TranslateService } from '@ngx-translate/core';
5
+ import { Router } from '@angular/router';
6
+ import { arrayDistinct, isNotEmptyArray } from '../../shared/functions';
7
+ import { JsonFeedUtils } from './feed.model';
8
+ import { DiscourseUtils } from './discourse/discourse.utils';
9
+ import { map, switchMap } from 'rxjs/operators';
10
+ import { PlatformService } from '../../core/services/platform.service';
11
+ import { RxStateProperty, RxStateSelect } from '../../shared/rx-state/rx-state.decorators';
12
+ import { ENVIRONMENT } from '../../../environments/environment.class';
13
+ import { APP_FEED_SERVICE } from './feed.service';
14
+ import * as i0 from "@angular/core";
15
+ import * as i1 from "@ionic/angular";
16
+ import * as i2 from "@ngx-translate/core";
17
+ import * as i3 from "./feed.directive";
18
+ import * as i4 from "@rx-angular/template/push";
19
+ import * as i5 from "../../shared/pipes/date-from-now.pipe";
20
+ import * as i6 from "../../shared/pipes/arrays.pipe";
21
+ import * as i7 from "../../shared/pipes/observable.pipes";
22
+ import * as i8 from "../../../environments/environment.class";
23
+ export class FeedsComponent {
24
+ environment;
25
+ feedService;
26
+ _debug = false;
27
+ _state = new RxState();
28
+ translate = inject(TranslateService);
29
+ platform = inject(PlatformService);
30
+ router = inject(Router);
31
+ version;
32
+ feeds$;
33
+ hasFeeds$;
34
+ feeds;
35
+ hasFeeds;
36
+ showHeader = true;
37
+ headerTextColor = 'light';
38
+ constructor(environment, feedService) {
39
+ this.environment = environment;
40
+ this.feedService = feedService;
41
+ this._state.connect('hasFeeds', this.feeds$.pipe(map(isNotEmptyArray)));
42
+ if (this.feedService) {
43
+ this._state.connect('feeds', this._state.select(['maxAgeInMonths', 'maxContentLength']).pipe(switchMap(({ maxAgeInMonths, maxContentLength }) => this.feedService.watchAll({
44
+ maxAgeInMonths,
45
+ maxContentLength,
46
+ })), map(({ data }) => data)));
47
+ }
48
+ // Initial state
49
+ this._state.set({
50
+ maxAgeInMonths: this.environment.feed?.maxAgeInMonths ?? -1 /* all */,
51
+ maxContentLength: this.environment.feed?.maxContentLength ?? -1 /* no max */,
52
+ });
53
+ // DEBUG
54
+ this._debug = !environment.production;
55
+ }
56
+ openFeedHome(feed) {
57
+ if (!feed) {
58
+ this.feeds?.forEach((f) => this.openFeedHome(f));
59
+ return;
60
+ }
61
+ const url = feed.home_page_url ?? DiscourseUtils.removeJsonExtension(feed.feed_url) ?? this.feedService.getHomeUrl();
62
+ if (!url)
63
+ return;
64
+ return this.platform.open(url);
65
+ }
66
+ openUrl(url) {
67
+ if (!url)
68
+ return;
69
+ const fixedUrl = DiscourseUtils.removeJsonExtension(url);
70
+ return this.platform.open(fixedUrl);
71
+ }
72
+ openTag(feed, tag) {
73
+ const url = this.feedService.getTagUrl(feed, tag);
74
+ return this.openUrl(url);
75
+ }
76
+ getTags(feedOrItem) {
77
+ if (JsonFeedUtils.isJsonFeed(feedOrItem)) {
78
+ return arrayDistinct((feedOrItem.items || [])
79
+ .map((item) => item.tags)
80
+ .filter(isNotEmptyArray)
81
+ .flat());
82
+ }
83
+ if (JsonFeedUtils.isJsonFeedItem(feedOrItem)) {
84
+ return arrayDistinct((feedOrItem.tags || []).flat());
85
+ }
86
+ return [];
87
+ }
88
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedsComponent, deps: [{ token: ENVIRONMENT }, { token: APP_FEED_SERVICE, optional: true }], target: i0.ɵɵFactoryTarget.Component });
89
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FeedsComponent, selector: "app-feeds", inputs: { feeds: "feeds", showHeader: "showHeader", headerTextColor: "headerTextColor" }, providers: [RxState], ngImport: i0, template: "@if (feeds | isNotEmptyArray) {\n <div class=\"feed ion-padding-horizontal ion-no-padding ion-padding-top\">\n\n <!-- feeds -->\n @for (feed of feeds$ | push; track feed.feed_url) {\n\n <!-- top header -->\n @if (showHeader) {\n <ion-item lines=\"none\" color=\"secondary\">\n <ion-icon slot=\"start\" name=\"megaphone\"></ion-icon>\n <ion-label>\n <b>{{ feed.title || ('SOCIAL.FEED.NEWS'|translate) }}</b>\n </ion-label>\n <ion-button slot=\"end\" fill=\"clear\" (click)=\"openFeedHome()\">\n <ion-label translate>SOCIAL.FEED.SHOW_ALL_FEED</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-item>\n }\n\n\n <!-- items -->\n @for (item of feed.items; track item.id) {\n <ion-card>\n <ion-card-header>\n <ion-card-subtitle style=\"vertical-align: middle\">\n\n <!-- Authors -->\n @for (author of (item.authors || feed.authors); track author) {\n @if (author.name || author.avatar) {\n <ion-chip (click)=\"openUrl(author.url)\" tappable>\n @if (author.avatar) {\n <ion-avatar>\n <ion-img [src]=\"author.avatar\" [alt]=\"author.name\"></ion-img>\n </ion-avatar>\n }\n @if (author.name) {\n <ion-label color=\"medium\">{{ author.name }}</ion-label>\n }\n </ion-chip>\n }\n }\n <ion-note class=\"ion-float-end\">\n <small>{{ item.date_published | dateFromNow }}</small>\n </ion-note>\n </ion-card-subtitle>\n\n <!-- title -->\n <ion-card-title (click)=\"openUrl(item.url || feed.feed_url)\" tappable>{{ item?.title }}</ion-card-title>\n\n <!-- tags -->\n @let tags = item | map: getTags;\n @if (tags | isNotEmptyArray) {\n <div class=\"tags\">\n @for (tag of tags; track tag; let last = $last) {\n <a (click)=\"openTag(feed, tag)\" tappable>\n <ion-text>#{{ tag }}</ion-text>\n </a>@if (!last) {\n &nbsp;\n }\n }\n </div>\n }\n </ion-card-header>\n\n <!-- Feed content -->\n <ion-card-content>\n <ion-text [feed]=\"item.url || feed.feed_url\">\n @if (item.content_html) {\n <p [innerHTML]=\"item.content_html\"></p>\n } @else if (item.content_text) {\n <p [innerText]=\"item.content_text\"></p>\n }\n </ion-text>\n </ion-card-content>\n\n <ion-button (click)=\"openUrl(item.url)\" class=\"ion-float-end\" fill=\"clear\">\n <ion-label>{{ (item.truncated ? 'SOCIAL.FEED.READ_MORE' : 'COMMON.BTN_SHOW') | translate }}</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-card>\n }\n }\n </div>\n}\n", styles: [".feed ion-item{border-radius:12px 12px 0 0;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}.feed ion-item ion-icon[slot=start]{-webkit-margin-end:8px;margin-inline-end:8px}.feed .tags{display:inline}.feed .tags a{color:var(--ion-color-step-600, #666666)!important}.feed ion-card{--ion-card-background: rgba(var(--ion-background-color-rgb), .6);--ion-card-color: var(--ion-text-color);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);margin:0 0 16px}.feed ion-card ion-card-header ion-card-title{--color: var(--ion-text-color)}.feed ion-card ion-card-header ion-card-subtitle{--color: var(--ion-color-step-50)}.feed ion-card ion-card-header ion-chip{--background: transparent;--border-color: transparent;--border-width: 0}.feed ion-card ion-card-header ion-chip ion-avatar{border:1px solid var(--ion-color-primary)}.feed ion-card ion-card-header ion-chip ion-label{color:var(--color)}.feed ion-button{text-transform:unset;color:var(--ion-color-step-400)}.feed a:hover{color:var(--ion-color-medium)}\n"], dependencies: [{ kind: "component", type: i1.IonAvatar, selector: "ion-avatar" }, { kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i1.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i1.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i1.IonCardSubtitle, selector: "ion-card-subtitle", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonChip, selector: "ion-chip", inputs: ["color", "disabled", "mode", "outline"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i1.IonImg, selector: "ion-img", inputs: ["alt", "src"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i1.IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i3.FeedDirective, selector: "feed,[feed]", inputs: ["feed"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "pipe", type: i4.RxPush, name: "push" }, { kind: "pipe", type: i5.DateFromNowPipe, name: "dateFromNow" }, { kind: "pipe", type: i6.NotEmptyArrayPipe, name: "isNotEmptyArray" }, { kind: "pipe", type: i7.MapPipe, name: "map" }] });
90
+ }
91
+ __decorate([
92
+ RxStateSelect()
93
+ ], FeedsComponent.prototype, "feeds$", void 0);
94
+ __decorate([
95
+ RxStateSelect()
96
+ ], FeedsComponent.prototype, "hasFeeds$", void 0);
97
+ __decorate([
98
+ RxStateProperty()
99
+ ], FeedsComponent.prototype, "feeds", void 0);
100
+ __decorate([
101
+ RxStateProperty()
102
+ ], FeedsComponent.prototype, "hasFeeds", void 0);
103
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedsComponent, decorators: [{
104
+ type: Component,
105
+ args: [{ selector: 'app-feeds', providers: [RxState], template: "@if (feeds | isNotEmptyArray) {\n <div class=\"feed ion-padding-horizontal ion-no-padding ion-padding-top\">\n\n <!-- feeds -->\n @for (feed of feeds$ | push; track feed.feed_url) {\n\n <!-- top header -->\n @if (showHeader) {\n <ion-item lines=\"none\" color=\"secondary\">\n <ion-icon slot=\"start\" name=\"megaphone\"></ion-icon>\n <ion-label>\n <b>{{ feed.title || ('SOCIAL.FEED.NEWS'|translate) }}</b>\n </ion-label>\n <ion-button slot=\"end\" fill=\"clear\" (click)=\"openFeedHome()\">\n <ion-label translate>SOCIAL.FEED.SHOW_ALL_FEED</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-item>\n }\n\n\n <!-- items -->\n @for (item of feed.items; track item.id) {\n <ion-card>\n <ion-card-header>\n <ion-card-subtitle style=\"vertical-align: middle\">\n\n <!-- Authors -->\n @for (author of (item.authors || feed.authors); track author) {\n @if (author.name || author.avatar) {\n <ion-chip (click)=\"openUrl(author.url)\" tappable>\n @if (author.avatar) {\n <ion-avatar>\n <ion-img [src]=\"author.avatar\" [alt]=\"author.name\"></ion-img>\n </ion-avatar>\n }\n @if (author.name) {\n <ion-label color=\"medium\">{{ author.name }}</ion-label>\n }\n </ion-chip>\n }\n }\n <ion-note class=\"ion-float-end\">\n <small>{{ item.date_published | dateFromNow }}</small>\n </ion-note>\n </ion-card-subtitle>\n\n <!-- title -->\n <ion-card-title (click)=\"openUrl(item.url || feed.feed_url)\" tappable>{{ item?.title }}</ion-card-title>\n\n <!-- tags -->\n @let tags = item | map: getTags;\n @if (tags | isNotEmptyArray) {\n <div class=\"tags\">\n @for (tag of tags; track tag; let last = $last) {\n <a (click)=\"openTag(feed, tag)\" tappable>\n <ion-text>#{{ tag }}</ion-text>\n </a>@if (!last) {\n &nbsp;\n }\n }\n </div>\n }\n </ion-card-header>\n\n <!-- Feed content -->\n <ion-card-content>\n <ion-text [feed]=\"item.url || feed.feed_url\">\n @if (item.content_html) {\n <p [innerHTML]=\"item.content_html\"></p>\n } @else if (item.content_text) {\n <p [innerText]=\"item.content_text\"></p>\n }\n </ion-text>\n </ion-card-content>\n\n <ion-button (click)=\"openUrl(item.url)\" class=\"ion-float-end\" fill=\"clear\">\n <ion-label>{{ (item.truncated ? 'SOCIAL.FEED.READ_MORE' : 'COMMON.BTN_SHOW') | translate }}</ion-label>\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\n </ion-button>\n </ion-card>\n }\n }\n </div>\n}\n", styles: [".feed ion-item{border-radius:12px 12px 0 0;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}.feed ion-item ion-icon[slot=start]{-webkit-margin-end:8px;margin-inline-end:8px}.feed .tags{display:inline}.feed .tags a{color:var(--ion-color-step-600, #666666)!important}.feed ion-card{--ion-card-background: rgba(var(--ion-background-color-rgb), .6);--ion-card-color: var(--ion-text-color);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);margin:0 0 16px}.feed ion-card ion-card-header ion-card-title{--color: var(--ion-text-color)}.feed ion-card ion-card-header ion-card-subtitle{--color: var(--ion-color-step-50)}.feed ion-card ion-card-header ion-chip{--background: transparent;--border-color: transparent;--border-width: 0}.feed ion-card ion-card-header ion-chip ion-avatar{border:1px solid var(--ion-color-primary)}.feed ion-card ion-card-header ion-chip ion-label{color:var(--color)}.feed ion-button{text-transform:unset;color:var(--ion-color-step-400)}.feed a:hover{color:var(--ion-color-medium)}\n"] }]
106
+ }], ctorParameters: () => [{ type: i8.Environment, decorators: [{
107
+ type: Inject,
108
+ args: [ENVIRONMENT]
109
+ }] }, { type: undefined, decorators: [{
110
+ type: Optional
111
+ }, {
112
+ type: Inject,
113
+ args: [APP_FEED_SERVICE]
114
+ }] }], propDecorators: { feeds$: [], hasFeeds$: [], feeds: [{
115
+ type: Input
116
+ }], hasFeeds: [], showHeader: [{
117
+ type: Input
118
+ }], headerTextColor: [{
119
+ type: Input
120
+ }] } });
121
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVlZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3NvY2lhbC9mZWVkL2ZlZWQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zb2NpYWwvZmVlZC9mZWVkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDNUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDeEUsT0FBTyxFQUFZLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN2RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDN0QsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUMzRixPQUFPLEVBQWUsV0FBVyxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFFbkYsT0FBTyxFQUFFLGdCQUFnQixFQUFnQixNQUFNLGdCQUFnQixDQUFDOzs7Ozs7Ozs7O0FBZWhFLE1BQU0sT0FBTyxjQUFjO0lBb0JRO0lBQ2M7SUFwQnJDLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFDZixNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQWEsQ0FBQztJ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InNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5qZWN0LCBpbmplY3QsIElucHV0LCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUnhTdGF0ZSB9IGZyb20gJ0ByeC1hbmd1bGFyL3N0YXRlJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBhcnJheURpc3RpbmN0LCBpc05vdEVtcHR5QXJyYXkgfSBmcm9tICcuLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcbmltcG9ydCB7IEpzb25GZWVkLCBKc29uRmVlZFV0aWxzIH0gZnJvbSAnLi9mZWVkLm1vZGVsJztcbmltcG9ydCB7IERpc2NvdXJzZVV0aWxzIH0gZnJvbSAnLi9kaXNjb3Vyc2UvZGlzY291cnNlLnV0aWxzJztcbmltcG9ydCB7IG1hcCwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgUGxhdGZvcm1TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9zZXJ2aWNlcy9wbGF0Zm9ybS5zZXJ2aWNlJztcbmltcG9ydCB7IFJ4U3RhdGVQcm9wZXJ0eSwgUnhTdGF0ZVNlbGVjdCB9IGZyb20gJy4uLy4uL3NoYXJlZC9yeC1zdGF0ZS9yeC1zdGF0ZS5kZWNvcmF0b3JzJztcbmltcG9ydCB7IEVudmlyb25tZW50LCBFTlZJUk9OTUVOVCB9IGZyb20gJy4uLy4uLy4uL2Vudmlyb25tZW50cy9lbnZpcm9ubWVudC5jbGFzcyc7XG5pbXBvcnQgeyBBcHBDb2xvcnMgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgQVBQX0ZFRURfU0VSVklDRSwgSUZlZWRTZXJ2aWNlIH0gZnJvbSAnLi9mZWVkLnNlcnZpY2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZlZWRTdGF0ZSB7XG4gIG1heEFnZUluTW9udGhzOiBudW1iZXI7XG4gIG1heENvbnRlbnRMZW5ndGg6IG51bWJlcjtcbiAgZmVlZHM6IEpzb25GZWVkW107XG4gIGhhc0ZlZWRzOiBib29sZWFuO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtZmVlZHMnLFxuICB0ZW1wbGF0ZVVybDogJy4vZmVlZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2ZlZWQuY29tcG9uZW50LnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbUnhTdGF0ZV0sXG59KVxuZXhwb3J0IGNsYXNzIEZlZWRzQ29tcG9uZW50PFQgZXh0ZW5kcyBKc29uRmVlZCA9IEpzb25GZWVkPiB7XG4gIHByb3RlY3RlZCBfZGVidWcgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIF9zdGF0ZSA9IG5ldyBSeFN0YXRlPEZlZWRTdGF0ZT4oKTtcbiAgcHJvdGVjdGVkIHRyYW5zbGF0ZSA9IGluamVjdChUcmFuc2xhdGVTZXJ2aWNlKTtcbiAgcHJvdGVjdGVkIHBsYXRmb3JtID0gaW5qZWN0KFBsYXRmb3JtU2VydmljZSk7XG4gIHByb3RlY3RlZCByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcbiAgcHJvdGVjdGVkIHZlcnNpb246IHN0cmluZztcblxuICBAUnhTdGF0ZVNlbGVjdCgpIGZlZWRzJDogT2JzZXJ2YWJsZTxUW10+O1xuXG4gIEBSeFN0YXRlU2VsZWN0KCkgaGFzRmVlZHMkOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuXG4gIEBSeFN0YXRlUHJvcGVydHkoKSBASW5wdXQoKSBmZWVkczogVFtdO1xuXG4gIEBSeFN0YXRlUHJvcGVydHkoKSBoYXNGZWVkczogYm9vbGVhbjtcblxuICBASW5wdXQoKSBzaG93SGVhZGVyID0gdHJ1ZTtcbiAgQElucHV0KCkgaGVhZGVyVGV4dENvbG9yOiBBcHBDb2xvcnMgPSAnbGlnaHQnO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoRU5WSVJPTk1FTlQpIHByb3RlY3RlZCBlbnZpcm9ubWVudDogRW52aXJvbm1lbnQsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChBUFBfRkVFRF9TRVJWSUNFKSBwdWJsaWMgZmVlZFNlcnZpY2U6IElGZWVkU2VydmljZTxUPlxuICApIHtcbiAgICB0aGlzLl9zdGF0ZS5jb25uZWN0KCdoYXNGZWVkcycsIHRoaXMuZmVlZHMkLnBpcGUobWFwKGlzTm90RW1wdHlBcnJheSkpKTtcblxuICAgIGlmICh0aGlzLmZlZWRTZXJ2aWNlKSB7XG4gICAgICB0aGlzLl9zdGF0ZS5jb25uZWN0KFxuICAgICAgICAnZmVlZHMnLFxuICAgICAgICB0aGlzLl9zdGF0ZS5zZWxlY3QoWydtYXhBZ2VJbk1vbnRocycsICdtYXhDb250ZW50TGVuZ3RoJ10pLnBpcGUoXG4gICAgICAgICAgc3dpdGNoTWFwKCh7IG1heEFnZUluTW9udGhzLCBtYXhDb250ZW50TGVuZ3RoIH0pID0+XG4gICAgICAgICAgICB0aGlzLmZlZWRTZXJ2aWNlLndhdGNoQWxsKHtcbiAgICAgICAgICAgICAgbWF4QWdlSW5Nb250aHMsXG4gICAgICAgICAgICAgIG1heENvbnRlbnRMZW5ndGgsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICksXG4gICAgICAgICAgbWFwKCh7IGRhdGEgfSkgPT4gZGF0YSlcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBJbml0aWFsIHN0YXRlXG4gICAgdGhpcy5fc3RhdGUuc2V0KHtcbiAgICAgIG1heEFnZUluTW9udGhzOiB0aGlzLmVudmlyb25tZW50LmZlZWQ/Lm1heEFnZUluTW9udGhzID8/IC0xIC8qIGFsbCAqLyxcbiAgICAgIG1heENvbnRlbnRMZW5ndGg6IHRoaXMuZW52aXJvbm1lbnQuZmVlZD8ubWF4Q29udGVudExlbmd0aCA/PyAtMSAvKiBubyBtYXggKi8sXG4gICAgfSk7XG5cbiAgICAvLyBERUJVR1xuICAgIHRoaXMuX2RlYnVnID0gIWVudmlyb25tZW50LnByb2R1Y3Rpb247XG4gIH1cblxuICBvcGVuRmVlZEhvbWUoZmVlZD86IFQpIHtcbiAgICBpZiAoIWZlZWQpIHtcbiAgICAgIHRoaXMuZmVlZHM/LmZvckVhY2goKGYpID0+IHRoaXMub3BlbkZlZWRIb21lKGYpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB1cmwgPSBmZWVkLmhvbWVfcGFnZV91cmwgPz8gRGlzY291cnNlVXRpbHMucmVtb3ZlSnNvbkV4dGVuc2lvbihmZWVkLmZlZWRfdXJsKSA/PyB0aGlzLmZlZWRTZXJ2aWNlLmdldEhvbWVVcmwoKTtcbiAgICBpZiAoIXVybCkgcmV0dXJuO1xuICAgIHJldHVybiB0aGlzLnBsYXRmb3JtLm9wZW4odXJsKTtcbiAgfVxuXG4gIG9wZW5VcmwodXJsOiBzdHJpbmcpIHtcbiAgICBpZiAoIXVybCkgcmV0dXJuO1xuICAgIGNvbnN0IGZpeGVkVXJsID0gRGlzY291cnNlVXRpbHMucmVtb3ZlSnNvbkV4dGVuc2lvbih1cmwpO1xuICAgIHJldHVybiB0aGlzLnBsYXRmb3JtLm9wZW4oZml4ZWRVcmwpO1xuICB9XG5cbiAgb3BlblRhZyhmZWVkOiBULCB0YWc6IHN0cmluZykge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuZmVlZFNlcnZpY2UuZ2V0VGFnVXJsKGZlZWQsIHRhZyk7XG4gICAgcmV0dXJuIHRoaXMub3BlblVybCh1cmwpO1xuICB9XG5cbiAgZ2V0VGFncyhmZWVkT3JJdGVtPzogVCB8IFRbJ2l0ZW1zJ11bMF0pIHtcbiAgICBpZiAoSnNvbkZlZWRVdGlscy5pc0pzb25GZWVkKGZlZWRPckl0ZW0pKSB7XG4gICAgICByZXR1cm4gYXJyYXlEaXN0aW5jdChcbiAgICAgICAgKGZlZWRPckl0ZW0uaXRlbXMgfHwgW10pXG4gICAgICAgICAgLm1hcCgoaXRlbSkgPT4gaXRlbS50YWdzKVxuICAgICAgICAgIC5maWx0ZXIoaXNOb3RFbXB0eUFycmF5KVxuICAgICAgICAgIC5mbGF0KClcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChKc29uRmVlZFV0aWxzLmlzSnNvbkZlZWRJdGVtKGZlZWRPckl0ZW0pKSB7XG4gICAgICByZXR1cm4gYXJyYXlEaXN0aW5jdCgoZmVlZE9ySXRlbS50YWdzIHx8IFtdKS5mbGF0KCkpO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cbn1cbiIsIkBpZiAoZmVlZHMgfCBpc05vdEVtcHR5QXJyYXkpIHtcbiAgPGRpdiBjbGFzcz1cImZlZWQgaW9uLXBhZGRpbmctaG9yaXpvbnRhbCBpb24tbm8tcGFkZGluZyBpb24tcGFkZGluZy10b3BcIj5cblxuICAgIDwhLS0gZmVlZHMgLS0+XG4gICAgQGZvciAoZmVlZCBvZiBmZWVkcyQgfCBwdXNoOyB0cmFjayBmZWVkLmZlZWRfdXJsKSB7XG5cbiAgICAgIDwhLS0gdG9wIGhlYWRlciAtLT5cbiAgICAgIEBpZiAoc2hvd0hlYWRlcikge1xuICAgICAgICA8aW9uLWl0ZW0gbGluZXM9XCJub25lXCIgY29sb3I9XCJzZWNvbmRhcnlcIj5cbiAgICAgICAgICA8aW9uLWljb24gc2xvdD1cInN0YXJ0XCIgbmFtZT1cIm1lZ2FwaG9uZVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgPGlvbi1sYWJlbD5cbiAgICAgICAgICAgIDxiPnt7IGZlZWQudGl0bGUgfHwgKCdTT0NJQUwuRkVFRC5ORVdTJ3x0cmFuc2xhdGUpIH19PC9iPlxuICAgICAgICAgIDwvaW9uLWxhYmVsPlxuICAgICAgICAgIDxpb24tYnV0dG9uIHNsb3Q9XCJlbmRcIiBmaWxsPVwiY2xlYXJcIiAoY2xpY2spPVwib3BlbkZlZWRIb21lKClcIj5cbiAgICAgICAgICAgIDxpb24tbGFiZWwgdHJhbnNsYXRlPlNPQ0lBTC5GRUVELlNIT1dfQUxMX0ZFRUQ8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgIDxpb24taWNvbiBzbG90PVwiZW5kXCIgbmFtZT1cImNoZXZyb24tZm9yd2FyZC1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICB9XG5cblxuICAgICAgPCEtLSBpdGVtcyAtLT5cbiAgICAgIEBmb3IgKGl0ZW0gb2YgZmVlZC5pdGVtczsgdHJhY2sgaXRlbS5pZCkge1xuICAgICAgICA8aW9uLWNhcmQ+XG4gICAgICAgICAgPGlvbi1jYXJkLWhlYWRlcj5cbiAgICAgICAgICAgIDxpb24tY2FyZC1zdWJ0aXRsZSBzdHlsZT1cInZlcnRpY2FsLWFsaWduOiBtaWRkbGVcIj5cblxuICAgICAgICAgICAgICA8IS0tIEF1dGhvcnMgLS0+XG4gICAgICAgICAgICAgIEBmb3IgKGF1dGhvciBvZiAoaXRlbS5hdXRob3JzIHx8IGZlZWQuYXV0aG9ycyk7IHRyYWNrIGF1dGhvcikge1xuICAgICAgICAgICAgICAgIEBpZiAoYXV0aG9yLm5hbWUgfHwgYXV0aG9yLmF2YXRhcikge1xuICAgICAgICAgICAgICAgICAgPGlvbi1jaGlwIChjbGljayk9XCJvcGVuVXJsKGF1dGhvci51cmwpXCIgdGFwcGFibGU+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoYXV0aG9yLmF2YXRhcikge1xuICAgICAgICAgICAgICAgICAgICAgIDxpb24tYXZhdGFyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pbWcgW3NyY109XCJhdXRob3IuYXZhdGFyXCIgW2FsdF09XCJhdXRob3IubmFtZVwiPjwvaW9uLWltZz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1hdmF0YXI+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGlmIChhdXRob3IubmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAgIDxpb24tbGFiZWwgY29sb3I9XCJtZWRpdW1cIj57eyBhdXRob3IubmFtZSB9fTwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8L2lvbi1jaGlwPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8aW9uLW5vdGUgY2xhc3M9XCJpb24tZmxvYXQtZW5kXCI+XG4gICAgICAgICAgICAgICAgPHNtYWxsPnt7IGl0ZW0uZGF0ZV9wdWJsaXNoZWQgfCBkYXRlRnJvbU5vdyB9fTwvc21hbGw+XG4gICAgICAgICAgICAgIDwvaW9uLW5vdGU+XG4gICAgICAgICAgICA8L2lvbi1jYXJkLXN1YnRpdGxlPlxuXG4gICAgICAgICAgICA8IS0tIHRpdGxlIC0tPlxuICAgICAgICAgICAgPGlvbi1jYXJkLXRpdGxlIChjbGljayk9XCJvcGVuVXJsKGl0ZW0udXJsIHx8IGZlZWQuZmVlZF91cmwpXCIgdGFwcGFibGU+e3sgaXRlbT8udGl0bGUgfX08L2lvbi1jYXJkLXRpdGxlPlxuXG4gICAgICAgICAgICA8IS0tIHRhZ3MgLS0+XG4gICAgICAgICAgICBAbGV0IHRhZ3MgPSBpdGVtIHwgbWFwOiBnZXRUYWdzO1xuICAgICAgICAgICAgQGlmICh0YWdzIHwgaXNOb3RFbXB0eUFycmF5KSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YWdzXCI+XG4gICAgICAgICAgICAgICAgQGZvciAodGFnIG9mIHRhZ3M7IHRyYWNrIHRhZzsgbGV0IGxhc3QgPSAkbGFzdCkge1xuICAgICAgICAgICAgICAgICAgPGEgKGNsaWNrKT1cIm9wZW5UYWcoZmVlZCwgdGFnKVwiIHRhcHBhYmxlPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLXRleHQ+I3t7IHRhZyB9fTwvaW9uLXRleHQ+XG4gICAgICAgICAgICAgICAgICA8L2E+QGlmICghbGFzdCkge1xuICAgICAgICAgICAgICAgICAgICAmbmJzcDtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvaW9uLWNhcmQtaGVhZGVyPlxuXG4gICAgICAgICAgPCEtLSBGZWVkIGNvbnRlbnQgLS0+XG4gICAgICAgICAgPGlvbi1jYXJkLWNvbnRlbnQ+XG4gICAgICAgICAgICA8aW9uLXRleHQgW2ZlZWRdPVwiaXRlbS51cmwgfHwgZmVlZC5mZWVkX3VybFwiPlxuICAgICAgICAgICAgICBAaWYgKGl0ZW0uY29udGVudF9odG1sKSB7XG4gICAgICAgICAgICAgICAgPHAgW2lubmVySFRNTF09XCJpdGVtLmNvbnRlbnRfaHRtbFwiPjwvcD5cbiAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoaXRlbS5jb250ZW50X3RleHQpIHtcbiAgICAgICAgICAgICAgICA8cCBbaW5uZXJUZXh0XT1cIml0ZW0uY29udGVudF90ZXh0XCI+PC9wPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2lvbi10ZXh0PlxuICAgICAgICAgIDwvaW9uLWNhcmQtY29udGVudD5cblxuICAgICAgICAgIDxpb24tYnV0dG9uIChjbGljayk9XCJvcGVuVXJsKGl0ZW0udXJsKVwiIGNsYXNzPVwiaW9uLWZsb2F0LWVuZFwiIGZpbGw9XCJjbGVhclwiPlxuICAgICAgICAgICAgPGlvbi1sYWJlbD57eyAoaXRlbS50cnVuY2F0ZWQgPyAnU09DSUFMLkZFRUQuUkVBRF9NT1JFJyA6ICdDT01NT04uQlROX1NIT1cnKSB8IHRyYW5zbGF0ZSB9fTwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgPGlvbi1pY29uIHNsb3Q9XCJlbmRcIiBuYW1lPVwiY2hldnJvbi1mb3J3YXJkLW91dGxpbmVcIj48L2lvbi1pY29uPlxuICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgPC9pb24tY2FyZD5cbiAgICAgIH1cbiAgICB9XG4gIDwvZGl2PlxufVxuIl19
@@ -0,0 +1,151 @@
1
+ import { Directive, inject, Input } from '@angular/core';
2
+ import { Subscription } from 'rxjs';
3
+ import { ActivatedRoute, Router } from '@angular/router';
4
+ import { UrlUtils } from '../../shared/file/url.utils';
5
+ import { LocationStrategy } from '@angular/common';
6
+ import { isNotNilOrBlank } from '../../shared/functions';
7
+ import { NavController } from '@ionic/angular';
8
+ import { DiscourseUtils } from './discourse/discourse.utils';
9
+ import { PlatformService } from '../../core/services/platform.service';
10
+ import * as i0 from "@angular/core";
11
+ export class FeedDirective {
12
+ element;
13
+ _subscription = new Subscription();
14
+ platform = inject(PlatformService);
15
+ locationStrategy = inject(LocationStrategy);
16
+ navController = inject(NavController);
17
+ router = inject(Router);
18
+ route = inject(ActivatedRoute);
19
+ _feedUrl;
20
+ _baseUrl;
21
+ set feedUrl(value) {
22
+ this._feedUrl = value;
23
+ this._baseUrl = value && DiscourseUtils.removeJsonExtension(value);
24
+ }
25
+ get feedUrl() {
26
+ return this._feedUrl;
27
+ }
28
+ constructor(element) {
29
+ this.element = element;
30
+ // DEBUG
31
+ //console.debug('[feed-directive] Creating feed directive');
32
+ }
33
+ ngAfterViewInit() {
34
+ console.debug('[feed-directive] Processing anchors');
35
+ // Listening click events
36
+ this._subscription.add(this.listenClickEvents(this.element.nativeElement));
37
+ }
38
+ ngOnDestroy() {
39
+ this._subscription.unsubscribe();
40
+ }
41
+ listenClickEvents(nativeElement) {
42
+ console.debug('[feed-directive] Start listening click events...');
43
+ const subscription = new Subscription();
44
+ const listener = (event) => this.click(event, nativeElement);
45
+ const links = nativeElement.querySelectorAll('a');
46
+ links.forEach((link) => {
47
+ // DEBUG
48
+ //console.debug('[feed-directive] Adding click listener to', link);
49
+ link.addEventListener('click', listener);
50
+ subscription.add(() => link.removeEventListener('click', listener));
51
+ });
52
+ // DEBUG
53
+ subscription.add(() => console.debug('[feed-directive] Stop listening click events'));
54
+ return subscription;
55
+ }
56
+ async click(event, containerElement) {
57
+ console.debug('[feed-directive] Processing click event...', event);
58
+ if (!(event.target instanceof HTMLAnchorElement) && !(event.target?.['tagName'] === 'A')) {
59
+ console.warn('[feed-directive] Invalid click event target. Should an anchor <a>', event.target);
60
+ return;
61
+ }
62
+ const element = event.target;
63
+ let href = element.getAttribute('href');
64
+ const fragment = UrlUtils.getFragment(href);
65
+ // Fragment
66
+ if (href?.startsWith('#') && isNotNilOrBlank(fragment)) {
67
+ event.preventDefault();
68
+ this.scrollToAnchor(containerElement, fragment);
69
+ return true;
70
+ }
71
+ const routerLink = element.getAttribute('routerLink');
72
+ if (isNotNilOrBlank(routerLink)) {
73
+ event.preventDefault();
74
+ return this.navController.navigateForward(routerLink);
75
+ }
76
+ // Resolve relative URL, if baseUrl has been set
77
+ if (this._baseUrl && UrlUtils.isRelativeUrl(href)) {
78
+ // Resolve URL, then open using the platform
79
+ href = UrlUtils.resolveRelativeUrl(this._baseUrl, href);
80
+ }
81
+ // Resolve internal URL as an app route
82
+ if (UrlUtils.isInternalUrl(href)) {
83
+ const routePath = this.normalizeUrl(href.startsWith('/') ? href : `/${href}`);
84
+ const urlTree = this.getUrlTree(routePath);
85
+ event.preventDefault();
86
+ this.router.navigated = false;
87
+ // Opening route
88
+ return this.navController.navigateForward(urlTree);
89
+ }
90
+ // External URL: open using the platform
91
+ event.preventDefault();
92
+ await this.platform.open(href);
93
+ return true;
94
+ }
95
+ scrollToAnchor(containerElement, anchorId) {
96
+ if (!containerElement || !anchorId) {
97
+ console.warn("Missing 'containerElement' or 'fragment' argument.");
98
+ return;
99
+ }
100
+ console.debug('[feed-directive-anchor] Scrolling to anchor #' + anchorId);
101
+ // Find the target element with the specified fragment ID
102
+ const targetElement = containerElement.querySelector(`#${anchorId}`);
103
+ if (targetElement) {
104
+ // Scroll smoothly to the target element
105
+ // eslint-disable-next-line @rx-angular/prefer-no-layout-sensitive-apis
106
+ targetElement.scrollIntoView({
107
+ behavior: 'smooth', // Smooth scrolling behavior
108
+ block: 'start', // Align the target element to the top of the container
109
+ });
110
+ }
111
+ else {
112
+ console.warn(`No element found with the ID "${anchorId}" inside the container.`);
113
+ }
114
+ }
115
+ /**
116
+ * Transform a relative URL to its absolute representation according to current router state.
117
+ * @param url Relative URL path.
118
+ * @return Absolute URL based on the current route.
119
+ */
120
+ normalizeUrl(url) {
121
+ if (UrlUtils.isExternalUrl(url)) {
122
+ return url;
123
+ }
124
+ if (this._baseUrl && UrlUtils.isRelativeUrl(url)) {
125
+ return UrlUtils.resolveRelativeUrl(this._baseUrl, url);
126
+ }
127
+ const urlTree = this.getUrlTree(url);
128
+ const serializedUrl = this.router.serializeUrl(urlTree);
129
+ return this.locationStrategy.prepareExternalUrl(serializedUrl);
130
+ }
131
+ getUrlTree(url) {
132
+ url = UrlUtils.normalizeUrl(url);
133
+ const urlPath = UrlUtils.stripFragmentAndQuery(url) || UrlUtils.stripFragmentAndQuery(this.router.url);
134
+ const parsedUrl = this.router.parseUrl(url);
135
+ const fragment = parsedUrl.fragment;
136
+ const queryParams = parsedUrl.queryParams;
137
+ return this.router.createUrlTree([urlPath], { relativeTo: this.route, fragment, queryParams });
138
+ }
139
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
140
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FeedDirective, selector: "feed,[feed]", inputs: { feedUrl: ["feed", "feedUrl"] }, ngImport: i0 });
141
+ }
142
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FeedDirective, decorators: [{
143
+ type: Directive,
144
+ args: [{
145
+ selector: 'feed,[feed]',
146
+ }]
147
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { feedUrl: [{
148
+ type: Input,
149
+ args: ['feed']
150
+ }] } });
151
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVlZC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3NvY2lhbC9mZWVkL2ZlZWQuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsU0FBUyxFQUFjLE1BQU0sRUFBRSxLQUFLLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDL0YsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBVyxNQUFNLGlCQUFpQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0NBQXNDLENBQUM7O0FBS3ZFLE1BQU0sT0FBTyxhQUFhO0lBb0JKO0lBbkJaLGFBQWEsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBQ25DLFFBQVEsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDbkMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDNUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN0QyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3hCLEtBQUssR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7SUFFL0IsUUFBUSxDQUFTO0lBQ2pCLFFBQVEsQ0FBUztJQUV6QixJQUFtQixPQUFPLENBQUMsS0FBYTtRQUN0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T0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELFVBQVUsQ0FBQyxHQUFXO1FBQ3BCLEdBQUcsR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2RyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM1QyxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDO1FBQ3BDLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxXQUFXLENBQUM7UUFDMUMsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDakcsQ0FBQzt3R0FySlUsYUFBYTs0RkFBYixhQUFhOzs0RkFBYixhQUFhO2tCQUh6QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxhQUFhO2lCQUN4QjsrRUFZb0IsT0FBTztzQkFBekIsS0FBSzt1QkFBQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBpbmplY3QsIElucHV0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciwgVXJsVHJlZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBVcmxVdGlscyB9IGZyb20gJy4uLy4uL3NoYXJlZC9maWxlL3VybC51dGlscyc7XG5pbXBvcnQgeyBMb2NhdGlvblN0cmF0ZWd5IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGlzTm90TmlsT3JCbGFuayB9IGZyb20gJy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHsgTmF2Q29udHJvbGxlciB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7IERpc2NvdXJzZVV0aWxzIH0gZnJvbSAnLi9kaXNjb3Vyc2UvZGlzY291cnNlLnV0aWxzJztcbmltcG9ydCB7IFBsYXRmb3JtU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvc2VydmljZXMvcGxhdGZvcm0uc2VydmljZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ2ZlZWQsW2ZlZWRdJyxcbn0pXG5leHBvcnQgY2xhc3MgRmVlZERpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgX3N1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgcHJpdmF0ZSBwbGF0Zm9ybSA9IGluamVjdChQbGF0Zm9ybVNlcnZpY2UpO1xuICBwcml2YXRlIGxvY2F0aW9uU3RyYXRlZ3kgPSBpbmplY3QoTG9jYXRpb25TdHJhdGVneSk7XG4gIHByaXZhdGUgbmF2Q29udHJvbGxlciA9IGluamVjdChOYXZDb250cm9sbGVyKTtcbiAgcHJpdmF0ZSByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcbiAgcHJpdmF0ZSByb3V0ZSA9IGluamVjdChBY3RpdmF0ZWRSb3V0ZSk7XG5cbiAgcHJpdmF0ZSBfZmVlZFVybDogc3RyaW5nO1xuICBwcml2YXRlIF9iYXNlVXJsOiBzdHJpbmc7XG5cbiAgQElucHV0KCdmZWVkJykgc2V0IGZlZWRVcmwodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuX2ZlZWRVcmwgPSB2YWx1ZTtcbiAgICB0aGlzLl9iYXNlVXJsID0gdmFsdWUgJiYgRGlzY291cnNlVXRpbHMucmVtb3ZlSnNvbkV4dGVuc2lvbih2YWx1ZSk7XG4gIH1cblxuICBnZXQgZmVlZFVybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9mZWVkVXJsO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pikge1xuICAgIC8vIERFQlVHXG4gICAgLy9jb25zb2xlLmRlYnVnKCdbZmVlZC1kaXJlY3RpdmVdIENyZWF0aW5nIGZlZWQgZGlyZWN0aXZlJyk7XG4gIH1cblxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGNvbnNvbGUuZGVidWcoJ1tmZWVkLWRpcmVjdGl2ZV0gUHJvY2Vzc2luZyBhbmNob3JzJyk7XG4gICAgLy8gTGlzdGVuaW5nIGNsaWNrIGV2ZW50c1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQodGhpcy5saXN0ZW5DbGlja0V2ZW50cyh0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgbGlzdGVuQ2xpY2tFdmVudHMobmF0aXZlRWxlbWVudDogSFRNTEVsZW1lbnQpOiBTdWJzY3JpcHRpb24ge1xuICAgIGNvbnNvbGUuZGVidWcoJ1tmZWVkLWRpcmVjdGl2ZV0gU3RhcnQgbGlzdGVuaW5nIGNsaWNrIGV2ZW50cy4uLicpO1xuICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgICBjb25zdCBsaXN0ZW5lciA9IChldmVudDogRXZlbnQpID0+IHRoaXMuY2xpY2soZXZlbnQsIG5hdGl2ZUVsZW1lbnQpO1xuICAgIGNvbnN0IGxpbmtzID0gbmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdhJyk7XG4gICAgbGlua3MuZm9yRWFjaCgobGluaykgPT4ge1xuICAgICAgLy8gREVCVUdcbiAgICAgIC8vY29uc29sZS5kZWJ1ZygnW2ZlZWQtZGlyZWN0aXZlXSBBZGRpbmcgY2xpY2sgbGlzdGVuZXIgdG8nLCBsaW5rKTtcbiAgICAgIGxpbmsuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsaXN0ZW5lcik7XG4gICAgICBzdWJzY3JpcHRpb24uYWRkKCgpID0+IGxpbmsucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBsaXN0ZW5lcikpO1xuICAgIH0pO1xuXG4gICAgLy8gREVCVUdcbiAgICBzdWJzY3JpcHRpb24uYWRkKCgpID0+IGNvbnNvbGUuZGVidWcoJ1tmZWVkLWRpcmVjdGl2ZV0gU3RvcCBsaXN0ZW5pbmcgY2xpY2sgZXZlbnRzJykpO1xuXG4gICAgcmV0dXJuIHN1YnNjcmlwdGlvbjtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBjbGljayhldmVudDogRXZlbnQsIGNvbnRhaW5lckVsZW1lbnQ6IEhUTUxFbGVtZW50KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc29sZS5kZWJ1ZygnW2ZlZWQtZGlyZWN0aXZlXSBQcm9jZXNzaW5nIGNsaWNrIGV2ZW50Li4uJywgZXZlbnQpO1xuXG4gICAgaWYgKCEoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEFuY2hvckVsZW1lbnQpICYmICEoZXZlbnQudGFyZ2V0Py5bJ3RhZ05hbWUnXSA9PT0gJ0EnKSkge1xuICAgICAgY29uc29sZS53YXJuKCdbZmVlZC1kaXJlY3RpdmVdIEludmFsaWQgY2xpY2sgZXZlbnQgdGFyZ2V0LiBTaG91bGQgYW4gYW5jaG9yIDxhPicsIGV2ZW50LnRhcmdldCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MQW5jaG9yRWxlbWVudDtcblxuICAgIGxldCBocmVmID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKTtcbiAgICBjb25zdCBmcmFnbWVudCA9IFVybFV0aWxzLmdldEZyYWdtZW50KGhyZWYpO1xuXG4gICAgLy8gRnJhZ21lbnRcbiAgICBpZiAoaHJlZj8uc3RhcnRzV2l0aCgnIycpICYmIGlzTm90TmlsT3JCbGFuayhmcmFnbWVudCkpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLnNjcm9sbFRvQW5jaG9yKGNvbnRhaW5lckVsZW1lbnQsIGZyYWdtZW50KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHJvdXRlckxpbmsgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgncm91dGVyTGluaycpO1xuICAgIGlmIChpc05vdE5pbE9yQmxhbmsocm91dGVyTGluaykpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICByZXR1cm4gdGhpcy5uYXZDb250cm9sbGVyLm5hdmlnYXRlRm9yd2FyZChyb3V0ZXJMaW5rKTtcbiAgICB9XG5cbiAgICAvLyBSZXNvbHZlIHJlbGF0aXZlIFVSTCwgaWYgYmFzZVVybCBoYXMgYmVlbiBzZXRcbiAgICBpZiAodGhpcy5fYmFzZVVybCAmJiBVcmxVdGlscy5pc1JlbGF0aXZlVXJsKGhyZWYpKSB7XG4gICAgICAvLyBSZXNvbHZlIFVSTCwgdGhlbiBvcGVuIHVzaW5nIHRoZSBwbGF0Zm9ybVxuICAgICAgaHJlZiA9IFVybFV0aWxzLnJlc29sdmVSZWxhdGl2ZVVybCh0aGlzLl9iYXNlVXJsLCBocmVmKTtcbiAgICB9XG5cbiAgICAvLyBSZXNvbHZlIGludGVybmFsIFVSTCBhcyBhbiBhcHAgcm91dGVcbiAgICBpZiAoVXJsVXRpbHMuaXNJbnRlcm5hbFVybChocmVmKSkge1xuICAgICAgY29uc3Qgcm91dGVQYXRoID0gdGhpcy5ub3JtYWxpemVVcmwoaHJlZi5zdGFydHNXaXRoKCcvJykgPyBocmVmIDogYC8ke2hyZWZ9YCk7XG4gICAgICBjb25zdCB1cmxUcmVlID0gdGhpcy5nZXRVcmxUcmVlKHJvdXRlUGF0aCk7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGVkID0gZmFsc2U7XG4gICAgICAvLyBPcGVuaW5nIHJvdXRlXG4gICAgICByZXR1cm4gdGhpcy5uYXZDb250cm9sbGVyLm5hdmlnYXRlRm9yd2FyZCh1cmxUcmVlKTtcbiAgICB9XG5cbiAgICAvLyBFeHRlcm5hbCBVUkw6IG9wZW4gdXNpbmcgdGhlIHBsYXRmb3JtXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBhd2FpdCB0aGlzLnBsYXRmb3JtLm9wZW4oaHJlZik7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzY3JvbGxUb0FuY2hvcihjb250YWluZXJFbGVtZW50OiBIVE1MRWxlbWVudCwgYW5jaG9ySWQ6IHN0cmluZykge1xuICAgIGlmICghY29udGFpbmVyRWxlbWVudCB8fCAhYW5jaG9ySWQpIHtcbiAgICAgIGNvbnNvbGUud2FybihcIk1pc3NpbmcgJ2NvbnRhaW5lckVsZW1lbnQnIG9yICdmcmFnbWVudCcgYXJndW1lbnQuXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnNvbGUuZGVidWcoJ1tmZWVkLWRpcmVjdGl2ZS1hbmNob3JdIFNjcm9sbGluZyB0byBhbmNob3IgIycgKyBhbmNob3JJZCk7XG5cbiAgICAvLyBGaW5kIHRoZSB0YXJnZXQgZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgZnJhZ21lbnQgSURcbiAgICBjb25zdCB0YXJnZXRFbGVtZW50ID0gY29udGFpbmVyRWxlbWVudC5xdWVyeVNlbGVjdG9yKGAjJHthbmNob3JJZH1gKTtcblxuICAgIGlmICh0YXJnZXRFbGVtZW50KSB7XG4gICAgICAvLyBTY3JvbGwgc21vb3RobHkgdG8gdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHJ4LWFuZ3VsYXIvcHJlZmVyLW5vLWxheW91dC1zZW5zaXRpdmUtYXBpc1xuICAgICAgdGFyZ2V0RWxlbWVudC5zY3JvbGxJbnRvVmlldyh7XG4gICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJywgLy8gU21vb3RoIHNjcm9sbGluZyBiZWhhdmlvclxuICAgICAgICBibG9jazogJ3N0YXJ0JywgLy8gQWxpZ24gdGhlIHRhcmdldCBlbGVtZW50IHRvIHRoZSB0b3Agb2YgdGhlIGNvbnRhaW5lclxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybihgTm8gZWxlbWVudCBmb3VuZCB3aXRoIHRoZSBJRCBcIiR7YW5jaG9ySWR9XCIgaW5zaWRlIHRoZSBjb250YWluZXIuYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zZm9ybSBhIHJlbGF0aXZlIFVSTCB0byBpdHMgYWJzb2x1dGUgcmVwcmVzZW50YXRpb24gYWNjb3JkaW5nIHRvIGN1cnJlbnQgcm91dGVyIHN0YXRlLlxuICAgKiBAcGFyYW0gdXJsIFJlbGF0aXZlIFVSTCBwYXRoLlxuICAgKiBAcmV0dXJuIEFic29sdXRlIFVSTCBiYXNlZCBvbiB0aGUgY3VycmVudCByb3V0ZS5cbiAgICovXG4gIG5vcm1hbGl6ZVVybCh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKFVybFV0aWxzLmlzRXh0ZXJuYWxVcmwodXJsKSkge1xuICAgICAgcmV0dXJuIHVybDtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2Jhc2VVcmwgJiYgVXJsVXRpbHMuaXNSZWxhdGl2ZVVybCh1cmwpKSB7XG4gICAgICByZXR1cm4gVXJsVXRpbHMucmVzb2x2ZVJlbGF0aXZlVXJsKHRoaXMuX2Jhc2VVcmwsIHVybCk7XG4gICAgfVxuXG4gICAgY29uc3QgdXJsVHJlZSA9IHRoaXMuZ2V0VXJsVHJlZSh1cmwpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRVcmwgPSB0aGlzLnJvdXRlci5zZXJpYWxpemVVcmwodXJsVHJlZSk7XG4gICAgcmV0dXJuIHRoaXMubG9jYXRpb25TdHJhdGVneS5wcmVwYXJlRXh0ZXJuYWxVcmwoc2VyaWFsaXplZFVybCk7XG4gIH1cblxuICBnZXRVcmxUcmVlKHVybDogc3RyaW5nKTogVXJsVHJlZSB7XG4gICAgdXJsID0gVXJsVXRpbHMubm9ybWFsaXplVXJsKHVybCk7XG4gICAgY29uc3QgdXJsUGF0aCA9IFVybFV0aWxzLnN0cmlwRnJhZ21lbnRBbmRRdWVyeSh1cmwpIHx8IFVybFV0aWxzLnN0cmlwRnJhZ21lbnRBbmRRdWVyeSh0aGlzLnJvdXRlci51cmwpO1xuICAgIGNvbnN0IHBhcnNlZFVybCA9IHRoaXMucm91dGVyLnBhcnNlVXJsKHVybCk7XG4gICAgY29uc3QgZnJhZ21lbnQgPSBwYXJzZWRVcmwuZnJhZ21lbnQ7XG4gICAgY29uc3QgcXVlcnlQYXJhbXMgPSBwYXJzZWRVcmwucXVlcnlQYXJhbXM7XG4gICAgcmV0dXJuIHRoaXMucm91dGVyLmNyZWF0ZVVybFRyZWUoW3VybFBhdGhdLCB7IHJlbGF0aXZlVG86IHRoaXMucm91dGUsIGZyYWdtZW50LCBxdWVyeVBhcmFtcyB9KTtcbiAgfVxufVxuIl19