diff --git a/de_DE.json b/de_DE.json
index 8b23cbf..0d183cf 100644
--- a/de_DE.json
+++ b/de_DE.json
@@ -16,9 +16,12 @@
"Repository": "Repository",
"API Token": "API Token",
"PR Filter": "PR-Filter",
+ "Your Repositories": "Eigene Repositories",
"Assigned to me": "Mir zugewiesen",
+ "Created by me": "Von mir erstellt",
"Review requested": "Review angefordert",
- "Both": "Beides",
+ "Reviewed by me": "Von mir bewertet",
+ "Mentioned me": "Hat mich erwähnt",
"Server": "Server",
"Last Rised": "Letzter Anstieg",
"Pull Requests": "Pull Requests",
diff --git a/en.json b/en.json
index f112ab7..35e96ef 100644
--- a/en.json
+++ b/en.json
@@ -16,9 +16,12 @@
"Repository": "Repository",
"API Token": "API Token",
"PR Filter": "PR Filter",
+ "Your Repositories": "Your Repositories",
"Assigned to me": "Assigned to me",
+ "Created by me": "Created by me",
"Review requested": "Review requested",
- "Both": "Both",
+ "Reviewed by me": "Reviewed by me",
+ "Mentioned me": "Mentioned me",
"Server": "Server",
"Last Rised": "Last Rised",
"Pull Requests": "Pull Requests",
diff --git a/manifest.json b/manifest.json
index 75c43d8..670515d 100644
--- a/manifest.json
+++ b/manifest.json
@@ -75,6 +75,19 @@
],
"Tooltip": "Shows light color, time and mode from an ESP32 model railway controller via MQTT",
"UUID": "dev.mars3142.ulanzideck.collection.railway"
+ },
+ {
+ "Name": "Model Railway Stream",
+ "Icon": "assets/icons/railway.png",
+ "PropertyInspectorPath": "property-inspector/stream/inspector.html",
+ "States": [
+ {
+ "Name": "Default",
+ "Image": "assets/icons/railway.png"
+ }
+ ],
+ "Tooltip": "Displays the live 128x64 monochrome display stream from an ESP32 model railway controller via MQTT",
+ "UUID": "dev.mars3142.ulanzideck.collection.stream"
}
],
"OS": [
diff --git a/plugin/actions/GiteaPRAction.js b/plugin/actions/GiteaPRAction.js
index b83817d..af69ca6 100644
--- a/plugin/actions/GiteaPRAction.js
+++ b/plugin/actions/GiteaPRAction.js
@@ -9,6 +9,7 @@ class GiteaPRAction extends ActionBase {
};
this.firstSeen = {};
this.settingsLoaded = false;
+ this.username = null;
this.$UD.onDidReceiveSettings(jsn => {
if (jsn.context !== this.context) return;
@@ -30,9 +31,18 @@ class GiteaPRAction extends ActionBase {
}
onRun() {
- if (this.config.url) {
- this.$UD.openUrl(`${this.config.url}/pulls?type=your_repositories&sort=&state=open&q=`);
- }
+ if (!this.config.url) return;
+ const filter = this.config.filter || 'review_requested';
+ const filterMap = {
+ your_repos: 'type=your_repositories',
+ assigned: 'type=your_repositories&assignee=0',
+ created: 'type=your_repositories&poster=0',
+ review_requested: 'type=your_repositories&review_requested=true',
+ reviewed: 'type=your_repositories&reviewed=true',
+ mentioned: 'type=your_repositories&mentioned=0',
+ };
+ const q = filterMap[filter] || filterMap.your_repos;
+ this.$UD.openUrl(`${this.config.url}/pulls?${q}&state=open`);
}
fetchPRs() {
@@ -46,32 +56,36 @@ class GiteaPRAction extends ActionBase {
const filter = this.config.filter || 'review_requested';
const base = `${this.config.url}/api/v1/repos/issues/search?type=pullrequest&state=open&limit=50`;
- const fetchPRs = async (url) => {
- const r = await fetch(url, { headers, signal: AbortSignal.timeout(8000) });
- console.log('GiteaPR status:', r.status, url);
- if (!r.ok) {
- const body = await r.text();
- console.log('GiteaPR error body:', body);
- return null;
+ const fetchPages = async (url, paramChar = '&') => {
+ const all = [];
+ let page = 1;
+ while (true) {
+ const r = await fetch(`${url}${paramChar}page=${page}`, { headers, signal: AbortSignal.timeout(8000) });
+ if (r.status === 404 || r.status === 403) return [];
+ if (!r.ok) {
+ console.log('GiteaPR error:', r.status, url);
+ return null;
+ }
+ const data = await r.json();
+ if (!Array.isArray(data) || data.length === 0) break;
+ all.push(...data);
+ if (data.length < 50) break;
+ page++;
}
- const data = await r.json();
- return Array.isArray(data) ? data : [];
+ return all;
};
- let prs;
- if (filter === 'both') {
- const [a, b] = await Promise.all([
- fetchPRs(`${base}&assigned=true`),
- fetchPRs(`${base}&review_requested=true`),
- ]);
- if (a === null || b === null) { this.renderButton(null, true); return; }
- const seen = new Set();
- prs = [...a, ...b].filter(pr => seen.has(pr.id) ? false : seen.add(pr.id));
- } else {
- const param = filter === 'assigned' ? '&assigned=true' : '&review_requested=true';
- prs = await fetchPRs(`${base}${param}`);
- if (prs === null) { this.renderButton(null, true); return; }
- }
+ const paramMap = {
+ your_repos: '', all: '', both: '',
+ assigned: '&assigned=true',
+ created: '&created=true',
+ review_requested: '&review_requested=true',
+ reviewed: '&reviewed=true',
+ mentioned: '&mentioned=true',
+ };
+ const raw = await fetchPages(`${base}${paramMap[filter] ?? ''}`);
+ if (raw === null) { this.renderButton(null, true); return; }
+ const prs = raw.filter(pr => pr.pull_request != null);
const wip = prs.filter(pr => pr.title?.startsWith('WIP: ')).length;
const now = Date.now();
@@ -120,7 +134,15 @@ class GiteaPRAction extends ActionBase {
ctx.fillText(isError ? this.$UD.t('API Error') : this.$UD.t('Offline'), 98, 166);
} else {
const filter = this.config.filter || 'review_requested';
- const label = filter === 'assigned' ? 'assigned' : filter === 'review_requested' ? 'review req.' : 'open';
+ const labelMap = {
+ your_repos: 'your repos',
+ assigned: 'assigned',
+ created: 'created',
+ review_requested: 'review req.',
+ reviewed: 'reviewed',
+ mentioned: 'mentioned',
+ };
+ const label = labelMap[filter] ?? 'your repos';
const color = count === 0 ? '#6bff6b' : count < 5 ? '#f0c040' : '#ff6b6b';
const text = count > 999 ? '999+' : String(count);
diff --git a/plugin/app.html b/plugin/app.html
index 0e0e7d2..e43768e 100644
--- a/plugin/app.html
+++ b/plugin/app.html
@@ -18,6 +18,7 @@
+