Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit45a88e0

Browse files
Fix "ref-issue" handling in markup (#35739) (#35771)
Backport#35739 by wxiaoguangThis is a follow up for#35662, and alsofix#31181, help#30275,fix#31161Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1 parent6aa1a1e commit45a88e0

File tree

10 files changed

+74
-90
lines changed

10 files changed

+74
-90
lines changed

‎templates/base/head_script.tmpl‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
3636
copy_success: {{ctx.Locale.Tr "copy_success"}},
3737
copy_error: {{ctx.Locale.Tr "copy_error"}},
3838
error_occurred: {{ctx.Locale.Tr "error.occurred"}},
39-
network_error: {{ctx.Locale.Tr "error.network_error"}},
4039
remove_label_str: {{ctx.Locale.Tr "remove_label_str"}},
4140
modal_confirm: {{ctx.Locale.Tr "modal.confirm"}},
4241
modal_cancel: {{ctx.Locale.Tr "modal.cancel"}},

‎web_src/js/components/ContextPopup.vue‎

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,62 +2,53 @@
22
import {SvgIcon}from'../svg.ts';
33
import {GET}from'../modules/fetch.ts';
44
import {getIssueColor,getIssueIcon}from'../features/issue.ts';
5-
import {computed,onMounted,shallowRef,useTemplateRef}from'vue';
6-
importtype {IssuePathInfo}from'../types.ts';
5+
import {computed,onMounted,shallowRef}from'vue';
76
8-
const {appSubUrl, i18n}=window.config;
7+
const props=defineProps<{
8+
repoLink:string,
9+
loadIssueInfoUrl:string,
10+
}>();
911
1012
const loading=shallowRef(false);
1113
const issue=shallowRef(null);
1214
const renderedLabels=shallowRef('');
13-
const i18nErrorOccurred=i18n.error_occurred;
14-
const i18nErrorMessage=shallowRef(null);
15+
const errorMessage=shallowRef(null);
1516
16-
const createdAt=computed(()=>newDate(issue.value.created_at).toLocaleDateString(undefined, {year:'numeric', month:'short', day:'numeric'}));
17-
const body=computed(()=> {
18-
const body=issue.value.body.replace(/\n+/g,'');
19-
if (body.length>85) {
20-
return`${body.substring(0,85)}…`;
21-
}
22-
returnbody;
17+
const createdAt=computed(()=> {
18+
returnnewDate(issue.value.created_at).toLocaleDateString(undefined, {year:'numeric', month:'short', day:'numeric'});
2319
});
2420
25-
const root=useTemplateRef('root');
26-
27-
onMounted(()=> {
28-
root.value.addEventListener('ce-load-context-popup', (e:CustomEventInit<IssuePathInfo>)=> {
29-
if (!loading.value&&issue.value===null) {
30-
load(e.detail);
31-
}
32-
});
21+
const body=computed(()=> {
22+
const body=issue.value.body.replace(/\n+/g,'');
23+
returnbody.length>85?`${body.substring(0,85)}…`:body;
3324
});
3425
35-
asyncfunction load(issuePathInfo:IssuePathInfo) {
26+
onMounted(async()=> {
3627
loading.value=true;
37-
i18nErrorMessage.value=null;
38-
28+
errorMessage.value=null;
3929
try {
40-
const response=awaitGET(`${appSubUrl}/${issuePathInfo.ownerName}/${issuePathInfo.repoName}/issues/${issuePathInfo.indexString}/info`);// backend: GetIssueInfo
41-
const respJson=awaitresponse.json();
42-
if (!response.ok) {
43-
i18nErrorMessage.value=respJson.message??i18n.network_error;
30+
const resp=awaitGET(props.loadIssueInfoUrl);
31+
if (!resp.ok) {
32+
errorMessage.value=resp.status?resp.statusText:'Unknown network error';
4433
return;
4534
}
35+
const respJson=awaitresp.json();
4636
issue.value=respJson.convertedIssue;
4737
renderedLabels.value=respJson.renderedLabels;
48-
}catch {
49-
i18nErrorMessage.value=i18n.network_error;
5038
}finally {
5139
loading.value=false;
5240
}
53-
}
41+
});
5442
</script>
5543

5644
<template>
57-
<divref="root">
45+
<divclass="tw-p-4">
5846
<divv-if="loading"class="tw-h-12 tw-w-12 is-loading"/>
59-
<divv-if="!loading && issue !== null"class="tw-flex tw-flex-col tw-gap-2">
60-
<divclass="tw-text-12">{{ issue.repository.full_name }} on {{ createdAt }}</div>
47+
<divv-else-if="issue"class="tw-flex tw-flex-col tw-gap-2">
48+
<divclass="tw-text-12">
49+
<a:href="repoLink"class="muted">{{ issue.repository.full_name }}</a>
50+
on {{ createdAt }}
51+
</div>
6152
<divclass="flex-text-block">
6253
<svg-icon:name="getIssueIcon(issue)":class="['text', getIssueColor(issue)]"/>
6354
<spanclass="issue-title tw-font-semibold tw-break-anywhere">
@@ -69,9 +60,8 @@ async function load(issuePathInfo: IssuePathInfo) {
6960
<!-- eslint-disable-next-line vue/no-v-html-->
7061
<divv-if="issue.labels.length"v-html="renderedLabels"/>
7162
</div>
72-
<divclass="tw-flex tw-flex-col tw-gap-2"v-if="!loading && issue === null">
73-
<divclass="tw-text-12">{{ i18nErrorOccurred }}</div>
74-
<div>{{ i18nErrorMessage }}</div>
63+
<divv-else>
64+
{{ errorMessage }}
7565
</div>
7666
</div>
7767
</template>

‎web_src/js/features/contextpopup.ts‎

Lines changed: 0 additions & 43 deletions
This file was deleted.

‎web_src/js/features/repo-diff.ts‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import {invertFileFolding} from './file-fold.ts';
1212
import{parseDom}from'../utils.ts';
1313
import{registerGlobalSelectorFunc}from'../modules/observer.ts';
1414

15-
const{i18n}=window.config;
16-
1715
functioninitRepoDiffFileBox(el:HTMLElement){
1816
// switch between "rendered" and "source", for image and CSV files
1917
queryElems(el,'.file-view-toggle',(btn)=>btn.addEventListener('click',()=>{
@@ -86,7 +84,7 @@ function initRepoDiffConversationForm() {
8684
}
8785
}catch(error){
8886
console.error('Error:',error);
89-
showErrorToast(i18n.network_error);
87+
showErrorToast(`Submit form failed:${error}`);
9088
}finally{
9189
form?.classList.remove('is-loading');
9290
}

‎web_src/js/features/repo-editor.ts‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import{html,htmlRaw}from'../utils/html.ts';
22
import{createCodeEditor}from'./codeeditor.ts';
33
import{hideElem,queryElems,showElem,createElementFromHTML}from'../utils/dom.ts';
4-
import{attachRefIssueContextPopup}from'./contextpopup.ts';
54
import{POST}from'../modules/fetch.ts';
65
import{initDropzone}from'./dropzone.ts';
76
import{confirmModal}from'./comp/ConfirmModal.ts';
@@ -199,5 +198,4 @@ export function initRepoEditor() {
199198
exportfunctionrenderPreviewPanelContent(previewPanel:Element,htmlContent:string){
200199
// the content is from the server, so it is safe to use innerHTML
201200
previewPanel.innerHTML=html`<divclass="render-content markup">${htmlRaw(htmlContent)}</div>`;
202-
attachRefIssueContextPopup(previewPanel.querySelectorAll('p .ref-issue'));
203201
}

‎web_src/js/features/repo-issue-edit.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {getComboMarkdownEditor, initComboMarkdownEditor, ComboMarkdownEditor} fr
33
import{POST}from'../modules/fetch.ts';
44
import{showErrorToast}from'../modules/toast.ts';
55
import{hideElem,querySingleVisibleElem,showElem,typeDOMEvent}from'../utils/dom.ts';
6-
import{attachRefIssueContextPopup}from'./contextpopup.ts';
76
import{triggerUploadStateChanged}from'./comp/EditorUpload.ts';
87
import{convertHtmlToMarkdown}from'../markup/html2markdown.ts';
98
import{applyAreYouSure,reinitializeAreYouSure}from'../vendor/jquery.are-you-sure.ts';
@@ -62,8 +61,6 @@ async function tryOnEditContent(e: DOMEvent<MouseEvent>) {
6261
renderContent=newRenderContent;
6362

6463
rawContent.textContent=comboMarkdownEditor.value();
65-
constrefIssues=renderContent.querySelectorAll<HTMLElement>('p .ref-issue');
66-
attachRefIssueContextPopup(refIssues);
6764

6865
if(!commentContent.querySelector('.dropzone-attachments')){
6966
if(data.attachments!==''){

‎web_src/js/index-domready.ts‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import '../../node_modules/easymde/dist/easymde.min.css'; // TODO: lazy load in
55
import{initHtmx}from'./htmx.ts';
66
import{initDashboardRepoList}from'./features/dashboard.ts';
77
import{initGlobalCopyToClipboardListener}from'./features/clipboard.ts';
8-
import{initContextPopups}from'./features/contextpopup.ts';
98
import{initRepoGraphGit}from'./features/repo-graph.ts';
109
import{initHeatmap}from'./features/heatmap.ts';
1110
import{initImageDiff}from'./features/imagediff.ts';
@@ -97,7 +96,6 @@ const initPerformanceTracer = callInitFunctions([
9796
initHeadNavbarContentToggle,
9897
initFootLanguageMenu,
9998

100-
initContextPopups,
10199
initHeatmap,
102100
initImageDiff,
103101
initMarkupAnchors,

‎web_src/js/markup/content.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {initMarkupRenderAsciicast} from './asciicast.ts';
55
import{initMarkupTasklist}from'./tasklist.ts';
66
import{registerGlobalSelectorFunc}from'../modules/observer.ts';
77
import{initMarkupRenderIframe}from'./render-iframe.ts';
8+
import{initMarkupRefIssue}from'./refissue.ts';
89

910
// code that runs for all markup content
1011
exportfunctioninitMarkupContent():void{
@@ -15,5 +16,6 @@ export function initMarkupContent(): void {
1516
initMarkupCodeMath(el);
1617
initMarkupRenderAsciicast(el);
1718
initMarkupRenderIframe(el);
19+
initMarkupRefIssue(el);
1820
});
1921
}

‎web_src/js/markup/refissue.ts‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import{queryElems}from'../utils/dom.ts';
2+
import{parseIssueHref}from'../utils.ts';
3+
import{createApp}from'vue';
4+
importContextPopupfrom'../components/ContextPopup.vue';
5+
import{createTippy,getAttachedTippyInstance}from'../modules/tippy.ts';
6+
7+
exportfunctioninitMarkupRefIssue(el:HTMLElement){
8+
queryElems(el,'.ref-issue',(el)=>{
9+
el.addEventListener('mouseenter',showMarkupRefIssuePopup);
10+
el.addEventListener('focus',showMarkupRefIssuePopup);
11+
});
12+
}
13+
14+
exportfunctionshowMarkupRefIssuePopup(e:MouseEvent|FocusEvent){
15+
constrefIssue=e.currentTargetasHTMLElement;
16+
if(getAttachedTippyInstance(refIssue))return;
17+
if(refIssue.classList.contains('ref-external-issue'))return;
18+
19+
constissuePathInfo=parseIssueHref(refIssue.getAttribute('href'));
20+
if(!issuePathInfo.ownerName)return;
21+
22+
constel=document.createElement('div');
23+
consttippy=createTippy(refIssue,{
24+
theme:'default',
25+
content:el,
26+
trigger:'mouseenter focus',
27+
placement:'top-start',
28+
interactive:true,
29+
role:'dialog',
30+
interactiveBorder:5,
31+
// onHide() { return false }, // help to keep the popup and debug the layout
32+
onShow:()=>{
33+
constview=createApp(ContextPopup,{
34+
// backend: GetIssueInfo
35+
loadIssueInfoUrl:`${window.config.appSubUrl}/${issuePathInfo.ownerName}/${issuePathInfo.repoName}/issues/${issuePathInfo.indexString}/info`,
36+
});
37+
view.mount(el);
38+
},
39+
});
40+
tippy.show();
41+
}

‎web_src/js/modules/tippy.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,7 @@ export function showTemporaryTooltip(target: Element, content: Content): void {
209209
},
210210
});
211211
}
212+
213+
exportfunctiongetAttachedTippyInstance(el:Element):Instance|null{
214+
returnel._tippy??null;
215+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp