improve Gitea PR plugin with correct filter options
- Replace custom filters with Gitea UI equivalents (your repos, assigned, created, review requested, reviewed, mentioned) - Fix pagination to fetch all pages from issues/search - Filter out false-positive issues (pull_request: null) - Use issues/search API for all filters (correct token scopes required) - Add StreamAction registration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+4
-1
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": [
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<script src="./actions/GiteaAction.js"></script>
|
||||
<script src="./actions/GiteaPRAction.js"></script>
|
||||
<script src="./actions/RailwayAction.js"></script>
|
||||
<script src="./actions/StreamAction.js"></script>
|
||||
<script src="./app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -24,6 +24,8 @@ $UD.onAdd(jsn => {
|
||||
ACTION_CACHES[context] = new GiteaPRAction($UD, context);
|
||||
} else if (name === 'railway') {
|
||||
ACTION_CACHES[context] = new RailwayAction($UD, context);
|
||||
} else if (name === 'stream') {
|
||||
ACTION_CACHES[context] = new StreamAction($UD, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
<div class="uspi-item">
|
||||
<div class="uspi-item-label" data-localize>PR Filter</div>
|
||||
<select class="uspi-item-value" name="filter">
|
||||
<option value="your_repos" data-localize>Your Repositories</option>
|
||||
<option value="assigned" data-localize>Assigned to me</option>
|
||||
<option value="created" data-localize>Created by me</option>
|
||||
<option value="review_requested" selected data-localize>Review requested</option>
|
||||
<option value="both" data-localize>Both</option>
|
||||
<option value="reviewed" data-localize>Reviewed by me</option>
|
||||
<option value="mentioned" data-localize>Mentioned me</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="uspi-item">
|
||||
|
||||
Reference in New Issue
Block a user