1- import './emoji-button' ;
1+ import type { User } from '@halo-dev/api-client' ;
2+ import { consume } from '@lit/context' ;
23import { css , html , LitElement } from 'lit' ;
4+ import { property , state } from 'lit/decorators.js' ;
35import { createRef , Ref , ref } from 'lit/directives/ref.js' ;
46import {
57 allowAnonymousCommentsContext ,
68 baseUrlContext ,
9+ captchaEnabledContext ,
710 currentUserContext ,
811 groupContext ,
912 kindContext ,
1013 nameContext ,
14+ toastContext ,
1115} from './context' ;
12- import { property , state } from 'lit/decorators.js' ;
13- import type { User } from '@halo-dev/api-client' ;
16+ import './emoji-button' ;
17+ import './icons/icon-loading' ;
18+ import { ToastManager } from './lit-toast' ;
1419import baseStyles from './styles/base' ;
15- import { consume } from '@lit/context' ;
1620import varStyles from './styles/var' ;
17- import './icons/icon-loading' ;
1821
1922export class BaseForm extends LitElement {
2023 @consume ( { context : baseUrlContext } )
@@ -29,6 +32,10 @@ export class BaseForm extends LitElement {
2932 @state ( )
3033 allowAnonymousComments = false ;
3134
35+ @consume ( { context : captchaEnabledContext , subscribe : true } )
36+ @state ( )
37+ captchaEnabled = false ;
38+
3239 @consume ( { context : groupContext } )
3340 @state ( )
3441 group = '' ;
@@ -41,9 +48,17 @@ export class BaseForm extends LitElement {
4148 @state ( )
4249 name = '' ;
4350
51+ @property ( { type : String } )
52+ @state ( )
53+ captcha = '' ;
54+
4455 @property ( { type : Boolean } )
4556 submitting = false ;
4657
58+ @consume ( { context : toastContext , subscribe : true } )
59+ @state ( )
60+ toastManager : ToastManager | undefined ;
61+
4762 textareaRef : Ref < HTMLTextAreaElement > = createRef < HTMLTextAreaElement > ( ) ;
4863
4964 get customAccount ( ) {
@@ -58,6 +73,25 @@ export class BaseForm extends LitElement {
5873 return `/console/login?redirect_uri=${ encodeURIComponent ( window . location . href + parentDomId ) } ` ;
5974 }
6075
76+ get showCaptcha ( ) {
77+ return this . captchaEnabled && ! this . currentUser ;
78+ }
79+
80+ async handleFetchCaptcha ( ) {
81+ if ( ! this . showCaptcha ) {
82+ return ;
83+ }
84+
85+ const response = await fetch ( `/apis/api.commentwidget.halo.run/v1alpha1/captcha/-/generate` ) ;
86+
87+ if ( ! response . ok ) {
88+ this . toastManager ?. error ( '获取验证码失败' ) ;
89+ return ;
90+ }
91+
92+ this . captcha = await response . text ( ) ;
93+ }
94+
6195 handleOpenLoginPage ( ) {
6296 window . location . href = this . loginUrl ;
6397 }
@@ -124,6 +158,7 @@ export class BaseForm extends LitElement {
124158 override connectedCallback ( ) : void {
125159 super . connectedCallback ( ) ;
126160 this . addEventListener ( 'keydown' , this . onKeydown ) ;
161+ this . handleFetchCaptcha ( ) ;
127162 }
128163
129164 override disconnectedCallback ( ) : void {
@@ -182,6 +217,20 @@ export class BaseForm extends LitElement {
182217 </ butto n> `
183218 : '' }
184219 <div class= "form__actions" >
220+ ${ this . showCaptcha
221+ ? html `
222+ <div class= "form__action--captcha" >
223+ <input name= "captchaCode" type = "text" placeholder= "请输入验证码" / >
224+ <img
225+ @click = ${ this . handleFetchCaptcha }
226+ src= "${ this . captcha } "
227+ alt = "captcha"
228+ width= "100%"
229+ / >
230+ </ div>
231+ `
232+ : '' }
233+
185234 <emoji- butto n @emoji-select = ${ this . onEmojiSelect } > </ emoji- butto n>
186235 <butto n .disabled = ${ this . submitting } type= "submit" class= "for m__butto n- - submit">
187236 ${ this . submitting
@@ -286,7 +335,7 @@ export class BaseForm extends LitElement {
286335 border : 0.05em solid var (--component-form-input-border-color );
287336 font-size : 0.875em ;
288337 display : block;
289- height : 2.25 em ;
338+ height : 2.65 em ;
290339 max-width : 100% ;
291340 outline : 0 ;
292341 padding : 0.4em 0.75em ;
@@ -349,12 +398,26 @@ export class BaseForm extends LitElement {
349398
350399 .form__actions {
351400 display : flex;
401+ flex-wrap : wrap;
352402 align-items : center;
353403 gap : 0.75em ;
354- flex : 1 1 auto ;
404+ width : 100 % ;
355405 justify-content : flex-end;
356406 }
357407
408+ .form__action--captcha {
409+ display : flex;
410+ align-items : center;
411+ gap : 0.3em ;
412+ flex-direction : row-reverse;
413+ }
414+
415+ .form__action--captcha img {
416+ height : 2.25em ;
417+ width : auto;
418+ border-radius : var (--base-border-radius );
419+ }
420+
358421 .form__button--submit {
359422 border-radius : var (--base-border-radius );
360423 background-color : var (--component-form-button-submit-bg-color );
0 commit comments