Skip to content

Commit 9d384fe

Browse files
authored
feat: improve feed directory UI with default parameter handling (#940)
1 parent b7e4094 commit 9d384fe

File tree

6 files changed

+149
-39
lines changed

6 files changed

+149
-39
lines changed

.gitignore

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
_data/configs.yml
12
_site
2-
.sass-cache
33
.jekyll-cache
44
.jekyll-metadata
5-
vendor
5+
.sass-cache
6+
node_modules
67
node_modules/
7-
_data/configs.yml
8+
vendor

Gemfile.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
GIT
22
remote: https://github.com/html2rss/html2rss-configs.git
3-
revision: 65cf54c8b5c5516cfb78f812a4745771052fcf9a
3+
revision: d7c60ffee7747afe425240bae539cdf71ad356f5
44
specs:
55
html2rss-configs (0.2.0)
66
html2rss
77

88
GIT
99
remote: https://github.com/html2rss/html2rss.git
10-
revision: 8bddc59e845adb45861b89f21d95e7f5595b3813
10+
revision: 3071d18755e3f546aa35bccfdaa83694c61a475c
1111
specs:
1212
html2rss (0.17.0)
1313
addressable (~> 2.7)
@@ -160,7 +160,7 @@ GEM
160160
mime-types (3.7.0)
161161
logger
162162
mime-types-data (~> 3.2025, >= 3.2025.0507)
163-
mime-types-data (3.2025.0902)
163+
mime-types-data (3.2025.0909)
164164
net-http (0.6.0)
165165
uri
166166
nokogiri (1.18.9-aarch64-linux-gnu)
@@ -190,7 +190,7 @@ GEM
190190
regexp_parser (2.11.2)
191191
reverse_markdown (3.0.0)
192192
nokogiri
193-
rexml (3.4.3)
193+
rexml (3.4.4)
194194
rouge (4.6.0)
195195
rss (0.3.1)
196196
rexml

assets/css/sass/feed-directory.scss

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@
1616
.feed-directory__item {
1717
display: flex;
1818
justify-content: space-between;
19-
align-items: baseline;
19+
align-items: flex-start;
2020
gap: var(--spacing-sm);
2121

2222
padding: var(--spacing-sm);
2323
border: 1px solid var(--border-color);
2424
border-radius: var(--border-radius);
25+
margin-bottom: 1px; /* Minimal gap between items */
2526

2627
transition: var(--transition-base);
28+
background-color: var(--color-bg);
2729
}
2830

2931
.feed-directory__item:hover {
@@ -38,12 +40,51 @@
3840
margin-inline-end: var(--spacing-sm);
3941
}
4042

43+
.feed-directory__item-main {
44+
display: flex;
45+
justify-content: space-between;
46+
align-items: center;
47+
gap: var(--spacing-sm);
48+
min-height: 2rem; /* Compact height for list feel */
49+
}
50+
4151
h3.feed-directory__item-name {
4252
font-size: var(--font-size-h4);
4353
font-weight: var(--font-weight-bold);
4454
color: var(--color-text);
4555
margin: 0;
4656
padding: 0;
57+
flex: 1;
58+
min-width: 0; /* Allow text to wrap */
59+
line-height: 1.4;
60+
}
61+
62+
.feed-directory__item-param-toggle {
63+
display: flex;
64+
align-items: center;
65+
gap: var(--spacing-xs);
66+
font-size: var(--font-size-xs);
67+
font-weight: var(--font-weight-normal);
68+
color: var(--color-text-light);
69+
background-color: var(--code-block-bg-color);
70+
padding: var(--spacing-xs) var(--spacing-sm);
71+
border-radius: var(--border-radius-sm);
72+
border: 1px solid var(--border-color);
73+
white-space: nowrap;
74+
cursor: pointer;
75+
transition: var(--transition-base);
76+
flex-shrink: 0;
77+
}
78+
79+
.feed-directory__item-param-toggle:hover {
80+
background-color: var(--border-color);
81+
color: var(--color-text);
82+
}
83+
84+
.feed-directory__param-icon {
85+
width: 14px;
86+
height: 14px;
87+
flex-shrink: 0;
4788
}
4889

4990
.feed-directory__item-url {
@@ -100,9 +141,23 @@ h3.feed-directory__item-name {
100141
}
101142

102143
.feed-directory__item-param-form {
103-
margin-block-start: var(--spacing-sm);
104-
padding-block-start: var(--spacing-sm);
105-
border-block-start: 1px solid var(--border-color);
144+
margin-top: var(--spacing-xs);
145+
padding: var(--spacing-xs);
146+
border-top: 1px solid var(--border-color);
147+
background-color: var(--code-block-bg-color);
148+
border-radius: var(--border-radius-sm);
149+
animation: slideDown 0.2s ease-out;
150+
}
151+
152+
@keyframes slideDown {
153+
from {
154+
opacity: 0;
155+
transform: translateY(-10px);
156+
}
157+
to {
158+
opacity: 1;
159+
transform: translateY(0);
160+
}
106161
}
107162

108163
.feed-directory__item-param-form__group {

assets/js/feed-directory/index.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,36 @@ document.addEventListener("alpine:init", () => {
6868
});
6969
},
7070

71+
initializeDefaultParameters() {
72+
Object.entries(this.config.url_parameters).forEach(([key, fallback]) => {
73+
const inputId = `${this.config.domain}-${this.config.name}-${key}`;
74+
const input = document.getElementById(inputId);
75+
76+
if (input && this.config.default_parameters[key]) {
77+
// Set the actual value in the input field
78+
input.value = this.config.default_parameters[key];
79+
// Also set placeholder as fallback
80+
input.placeholder = this.config.default_parameters[key];
81+
}
82+
});
83+
84+
// Now set params with default values (this will trigger the watcher)
85+
this.params = { ...this.config.default_parameters };
86+
},
87+
7188
init() {
7289
if (!this.config) return;
90+
91+
// Initialize params first
92+
this.params = {};
93+
94+
// Set default values in input fields after DOM is ready
95+
if (this.config.default_parameters && !this.config.valid_channel_url) {
96+
this.$nextTick(() => {
97+
this.initializeDefaultParameters();
98+
});
99+
}
100+
73101
if (!this.config.valid_channel_url) {
74102
this.$watch("params", (value) => {
75103
let params = {};

bin/data-update

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ require 'yaml'
1212

1313
file_names = Html2rss::Configs.file_names.sort
1414

15+
def extract_default_parameters(parameters)
16+
return {} unless parameters.is_a?(Hash)
17+
18+
parameters.each_with_object({}) do |(param_name, param_config), defaults|
19+
if param_config.is_a?(Hash) && param_config['default']
20+
defaults[param_name] = param_config['default']
21+
end
22+
end
23+
end
24+
1525
def valid_url(url)
1626
!!URI(url)
1727
rescue StandardError
@@ -34,11 +44,15 @@ output = file_names.map do |file_name|
3444

3545
file_name_splits = file_name.split('/')
3646

47+
# Extract default parameter values from the parameters section
48+
default_parameters = extract_default_parameters(config['parameters'])
49+
3750
{
3851
'domain' => file_name_splits[-2..-2].join,
3952
'name' => File.basename(file_name_splits[-1..].join, '.*'),
4053
'valid_channel_url' => valid_url(config['channel']['url']),
4154
'url_parameters' => string_formatting_references(config['channel']['url']),
55+
'default_parameters' => default_parameters,
4256
'channel' => config['channel']
4357
}
4458
end

feed-directory/index.html

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,47 @@ <h2 class="fs-6">Instance URL</h2>
8989
>
9090
<div class="feed-directory__item-info">
9191
{% if config.channel.url %}
92-
<h3 class="feed-directory__item-name">
93-
{% if config.valid_channel_url %}
94-
<a
95-
href="{{ config.channel.url | escape }}"
96-
target="_blank"
97-
rel="noopener noreferrer"
92+
<div class="feed-directory__item-main">
93+
<h3 class="feed-directory__item-name">
94+
{% if config.valid_channel_url %}
95+
<a
96+
href="{{ config.channel.url | escape }}"
97+
target="_blank"
98+
rel="noopener noreferrer"
99+
>
100+
{{ config.channel.url | escape }}
101+
</a>
102+
{% else %}
103+
<span x-show="!pathPreview">{{ config.channel.url | escape }}</span>
104+
<a
105+
x-bind:href="pathPreview"
106+
x-show="pathPreview"
107+
x-text="pathPreview"
108+
></a>
109+
{% endif %}
110+
</h3>
111+
{% unless config.valid_channel_url %}
112+
<button
113+
class="feed-directory__item-param-toggle"
114+
x-on:click="toggleParamsForm"
115+
:title="showParamsForm ? 'Hide parameters' : 'Configure parameters'"
116+
:aria-label="showParamsForm ? 'Hide parameters' : 'Configure parameters'"
98117
>
99-
{{ config.channel.url | escape }}
100-
</a>
101-
{% else %}
102-
<span x-show="!pathPreview">{{ config.channel.url | escape }}</span>
103-
<a
104-
x-bind:href="pathPreview"
105-
x-show="pathPreview"
106-
x-text="pathPreview"
107-
></a>
108-
{% endif %}
109-
</h3>
118+
<svg
119+
class="feed-directory__param-icon"
120+
viewBox="0 0 24 24"
121+
fill="none"
122+
stroke="currentColor"
123+
stroke-width="2"
124+
aria-hidden="true"
125+
>
126+
<circle cx="12" cy="12" r="3" />
127+
<path d="M12 1v6m0 6v6m11-7h-6m-6 0H1" />
128+
</svg>
129+
<span x-text="showParamsForm ? 'Hide' : 'Configure'"></span>
130+
</button>
131+
{% endunless %}
132+
</div>
110133
{% endif %} {% unless config.valid_channel_url %}
111134
<div class="feed-directory__item-param-form" x-show="showParamsForm">
112135
<form role="form">
@@ -153,23 +176,12 @@ <h3 class="feed-directory__item-name">
153176
</svg>
154177
</a>
155178
{% else %}
156-
<button
157-
x-show="!showParamsForm"
158-
x-on:click="toggleParamsForm"
159-
title="Start setting parameters and get the RSS URL"
160-
aria-label="Start setting parameters and get the RSS URL"
161-
>
162-
<svg class="feed-directory__item-actions__settings-icon">
163-
<use xlink:href="#settings-icon"></use>
164-
</svg>
165-
</button>
166179
<a
167180
:href="getFeedUrl(config, params)"
168181
rel="noopener noreferrer"
169182
target="_blank"
170183
title="Show RSS"
171184
aria-label="Open RSS feed"
172-
x-show="showParamsForm"
173185
>
174186
<svg class="feed-directory__item-actions__rss-icon">
175187
<use xlink:href="#rss-icon"></use>

0 commit comments

Comments
 (0)