mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	add thumbnail preview section to issue attachments (#13826)
* add thumbnail preview section to attachments * dont show thumbnail if the image is already shown inline * update router to pass the `content` to the attachemnts template * limit attachment preview height to 150px (same as width) * remove unused css (referance removed in https://github.com/go-gitea/gitea/pull/11141/files#diff-9faae32445ed9673de2830c9fc35e93f44487f0a0068202988adaf00a5bac850L66 ) * dont show divider after edit if no attachemnts Co-authored-by: James <inbox.dev@jhodges.co.uk> Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
		@@ -1649,7 +1649,7 @@ func UpdateIssueContent(ctx *context.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	ctx.JSON(200, map[string]interface{}{
 | 
						ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
		"content":     string(markdown.Render([]byte(issue.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())),
 | 
							"content":     string(markdown.Render([]byte(issue.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())),
 | 
				
			||||||
		"attachments": attachmentsHTML(ctx, issue.Attachments),
 | 
							"attachments": attachmentsHTML(ctx, issue.Attachments, issue.Content),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2065,7 +2065,7 @@ func UpdateCommentContent(ctx *context.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	ctx.JSON(200, map[string]interface{}{
 | 
						ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
		"content":     string(markdown.Render([]byte(comment.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())),
 | 
							"content":     string(markdown.Render([]byte(comment.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())),
 | 
				
			||||||
		"attachments": attachmentsHTML(ctx, comment.Attachments),
 | 
							"attachments": attachmentsHTML(ctx, comment.Attachments, comment.Content),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2399,10 +2399,11 @@ func updateAttachments(item interface{}, files []string) error {
 | 
				
			|||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func attachmentsHTML(ctx *context.Context, attachments []*models.Attachment) string {
 | 
					func attachmentsHTML(ctx *context.Context, attachments []*models.Attachment, content string) string {
 | 
				
			||||||
	attachHTML, err := ctx.HTMLString(string(tplAttachment), map[string]interface{}{
 | 
						attachHTML, err := ctx.HTMLString(string(tplAttachment), map[string]interface{}{
 | 
				
			||||||
		"ctx":         ctx.Data,
 | 
							"ctx":         ctx.Data,
 | 
				
			||||||
		"Attachments": attachments,
 | 
							"Attachments": attachments,
 | 
				
			||||||
 | 
							"Content":     content,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.ServerError("attachmentsHTML.HTMLString", err)
 | 
							ctx.ServerError("attachmentsHTML.HTMLString", err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,14 +66,9 @@
 | 
				
			|||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						<div id="comment-{{.Issue.ID}}" class="raw-content hide">{{.Issue.Content}}</div>
 | 
											<div id="comment-{{.Issue.ID}}" class="raw-content hide">{{.Issue.Content}}</div>
 | 
				
			||||||
						<div class="edit-content-zone hide" data-write="issue-{{.Issue.ID}}-write" data-preview="issue-{{.Issue.ID}}-preview" data-update-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/content" data-context="{{.RepoLink}}" data-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/attachments" data-view-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/view-attachments"></div>
 | 
											<div class="edit-content-zone hide" data-write="issue-{{.Issue.ID}}-write" data-preview="issue-{{.Issue.ID}}-preview" data-update-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/content" data-context="{{.RepoLink}}" data-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/attachments" data-view-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/view-attachments"></div>
 | 
				
			||||||
					{{if .Issue.Attachments}}
 | 
					    					{{if .Issue.Attachments}}
 | 
				
			||||||
						<div class="dropzone-attachments">
 | 
					    						{{template "repo/issue/view_content/attachments" Dict "ctx" $ "Attachments" .Issue.Attachments "Content" .Issue.RenderedContent}}
 | 
				
			||||||
							<div class="ui clearing divider"></div>
 | 
					    					{{end}}
 | 
				
			||||||
							<div class="ui middle aligned padded grid">
 | 
					 | 
				
			||||||
								{{template "repo/issue/view_content/attachments" Dict "ctx" $ "Attachments" .Issue.Attachments}}
 | 
					 | 
				
			||||||
							</div>
 | 
					 | 
				
			||||||
						</div>
 | 
					 | 
				
			||||||
					{{end}}
 | 
					 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					{{$reactions := .Issue.Reactions.GroupByType}}
 | 
										{{$reactions := .Issue.Reactions.GroupByType}}
 | 
				
			||||||
					{{if $reactions}}
 | 
										{{if $reactions}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,42 @@
 | 
				
			|||||||
{{- range .Attachments -}}
 | 
					<div class="dropzone-attachments">
 | 
				
			||||||
<div class="twelve wide column" style="padding: 6px;">
 | 
					    {{if .Attachments}}
 | 
				
			||||||
	<a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}" title='{{$.ctx.i18n.Tr "repo.issues.attachment.open_tab" .Name}}'>
 | 
					        <div class="ui clearing divider"></div>
 | 
				
			||||||
	{{if FilenameIsImage .Name}}
 | 
					    {{end}}
 | 
				
			||||||
		<span class="ui image">{{svg "octicon-file"}}</span>
 | 
					    <div class="ui middle aligned padded grid">
 | 
				
			||||||
	{{else}}
 | 
					        {{$hasThumbnails := false}}
 | 
				
			||||||
		<span class="ui image">{{svg "octicon-desktop-download"}}</span>
 | 
					        {{- range .Attachments -}}
 | 
				
			||||||
	{{end}}
 | 
					            <div class="twelve wide column" style="padding: 6px;">
 | 
				
			||||||
		<span><strong>{{.Name}}</strong></span>
 | 
					                <a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}" title='{{$.ctx.i18n.Tr "repo.issues.attachment.open_tab" .Name}}'>
 | 
				
			||||||
	</a>
 | 
					                    {{if FilenameIsImage .Name}}
 | 
				
			||||||
 | 
					                        {{if not (containGeneric $.Content .UUID)}}
 | 
				
			||||||
 | 
					                            {{$hasThumbnails = true}}
 | 
				
			||||||
 | 
					                        {{end}}
 | 
				
			||||||
 | 
					                        <span class="ui image">{{svg "octicon-file"}}</span>
 | 
				
			||||||
 | 
					                    {{else}}
 | 
				
			||||||
 | 
					                        <span class="ui image">{{svg "octicon-desktop-download"}}</span>
 | 
				
			||||||
 | 
					                    {{end}}
 | 
				
			||||||
 | 
					                    <span><strong>{{.Name}}</strong></span>
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="four wide column" style="padding: 0px;">
 | 
				
			||||||
 | 
					                <span class="ui text grey right">{{.Size | FileSize}}</span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        {{end -}}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {{if $hasThumbnails}}
 | 
				
			||||||
 | 
					        <div class="ui clearing divider"></div>
 | 
				
			||||||
 | 
					        <div class="ui small images thumbnails">
 | 
				
			||||||
 | 
					            {{- range .Attachments -}}
 | 
				
			||||||
 | 
					                {{if FilenameIsImage .Name}}
 | 
				
			||||||
 | 
					                    {{if not (containGeneric $.Content .UUID)}}
 | 
				
			||||||
 | 
					                    <a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}">
 | 
				
			||||||
 | 
					                        <img class="ui image" src="{{.DownloadURL}}" title='{{$.ctx.i18n.Tr "repo.issues.attachment.open_tab" .Name}}'>
 | 
				
			||||||
 | 
					                    </a>
 | 
				
			||||||
 | 
					                    {{end}}
 | 
				
			||||||
 | 
					                {{end}}
 | 
				
			||||||
 | 
					            {{end -}}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    {{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
<div class="four wide column" style="padding: 0px;">
 | 
					 | 
				
			||||||
	<span class="ui text grey right">{{.Size | FileSize}}</span>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
{{end -}}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,14 +72,9 @@
 | 
				
			|||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					<div id="comment-{{.ID}}" class="raw-content hide">{{.Content}}</div>
 | 
										<div id="comment-{{.ID}}" class="raw-content hide">{{.Content}}</div>
 | 
				
			||||||
					<div class="edit-content-zone hide" data-write="issuecomment-{{.ID}}-write" data-preview="issuecomment-{{.ID}}-preview" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div>
 | 
										<div class="edit-content-zone hide" data-write="issuecomment-{{.ID}}-write" data-preview="issuecomment-{{.ID}}-preview" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div>
 | 
				
			||||||
				{{if .Attachments}}
 | 
					    				{{if .Attachments}}
 | 
				
			||||||
					<div class="dropzone-attachments">
 | 
					    					{{template "repo/issue/view_content/attachments" Dict "ctx" $ "Attachments" .Attachments "Content" .RenderedContent}}
 | 
				
			||||||
						<div class="ui clearing divider"></div>
 | 
					    				{{end}}
 | 
				
			||||||
						<div class="ui middle aligned padded grid">
 | 
					 | 
				
			||||||
							{{template "repo/issue/view_content/attachments" Dict "ctx" $ "Attachments" .Attachments}}
 | 
					 | 
				
			||||||
						</div>
 | 
					 | 
				
			||||||
					</div>
 | 
					 | 
				
			||||||
				{{end}}
 | 
					 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
				{{$reactions := .Reactions.GroupByType}}
 | 
									{{$reactions := .Reactions.GroupByType}}
 | 
				
			||||||
				{{if $reactions}}
 | 
									{{if $reactions}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1048,17 +1048,14 @@ async function initRepository() {
 | 
				
			|||||||
              if (data.attachments !== '') {
 | 
					              if (data.attachments !== '') {
 | 
				
			||||||
                $content.append(`
 | 
					                $content.append(`
 | 
				
			||||||
                  <div class="dropzone-attachments">
 | 
					                  <div class="dropzone-attachments">
 | 
				
			||||||
                    <div class="ui clearing divider"></div>
 | 
					 | 
				
			||||||
                    <div class="ui middle aligned padded grid">
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                `);
 | 
					                `);
 | 
				
			||||||
                $content.find('.dropzone-attachments .grid').html(data.attachments);
 | 
					                $content.find('.dropzone-attachments').replaceWith(data.attachments);
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            } else if (data.attachments === '') {
 | 
					            } else if (data.attachments === '') {
 | 
				
			||||||
              $content.find('.dropzone-attachments').remove();
 | 
					              $content.find('.dropzone-attachments').remove();
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
              $content.find('.dropzone-attachments .grid').html(data.attachments);
 | 
					              $content.find('.dropzone-attachments').replaceWith(data.attachments);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (dz) {
 | 
					            if (dz) {
 | 
				
			||||||
              dz.emit('submit');
 | 
					              dz.emit('submit');
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1016,50 +1016,10 @@
 | 
				
			|||||||
            font-style: italic;
 | 
					            font-style: italic;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          > .bottom.segment {
 | 
					          .dropzone-attachments .thumbnails .ui.image {
 | 
				
			||||||
            background: var(--color-box-body);
 | 
					            max-height: 150px;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            .ui.images::after {
 | 
					 | 
				
			||||||
              clear: both;
 | 
					 | 
				
			||||||
              content: ' ';
 | 
					 | 
				
			||||||
              display: block;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            a {
 | 
					 | 
				
			||||||
              display: block;
 | 
					 | 
				
			||||||
              float: left;
 | 
					 | 
				
			||||||
              margin: 5px;
 | 
					 | 
				
			||||||
              padding: 5px;
 | 
					 | 
				
			||||||
              height: 150px;
 | 
					 | 
				
			||||||
              border: solid 1px var(--color-secondary);
 | 
					 | 
				
			||||||
              border-radius: 3px;
 | 
					 | 
				
			||||||
              max-width: 150px;
 | 
					 | 
				
			||||||
              background-color: var(--color-body);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              &::before {
 | 
					 | 
				
			||||||
                content: ' ';
 | 
					 | 
				
			||||||
                display: inline-block;
 | 
					 | 
				
			||||||
                height: 100%;
 | 
					 | 
				
			||||||
                vertical-align: middle;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            .ui.image {
 | 
					 | 
				
			||||||
              max-height: 100%;
 | 
					 | 
				
			||||||
              width: auto;
 | 
					 | 
				
			||||||
              margin: 0;
 | 
					 | 
				
			||||||
              vertical-align: middle;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            span.ui.image {
 | 
					 | 
				
			||||||
              font-size: 128px;
 | 
					 | 
				
			||||||
              color: var(--color-text);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            span.ui.image:hover {
 | 
					 | 
				
			||||||
              color: var(--color-text);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .ui.form {
 | 
					        .ui.form {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user