feeds-fun 1.16.5 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/DiscoveryForm.vue +3 -5
- package/src/components/EntriesList.vue +1 -11
- package/src/components/EntryForList.vue +54 -67
- package/src/components/FeedForList.vue +29 -64
- package/src/components/FeedInfo.vue +12 -14
- package/src/components/FeedsList.vue +2 -1
- package/src/components/OPMLUpload.vue +3 -3
- package/src/components/RuleConstructor.vue +12 -6
- package/src/components/RuleForList.vue +25 -24
- package/src/components/RulesList.vue +2 -1
- package/src/components/SimplePagination.vue +2 -2
- package/src/components/SupertokensLogin.vue +5 -6
- package/src/components/UserSetting.vue +7 -12
- package/src/components/UserSettingForNotification.vue +4 -3
- package/src/components/body_list/EntryBody.vue +43 -0
- package/src/components/body_list/FaviconColumn.vue +24 -0
- package/src/components/body_list/ReverseTimeColumn.vue +28 -0
- package/src/components/collections/Block.vue +1 -1
- package/src/components/collections/BlockItem.vue +4 -3
- package/src/components/collections/DetailedItem.vue +4 -10
- package/src/components/collections/FeedItem.vue +31 -24
- package/src/components/collections/Notification.vue +6 -8
- package/src/components/collections/SubscribingProgress.vue +14 -17
- package/src/components/collections/Warning.vue +36 -38
- package/src/components/main/Block.vue +5 -0
- package/src/components/main/Description.vue +51 -0
- package/src/components/main/HeaderLine.vue +7 -0
- package/src/components/main/Item.vue +27 -0
- package/src/components/main/NewsTitle.vue +26 -0
- package/src/components/notifications/ApiKey.vue +14 -5
- package/src/components/notifications/CreateRuleHelp.vue +10 -11
- package/src/components/page_header/ExternalLinks.vue +58 -0
- package/src/components/tags/Base.vue +28 -0
- package/src/components/tags/EntryTag.vue +73 -0
- package/src/components/{TagsList.vue → tags/EntryTagsList.vue} +8 -9
- package/src/components/tags/FakeTag.vue +35 -0
- package/src/components/tags/FilterTag.vue +114 -0
- package/src/components/tags/RuleTag.vue +67 -0
- package/src/components/{TagsFilter.vue → tags/TagsFilter.vue} +13 -7
- package/src/css/base.css +38 -0
- package/src/css/inputs.css +49 -0
- package/src/css/page_header.css +34 -0
- package/src/css/panels.css +49 -0
- package/src/css/side_panel_layout.css +34 -0
- package/src/css/tags.css +44 -0
- package/src/layouts/SidePanelLayout.vue +35 -91
- package/src/layouts/WideLayout.vue +5 -17
- package/src/logic/events.ts +23 -0
- package/src/logic/tagsFilterState.ts +14 -6
- package/src/logic/types.ts +16 -7
- package/src/logic/utils.ts +29 -0
- package/src/main.ts +42 -10
- package/src/style.css +10 -100
- package/src/values/DateTime.vue +1 -1
- package/src/values/{URL.vue → ExternalUrl.vue} +7 -6
- package/src/views/CollectionsView.vue +3 -6
- package/src/views/DiscoveryView.vue +9 -11
- package/src/views/FeedsView.vue +3 -2
- package/src/views/MainView.vue +189 -44
- package/src/views/NewsView.vue +2 -1
- package/src/views/RulesView.vue +6 -3
- package/src/views/SettingsView.vue +92 -33
- package/src/components/FfunTag.vue +0 -122
- package/src/inputs/Marker.vue +0 -54
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex my-1">
|
|
3
|
+
<div class="max-w-3xl flex-1 bg-white border rounded p-4">
|
|
4
|
+
<h2
|
|
5
|
+
v-if="url"
|
|
6
|
+
class="mt-0"
|
|
7
|
+
><a
|
|
8
|
+
:href="url"
|
|
9
|
+
target="_blank"
|
|
10
|
+
@click="emit('body-title-clicked')"
|
|
11
|
+
>{{ title }}</a
|
|
12
|
+
></h2
|
|
13
|
+
>
|
|
14
|
+
<p v-if="loading">loading…</p>
|
|
15
|
+
<div
|
|
16
|
+
v-if="text"
|
|
17
|
+
class="prose max-w-none"
|
|
18
|
+
v-html="text" />
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script lang="ts" setup>
|
|
24
|
+
import _ from "lodash";
|
|
25
|
+
import {computed, ref, useTemplateRef, onMounted} from "vue";
|
|
26
|
+
import type * as t from "@/logic/types";
|
|
27
|
+
import * as events from "@/logic/events";
|
|
28
|
+
import * as e from "@/logic/enums";
|
|
29
|
+
import {computedAsync} from "@vueuse/core";
|
|
30
|
+
import DOMPurify from "dompurify";
|
|
31
|
+
import {useEntriesStore} from "@/stores/entries";
|
|
32
|
+
|
|
33
|
+
const entriesStore = useEntriesStore();
|
|
34
|
+
|
|
35
|
+
const properties = defineProps<{
|
|
36
|
+
url: string | null;
|
|
37
|
+
title: string | null;
|
|
38
|
+
loading: boolean;
|
|
39
|
+
text: string | null;
|
|
40
|
+
}>();
|
|
41
|
+
|
|
42
|
+
const emit = defineEmits(["body-title-clicked"]);
|
|
43
|
+
</script>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex-shrink-0 w-8 text-right pr-1">
|
|
3
|
+
<favicon-element
|
|
4
|
+
:url="url"
|
|
5
|
+
class="w-5 h-5 mx-1 inline align-text-bottom" />
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script lang="ts" setup>
|
|
10
|
+
import _ from "lodash";
|
|
11
|
+
import {computed, ref, useTemplateRef, onMounted} from "vue";
|
|
12
|
+
import type * as t from "@/logic/types";
|
|
13
|
+
import * as events from "@/logic/events";
|
|
14
|
+
import * as e from "@/logic/enums";
|
|
15
|
+
import {computedAsync} from "@vueuse/core";
|
|
16
|
+
import DOMPurify from "dompurify";
|
|
17
|
+
import {useEntriesStore} from "@/stores/entries";
|
|
18
|
+
|
|
19
|
+
const entriesStore = useEntriesStore();
|
|
20
|
+
|
|
21
|
+
const properties = defineProps<{
|
|
22
|
+
url: string;
|
|
23
|
+
}>();
|
|
24
|
+
</script>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="flex-shrink-0 w-16 cursor-default text-right"
|
|
4
|
+
:title="title">
|
|
5
|
+
<value-date-time
|
|
6
|
+
class=""
|
|
7
|
+
:value="time"
|
|
8
|
+
:reversed="true" />
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script lang="ts" setup>
|
|
13
|
+
import _ from "lodash";
|
|
14
|
+
import {computed, ref, useTemplateRef, onMounted} from "vue";
|
|
15
|
+
import type * as t from "@/logic/types";
|
|
16
|
+
import * as events from "@/logic/events";
|
|
17
|
+
import * as e from "@/logic/enums";
|
|
18
|
+
import {computedAsync} from "@vueuse/core";
|
|
19
|
+
import DOMPurify from "dompurify";
|
|
20
|
+
import {useEntriesStore} from "@/stores/entries";
|
|
21
|
+
|
|
22
|
+
const entriesStore = useEntriesStore();
|
|
23
|
+
|
|
24
|
+
const properties = defineProps<{
|
|
25
|
+
time: Date | null;
|
|
26
|
+
title: string;
|
|
27
|
+
}>();
|
|
28
|
+
</script>
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
v-model="model"
|
|
10
10
|
checked />
|
|
11
11
|
<label
|
|
12
|
-
class="ml-2"
|
|
12
|
+
class="ml-2 inline-block"
|
|
13
13
|
:for="collection.id">
|
|
14
14
|
<div class="inline-block">
|
|
15
|
-
<span class="text-green-700 font-bold">{{ collection.name }}</span>
|
|
16
|
-
|
|
15
|
+
<span class="text-green-700 font-bold">{{ collection.name }}</span>
|
|
16
|
+
— {{ collection.feedsNumber }} feeds —
|
|
17
|
+
{{ collection.description }}
|
|
17
18
|
</div>
|
|
18
19
|
</label>
|
|
19
20
|
</div>
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
<p class="">{{ collection.description }}</p>
|
|
5
5
|
|
|
6
6
|
<div v-if="showFeeds">
|
|
7
|
-
<
|
|
7
|
+
<ul
|
|
8
8
|
v-for="feed in feeds"
|
|
9
9
|
:key="feed.url"
|
|
10
|
-
class="
|
|
10
|
+
class="ffun-body-list-entry">
|
|
11
11
|
<collections-feed-item :feed="feed" />
|
|
12
|
-
</
|
|
12
|
+
</ul>
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
15
|
<button
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
class="ffun-form-button mr-2">
|
|
18
18
|
<template v-if="collection.feedsNumber === 1"> Subscribe to 1 feed </template>
|
|
19
19
|
|
|
20
|
-
<template v-else> Subscribe to
|
|
20
|
+
<template v-else> Subscribe to {{ collection.feedsNumber }} feeds </template>
|
|
21
21
|
</button>
|
|
22
22
|
|
|
23
23
|
<button
|
|
@@ -107,9 +107,3 @@
|
|
|
107
107
|
{lazy: true}
|
|
108
108
|
);
|
|
109
109
|
</script>
|
|
110
|
-
|
|
111
|
-
<style scoped>
|
|
112
|
-
.collection-feed-block:not(:last-child) {
|
|
113
|
-
border-bottom-width: 1px;
|
|
114
|
-
}
|
|
115
|
-
</style>
|
|
@@ -1,39 +1,37 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex">
|
|
3
|
-
<div class="
|
|
2
|
+
<div class="flex text-lg">
|
|
3
|
+
<div class="ffun-body-list-icon-column">
|
|
4
4
|
<a
|
|
5
|
+
v-if="subscribed"
|
|
5
6
|
href="#"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class="text-
|
|
9
|
-
>subscribe</a
|
|
10
|
-
>
|
|
7
|
+
@click.prevent="feedsStore.unsubscribe(feed.id)"
|
|
8
|
+
title="Unsubscribe from this feed"
|
|
9
|
+
class="text-red-500 hover:text-red-600 ti ti-x" />
|
|
11
10
|
|
|
12
|
-
<
|
|
11
|
+
<a
|
|
13
12
|
v-else
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
href="#"
|
|
14
|
+
@click.prevent="feedsStore.subscribe(feed.url)"
|
|
15
|
+
title="Subscribe to this feed"
|
|
16
|
+
class="text-green-600 hover:text-green-700 ti ti-plus" />
|
|
17
17
|
</div>
|
|
18
18
|
|
|
19
|
-
<
|
|
20
|
-
<favicon-element
|
|
21
|
-
:url="feed.url"
|
|
22
|
-
class="w-4 h-4 align-text-bottom mx-1 inline" />
|
|
23
|
-
</div>
|
|
19
|
+
<body-list-favicon-column :url="feed.url" />
|
|
24
20
|
|
|
25
21
|
<div class="flex-grow">
|
|
26
|
-
<
|
|
22
|
+
<external-url
|
|
23
|
+
class="ffun-normal-link"
|
|
24
|
+
:url="feed.url"
|
|
25
|
+
:text="purifiedTitle" />
|
|
27
26
|
</div>
|
|
28
27
|
</div>
|
|
29
28
|
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
</div>
|
|
29
|
+
<body-list-entry-body
|
|
30
|
+
class="ml-8"
|
|
31
|
+
:url="null"
|
|
32
|
+
:title="null"
|
|
33
|
+
:loading="false"
|
|
34
|
+
:text="purifiedDescription" />
|
|
37
35
|
</template>
|
|
38
36
|
|
|
39
37
|
<script lang="ts" setup>
|
|
@@ -41,6 +39,7 @@
|
|
|
41
39
|
import type * as t from "@/logic/types";
|
|
42
40
|
import * as e from "@/logic/enums";
|
|
43
41
|
import * as api from "@/logic/api";
|
|
42
|
+
import * as utils from "@/logic/utils";
|
|
44
43
|
import {computedAsync} from "@vueuse/core";
|
|
45
44
|
import DOMPurify from "dompurify";
|
|
46
45
|
import {useEntriesStore} from "@/stores/entries";
|
|
@@ -57,6 +56,14 @@
|
|
|
57
56
|
const globalSettings = useGlobalSettingsStore();
|
|
58
57
|
|
|
59
58
|
const subscribed = computed(() => properties.feed.id in feedsStore.feeds);
|
|
59
|
+
|
|
60
|
+
const purifiedTitle = computed(() => {
|
|
61
|
+
return utils.purifyTitle({raw: properties.feed.title, default_: properties.feed.url});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const purifiedDescription = computed(() => {
|
|
65
|
+
return utils.purifyBody({raw: properties.feed.description, default_: "No description"});
|
|
66
|
+
});
|
|
60
67
|
</script>
|
|
61
68
|
|
|
62
69
|
<style scoped></style>
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="ffun-info-
|
|
3
|
-
<
|
|
4
|
-
<p
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<p>Subscribe to some and enjoy the full power of Feeds Fun!</p>
|
|
9
|
-
<collections-block />
|
|
2
|
+
<div class="ffun-info-common">
|
|
3
|
+
<h4>Subscribe to curated collections</h4>
|
|
4
|
+
<p>We've prepared thematic collections just for you.</p>
|
|
5
|
+
<p>News from collections are always tagged, ensuring you get the full power of Feeds Fun!</p>
|
|
6
|
+
|
|
7
|
+
<collections-block class="mt-4" />
|
|
10
8
|
</div>
|
|
11
9
|
</template>
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
>
|
|
8
|
-
|
|
9
|
-
<p
|
|
10
|
-
v-if="loaded"
|
|
11
|
-
class="ffun-info-good"
|
|
12
|
-
>Feeds added!</p
|
|
13
|
-
>
|
|
2
|
+
<div
|
|
3
|
+
v-if="loading"
|
|
4
|
+
class="ffun-info-waiting mt-4">
|
|
5
|
+
<p>Subscribing…</p>
|
|
6
|
+
</div>
|
|
14
7
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
8
|
+
<div
|
|
9
|
+
v-if="loaded"
|
|
10
|
+
class="ffun-info-good mt-4"
|
|
11
|
+
><p>Feeds added!</p>
|
|
12
|
+
</div>
|
|
13
|
+
<div
|
|
14
|
+
v-if="error"
|
|
15
|
+
class="ffun-info-bad mt-4"
|
|
16
|
+
><p>Unknown error occurred! Please, try later.</p>
|
|
20
17
|
</div>
|
|
21
18
|
</template>
|
|
22
19
|
|
|
@@ -1,54 +1,52 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="ffun-info-
|
|
3
|
-
<
|
|
2
|
+
<div class="ffun-info-common">
|
|
3
|
+
<h4>Pay attention to your feed URLs</h4>
|
|
4
|
+
|
|
5
|
+
<p>
|
|
6
|
+
Some websites, like
|
|
7
|
+
<external-url
|
|
8
|
+
url="https://www.reddit.com"
|
|
9
|
+
text="Reddit" />
|
|
4
10
|
|
|
5
|
-
<p
|
|
6
|
-
>Websites like
|
|
7
|
-
<a
|
|
8
|
-
href="https://reddit.com"
|
|
9
|
-
target="_blank"
|
|
10
|
-
>Reddit</a
|
|
11
|
-
>
|
|
12
11
|
or
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
>
|
|
18
|
-
provide multiple feeds by:</p
|
|
19
|
-
>
|
|
12
|
+
<external-url
|
|
13
|
+
url="https://arxiv.org"
|
|
14
|
+
text="arXiv" />, provide multiple URLs for feeds:
|
|
15
|
+
</p>
|
|
20
16
|
|
|
21
17
|
<ul>
|
|
22
|
-
<li
|
|
23
|
-
|
|
24
|
-
<code class="inline-block">https://
|
|
25
|
-
|
|
26
|
-
>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<code class="inline-block">https://
|
|
30
|
-
>
|
|
18
|
+
<li>
|
|
19
|
+
By customizing the list of categories, like
|
|
20
|
+
<code class="inline-block">https://example.org/feed/rss?category1+category2</code>.
|
|
21
|
+
</li>
|
|
22
|
+
<li>
|
|
23
|
+
By supporting different feed formats, like
|
|
24
|
+
<code class="inline-block">https://example.org/feed/rss</code> and
|
|
25
|
+
<code class="inline-block">https://example.org/feed/atom</code>.
|
|
26
|
+
</li>
|
|
31
27
|
</ul>
|
|
32
28
|
|
|
33
|
-
<p
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
<p> Consequently, the same news may appear in multiple feeds. </p>
|
|
30
|
+
|
|
31
|
+
<p>
|
|
32
|
+
We do our best to detect duplicates, but in some cases, they may slip through and lead to extra usage of your API
|
|
33
|
+
key.
|
|
34
|
+
</p>
|
|
37
35
|
|
|
38
|
-
<p><strong>
|
|
36
|
+
<p><strong>Please follow these recommendations:</strong></p>
|
|
39
37
|
|
|
40
38
|
<ul>
|
|
41
|
-
<li>Use
|
|
42
|
-
<li
|
|
43
|
-
|
|
39
|
+
<li>Use short, granular feed URLs.</li>
|
|
40
|
+
<li>If a feed URL can be split into multiple simpler URLs, add them separately.</li>
|
|
41
|
+
<li>
|
|
42
|
+
Add feeds directly from
|
|
44
43
|
<a
|
|
45
|
-
class="ffun-normal-link"
|
|
46
44
|
href="#"
|
|
47
|
-
@click.prevent="goToCollections()"
|
|
48
|
-
|
|
45
|
+
@click.prevent="goToCollections()">
|
|
46
|
+
collections</a
|
|
49
47
|
>
|
|
50
|
-
instead of using URLs from
|
|
51
|
-
>
|
|
48
|
+
instead of using URLs from websites.
|
|
49
|
+
</li>
|
|
52
50
|
</ul>
|
|
53
51
|
|
|
54
52
|
<user-setting-for-notification
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- PC -->
|
|
3
|
+
<div class="hidden md:flex items-stretch rounded-xl overflow-hidden min-h-28 max-h-28 mx-2">
|
|
4
|
+
<div class="w-12 bg-blue-200 flex items-center justify-center text-4xl font-bold">
|
|
5
|
+
<i :class="['ti', icon]"></i>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<div class="w-1/3 bg-blue-100 px-4 flex items-center text-xl font-medium">
|
|
9
|
+
<slot name="caption" />
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div class="flex-1 bg-slate-100 p-6 text-gray-800 flex items-center">
|
|
13
|
+
<div class="w-full">
|
|
14
|
+
<slot name="description" />
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<!-- Mobile -->
|
|
20
|
+
<div class="flex flex-col md:hidden flex items-stretch rounded-xl overflow-hidden min-h-28 max-h-28 mx-2">
|
|
21
|
+
<div class="w-full flex">
|
|
22
|
+
<div class="w-12 bg-blue-200 flex items-center justify-center text-lg font-bold">
|
|
23
|
+
<i :class="['ti', icon]"></i>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div class="flex-grow bg-blue-100 px-4 flex justify-center text-lg font-medium">
|
|
27
|
+
<slot name="caption" />
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div class="flex-1 bg-slate-100 px-4 text-gray-800 flex items-center">
|
|
32
|
+
<div class="w-full">
|
|
33
|
+
<slot name="description" />
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script lang="ts" setup>
|
|
40
|
+
import * as t from "@/logic/types";
|
|
41
|
+
import {computed, ref, inject} from "vue";
|
|
42
|
+
import type {Ref} from "vue";
|
|
43
|
+
import {useTagsStore} from "@/stores/tags";
|
|
44
|
+
import * as tagsFilterState from "@/logic/tagsFilterState";
|
|
45
|
+
import * as asserts from "@/logic/asserts";
|
|
46
|
+
import * as events from "@/logic/events";
|
|
47
|
+
|
|
48
|
+
const properties = defineProps<{
|
|
49
|
+
icon: string;
|
|
50
|
+
}>();
|
|
51
|
+
</script>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-col items-stretch rounded-xl overflow-hidden min-h-28 max-h-28 mx-2">
|
|
3
|
+
<div class="bg-blue-100 py-1 items-center text-xl font-medium">
|
|
4
|
+
<slot name="caption" />
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div class="flex-1 bg-slate-100 p-2 text-gray-800 flex items-center">
|
|
8
|
+
<div class="">
|
|
9
|
+
<slot name="description" />
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script lang="ts" setup>
|
|
16
|
+
import * as t from "@/logic/types";
|
|
17
|
+
import {computed, ref, inject} from "vue";
|
|
18
|
+
import type {Ref} from "vue";
|
|
19
|
+
import {useTagsStore} from "@/stores/tags";
|
|
20
|
+
import * as tagsFilterState from "@/logic/tagsFilterState";
|
|
21
|
+
import * as asserts from "@/logic/asserts";
|
|
22
|
+
import * as events from "@/logic/events";
|
|
23
|
+
|
|
24
|
+
const properties = defineProps<{
|
|
25
|
+
icon: string;
|
|
26
|
+
}>();
|
|
27
|
+
</script>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="block text-base md:text-lg">
|
|
3
|
+
<span
|
|
4
|
+
v-if="score"
|
|
5
|
+
class="cursor-pointer text-purple-700 inline-block w-12"
|
|
6
|
+
>{{ score }}</span
|
|
7
|
+
>
|
|
8
|
+
|
|
9
|
+
<span class="font-bold">{{ title }}</span>
|
|
10
|
+
</span>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script lang="ts" setup>
|
|
14
|
+
import * as t from "@/logic/types";
|
|
15
|
+
import {computed, ref, inject} from "vue";
|
|
16
|
+
import type {Ref} from "vue";
|
|
17
|
+
import {useTagsStore} from "@/stores/tags";
|
|
18
|
+
import * as tagsFilterState from "@/logic/tagsFilterState";
|
|
19
|
+
import * as asserts from "@/logic/asserts";
|
|
20
|
+
import * as events from "@/logic/events";
|
|
21
|
+
|
|
22
|
+
const properties = defineProps<{
|
|
23
|
+
title: string;
|
|
24
|
+
score: number | null;
|
|
25
|
+
}>();
|
|
26
|
+
</script>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="ffun-info-
|
|
2
|
+
<div class="ffun-info-common">
|
|
3
|
+
<h4>Setup API keys</h4>
|
|
4
|
+
|
|
3
5
|
<p>
|
|
4
6
|
Please
|
|
5
7
|
<a
|
|
@@ -7,17 +9,24 @@
|
|
|
7
9
|
@click.prevent="goToSettings()"
|
|
8
10
|
>set up</a
|
|
9
11
|
>
|
|
10
|
-
your own
|
|
12
|
+
your own
|
|
13
|
+
<external-url
|
|
14
|
+
url="https://platform.openai.com/docs/api-reference/introduction"
|
|
15
|
+
text="OpenAI" />
|
|
16
|
+
or
|
|
17
|
+
<external-url
|
|
18
|
+
url="https://ai.google.dev/gemini-api/docs/api-key"
|
|
19
|
+
text="Gemini" />
|
|
20
|
+
API keys to tag your personal feeds.
|
|
11
21
|
</p>
|
|
12
22
|
|
|
13
23
|
<p>
|
|
14
|
-
Remember, Feeds Fun provides tags for feeds from
|
|
15
24
|
<a
|
|
16
25
|
href="#"
|
|
17
26
|
@click.prevent="goToCollections()"
|
|
18
|
-
>
|
|
27
|
+
>Collection</a
|
|
19
28
|
>
|
|
20
|
-
|
|
29
|
+
feeds are tagged automatically, so no actions are required for them.
|
|
21
30
|
</p>
|
|
22
31
|
|
|
23
32
|
<user-setting-for-notification
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="ffun-info-
|
|
3
|
-
<
|
|
4
|
-
|
|
2
|
+
<div class="ffun-info-common">
|
|
3
|
+
<h4>Create your first rule</h4>
|
|
4
|
+
|
|
5
5
|
<ol class="list-decimal list-inside">
|
|
6
|
-
<li><strong>Click</strong>
|
|
7
|
-
<li>See how news
|
|
8
|
-
<li>Locate the <strong>Create Rule</strong> panel in the left sidebar.</li>
|
|
6
|
+
<li><strong>Click on a tag</strong> that interests you.</li>
|
|
7
|
+
<li>See how Feeds Fun filters news based on the selected tag.</li>
|
|
9
8
|
<li>
|
|
10
|
-
Assign a
|
|
9
|
+
<strong>Assign a score</strong> to the filtered news in the "Create Rule" block in the left sidebar:
|
|
11
10
|
<ul>
|
|
12
|
-
<li>Use
|
|
13
|
-
<li>Use
|
|
11
|
+
<li>Use positive scores for important or engaging content.</li>
|
|
12
|
+
<li>Use negative scores for irrelevant or boring content.</li>
|
|
14
13
|
</ul>
|
|
15
14
|
</li>
|
|
16
|
-
<li>Click
|
|
17
|
-
<li>
|
|
15
|
+
<li><strong>Click the "Create Rule" button</strong>.</li>
|
|
16
|
+
<li>See how Feeds Fun reorganizes news based on your rule.</li>
|
|
18
17
|
</ol>
|
|
19
18
|
</div>
|
|
20
19
|
</template>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<a
|
|
3
|
+
v-if="showApi"
|
|
4
|
+
href="/api/docs"
|
|
5
|
+
target="_blank"
|
|
6
|
+
class="ffun-page-header-link"
|
|
7
|
+
@click="events.socialLinkClicked({linkType: 'api'})"
|
|
8
|
+
>API</a
|
|
9
|
+
>
|
|
10
|
+
|
|
11
|
+
<a
|
|
12
|
+
v-if="settings.blog"
|
|
13
|
+
:href="settings.blog"
|
|
14
|
+
target="_blank"
|
|
15
|
+
class="ffun-page-header-link"
|
|
16
|
+
@click="events.socialLinkClicked({linkType: 'blog'})"
|
|
17
|
+
>Blog</a
|
|
18
|
+
>
|
|
19
|
+
|
|
20
|
+
<a
|
|
21
|
+
v-if="settings.redditSubreddit"
|
|
22
|
+
:href="settings.redditSubreddit"
|
|
23
|
+
target="_blank"
|
|
24
|
+
class="ffun-page-header-link text-xl align-middle"
|
|
25
|
+
title="Reddit"
|
|
26
|
+
@click="events.socialLinkClicked({linkType: 'reddit'})"
|
|
27
|
+
><i class="ti ti-brand-reddit"></i
|
|
28
|
+
></a>
|
|
29
|
+
|
|
30
|
+
<a
|
|
31
|
+
v-if="settings.discordInvite"
|
|
32
|
+
:href="settings.discordInvite"
|
|
33
|
+
target="_blank"
|
|
34
|
+
class="ffun-page-header-link text-xl align-middle"
|
|
35
|
+
title="Discord"
|
|
36
|
+
@click="events.socialLinkClicked({linkType: 'discord'})"
|
|
37
|
+
><i class="ti ti-brand-discord"></i
|
|
38
|
+
></a>
|
|
39
|
+
|
|
40
|
+
<a
|
|
41
|
+
v-if="settings.githubRepo"
|
|
42
|
+
:href="settings.githubRepo"
|
|
43
|
+
target="_blank"
|
|
44
|
+
class="ffun-page-header-link text-xl align-middle"
|
|
45
|
+
title="GitHub"
|
|
46
|
+
@click="events.socialLinkClicked({linkType: 'github'})">
|
|
47
|
+
<i class="ti ti-brand-github"></i
|
|
48
|
+
></a>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<script lang="ts" setup>
|
|
52
|
+
import {ref, computed, useSlots, onMounted, watch, watchEffect} from "vue";
|
|
53
|
+
|
|
54
|
+
import * as events from "@/logic/events";
|
|
55
|
+
import * as settings from "@/logic/settings";
|
|
56
|
+
|
|
57
|
+
const properties = defineProps<{showApi: boolean}>();
|
|
58
|
+
</script>
|