Skip to content

Commit 546f133

Browse files
committed
refactor
1 parent 7ab8dc3 commit 546f133

File tree

11 files changed

+31
-67
lines changed

11 files changed

+31
-67
lines changed

templates/admin/user/edit.tmpl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,7 @@
195195
</div>
196196

197197
<div class="inline field tw-pl-4">
198-
<label for="avatar">{{ctx.Locale.Tr "settings.choose_new_avatar"}}</label>
199-
<input id="new-avatar" name="avatar" type="file" accept="image/png,image/jpeg,image/gif,image/webp">
200-
</div>
201-
202-
<div class="field tw-pl-4 cropper-panel tw-hidden">
203-
<div>{{ctx.Locale.Tr "settings.cropper_prompt"}}</div>
204-
<div class="cropper-wrapper"><img class="cropper-source" src alt></div>
198+
{{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
205199
</div>
206200

207201
<div class="field">

templates/org/settings/options.tmpl

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,8 @@
8989
<form class="ui form" action="{{.Link}}/avatar" method="post" enctype="multipart/form-data">
9090
{{.CsrfTokenHtml}}
9191
<div class="inline field">
92-
<label for="avatar">{{ctx.Locale.Tr "settings.choose_new_avatar"}}</label>
93-
<input id="new-avatar" name="avatar" type="file" accept="image/png,image/jpeg,image/gif,image/webp">
92+
{{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
9493
</div>
95-
96-
<div class="field tw-pl-4 cropper-panel tw-hidden">
97-
<div>{{ctx.Locale.Tr "settings.cropper_prompt"}}</div>
98-
<div class="cropper-wrapper"><img class="cropper-source" src alt></div>
99-
</div>
100-
10194
<div class="field">
10295
<button class="ui primary button">{{ctx.Locale.Tr "settings.update_avatar"}}</button>
10396
<button class="ui red button link-action" data-url="{{.Link}}/avatar/delete">{{ctx.Locale.Tr "settings.delete_current_avatar"}}</button>

templates/repo/settings/options.tmpl

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,7 @@
4040
<form class="ui form" action="{{.Link}}/avatar" method="post" enctype="multipart/form-data">
4141
{{.CsrfTokenHtml}}
4242
<div class="inline field">
43-
<label for="avatar">{{ctx.Locale.Tr "settings.choose_new_avatar"}}</label>
44-
<input id="new-avatar" name="avatar" type="file" accept="image/png,image/jpeg,image/gif,image/webp">
45-
</div>
46-
<div class="field tw-pl-4 cropper-panel tw-hidden">
47-
<div>{{ctx.Locale.Tr "settings.cropper_prompt"}}</div>
48-
<div class="cropper-wrapper"><img class="cropper-source" src alt></div>
43+
{{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
4944
</div>
5045
<div class="field">
5146
<button class="ui primary button">{{ctx.Locale.Tr "settings.update_avatar"}}</button>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{{- /* we do not need to set for/id here, global aria init code will add them automatically */ -}}
2+
<label>{{.LabelText}}</label>
3+
<input name="avatar" type="file" accept="image/png,image/jpeg,image/gif,image/webp">
4+
{{- /* the cropper-panel must be next sibling of the input "js-avatar-with-cropper" */ -}}
5+
<div class="cropper-panel tw-hidden">
6+
<div>{{ctx.Locale.Tr "settings.cropper_prompt"}}</div>
7+
<div class="cropper-wrapper"><img class="cropper-source" src alt></div>
8+
</div>

templates/user/settings/profile.tmpl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,7 @@
124124
</div>
125125

126126
<div class="inline field tw-pl-4">
127-
<label for="new-avatar">{{ctx.Locale.Tr "settings.choose_new_avatar"}}</label>
128-
<input id="new-avatar" name="avatar" type="file" accept="image/png,image/jpeg,image/gif,image/webp">
129-
</div>
130-
131-
<div class="field tw-pl-4 cropper-panel tw-hidden">
132-
<div>{{ctx.Locale.Tr "settings.cropper_prompt"}}</div>
133-
<div class="cropper-wrapper"><img class="cropper-source" src alt></div>
127+
{{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
134128
</div>
135129

136130
<div class="field">

web_src/css/features/cropper.css

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
@import "cropperjs/dist/cropper.css";
22

3-
.page-content.admin.edit.user .cropper-panel .cropper-wrapper,
4-
.page-content.organization.settings.options .cropper-panel .cropper-wrapper,
5-
.page-content.repository.settings.options .cropper-panel .cropper-wrapper,
6-
.page-content.user.profile .cropper-panel .cropper-wrapper {
3+
input[name="avatar"] + .cropper-panel .cropper-wrapper {
74
max-width: 400px;
85
max-height: 400px;
96
}

web_src/js/features/admin/common.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import $ from 'jquery';
22
import {checkAppUrl} from '../common-page.ts';
33
import {hideElem, showElem, toggleElem} from '../../utils/dom.ts';
44
import {POST} from '../../modules/fetch.ts';
5-
import {initCompCropper} from '../comp/Cropper.ts';
5+
import {initAvatarUploaderWithCropper} from '../comp/Cropper.ts';
66

77
const {appSubUrl} = window.config;
88

@@ -260,11 +260,5 @@ export function initAdminCommon(): void {
260260
});
261261
}
262262

263-
// Avatar Cropper
264-
if (document.querySelector<HTMLDivElement>('.admin.edit.user')) {
265-
const fileInput = document.querySelector<HTMLInputElement>('#new-avatar');
266-
const container = document.querySelector<HTMLElement>('.admin.edit.user .cropper-panel');
267-
const imageSource = container.querySelector<HTMLImageElement>('.cropper-source');
268-
initCompCropper({container, fileInput, imageSource});
269-
}
263+
initAvatarUploaderWithCropper(document.querySelector('.admin.edit.user input[name="avatar"]'));
270264
}
Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {initCompLabelEdit} from './comp/LabelEdit.ts';
22
import {toggleElem} from '../utils/dom.ts';
3-
import {initCompCropper} from './comp/Cropper.ts';
3+
import {initAvatarUploaderWithCropper} from './comp/Cropper.ts';
44

55
export function initCommonOrganization() {
66
if (!document.querySelectorAll('.organization').length) {
@@ -15,11 +15,5 @@ export function initCommonOrganization() {
1515
// Labels
1616
initCompLabelEdit('.page-content.organization.settings.labels');
1717

18-
// Avatar Cropper
19-
if (document.querySelector<HTMLDivElement>('.organization.settings.options')) {
20-
const fileInput = document.querySelector<HTMLInputElement>('#new-avatar');
21-
const container = document.querySelector<HTMLElement>('.organization.settings.options .cropper-panel');
22-
const imageSource = container.querySelector<HTMLImageElement>('.cropper-source');
23-
initCompCropper({container, fileInput, imageSource});
24-
}
18+
initAvatarUploaderWithCropper(document.querySelector('.organization.settings.options input[name="avatar"]'));
2519
}

web_src/js/features/comp/Cropper.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import {showElem, type DOMEvent} from '../../utils/dom.ts';
1+
import {showElem, type DOMEvent, queryElemSiblings} from '../../utils/dom.ts';
22

33
type CropperOpts = {
44
container: HTMLElement,
55
imageSource: HTMLImageElement,
66
fileInput: HTMLInputElement,
77
}
88

9-
export async function initCompCropper({container, fileInput, imageSource}: CropperOpts) {
9+
async function initCompCropper({container, fileInput, imageSource}: CropperOpts) {
1010
const {default: Cropper} = await import(/* webpackChunkName: "cropperjs" */'cropperjs');
1111
let currentFileName = '';
1212
let currentFileLastModified = 0;
@@ -38,3 +38,11 @@ export async function initCompCropper({container, fileInput, imageSource}: Cropp
3838
}
3939
});
4040
}
41+
42+
export async function initAvatarUploaderWithCropper(fileInput?: HTMLInputElement) {
43+
if (!fileInput) return;
44+
const panel = queryElemSiblings(fileInput, '.cropper-panel')[0] as HTMLElement;
45+
if (!panel) return;
46+
const imageSource = panel.querySelector<HTMLImageElement>('.cropper-source');
47+
await initCompCropper({container: panel, fileInput, imageSource});
48+
}

web_src/js/features/repo-settings.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {minimatch} from 'minimatch';
33
import {createMonaco} from './codeeditor.ts';
44
import {onInputDebounce, queryElems, toggleElem} from '../utils/dom.ts';
55
import {POST} from '../modules/fetch.ts';
6-
import {initCompCropper} from './comp/Cropper.ts';
6+
import {initAvatarUploaderWithCropper} from './comp/Cropper.ts';
77
import {initRepoSettingsBranchesDrag} from './repo-settings-branches.ts';
88

99
const {appSubUrl, csrfToken} = window.config;
@@ -158,11 +158,5 @@ export function initRepoSettings() {
158158
initRepoSettingsGitHook();
159159
initRepoSettingsBranchesDrag();
160160

161-
// Avatar Cropper
162-
if (document.querySelector<HTMLDivElement>('.repository.settings.options')) {
163-
const fileInput = document.querySelector<HTMLInputElement>('#new-avatar');
164-
const container = document.querySelector<HTMLElement>('.repository.settings.options .cropper-panel');
165-
const imageSource = container.querySelector<HTMLImageElement>('.cropper-source');
166-
initCompCropper({container, fileInput, imageSource});
167-
}
161+
initAvatarUploaderWithCropper(document.querySelector('.repository.settings.options input[name="avatar"]'));
168162
}

web_src/js/features/user-settings.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
import {hideElem, showElem} from '../utils/dom.ts';
2-
import {initCompCropper} from './comp/Cropper.ts';
3-
4-
function initUserSettingsAvatarCropper() {
5-
const fileInput = document.querySelector<HTMLInputElement>('#new-avatar');
6-
const container = document.querySelector<HTMLElement>('.user.settings.profile .cropper-panel');
7-
const imageSource = container.querySelector<HTMLImageElement>('.cropper-source');
8-
initCompCropper({container, fileInput, imageSource});
9-
}
2+
import {initAvatarUploaderWithCropper} from './comp/Cropper.ts';
103

114
export function initUserSettings() {
125
if (!document.querySelector('.user.settings.profile')) return;
136

14-
initUserSettingsAvatarCropper();
7+
initAvatarUploaderWithCropper(document.querySelector('.user.settings.profile input[name="avatar"]'));
158

169
const usernameInput = document.querySelector<HTMLInputElement>('#username');
1710
if (!usernameInput) return;

0 commit comments

Comments
 (0)