@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.
- package/doc/changelog.md +4 -0
- package/doc/feed/feed-en.json +26 -0
- package/doc/feed/feed-fr.json +26 -0
- package/esm2022/public_api.mjs +9 -1
- package/esm2022/src/app/core/home/home.mjs +13 -12
- package/esm2022/src/app/core/home/home.module.mjs +7 -3
- package/esm2022/src/app/core/services/local-settings.service.mjs +3 -2
- package/esm2022/src/app/core/services/network.service.mjs +12 -1
- package/esm2022/src/app/social/feed/discourse/discourse-feed.service.mjs +179 -0
- package/esm2022/src/app/social/feed/discourse/discourse.model.mjs +2 -0
- package/esm2022/src/app/social/feed/discourse/discourse.utils.mjs +168 -0
- package/esm2022/src/app/social/feed/feed.component.mjs +121 -0
- package/esm2022/src/app/social/feed/feed.directive.mjs +151 -0
- package/esm2022/src/app/social/feed/feed.model.mjs +68 -0
- package/esm2022/src/app/social/feed/feed.module.mjs +22 -0
- package/esm2022/src/app/social/feed/feed.service.mjs +3 -0
- package/esm2022/src/environments/environment.class.mjs +2 -1
- package/esm2022/src/environments/environment.mjs +10 -1
- package/fesm2022/sumaris-net.ngx-components.mjs +681 -8
- package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +8 -0
- package/src/app/core/home/home.d.ts +1 -1
- package/src/app/core/home/home.module.d.ts +2 -1
- package/src/app/core/services/local-settings.service.d.ts +1 -0
- package/src/app/core/services/network.service.d.ts +1 -0
- package/src/app/social/feed/discourse/discourse-feed.service.d.ts +55 -0
- package/src/app/social/feed/discourse/discourse.model.d.ts +7 -0
- package/src/app/social/feed/discourse/discourse.utils.d.ts +44 -0
- package/src/app/social/feed/feed.component.d.ts +39 -0
- package/src/app/social/feed/feed.directive.d.ts +32 -0
- package/src/app/social/feed/feed.model.d.ts +69 -0
- package/src/app/social/feed/feed.module.d.ts +11 -0
- package/src/app/social/feed/feed.service.d.ts +13 -0
- package/src/assets/i18n/en-US.json +5 -1
- package/src/assets/i18n/en.json +5 -0
- package/src/assets/i18n/fr.json +5 -0
- 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 \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 \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
|