fix(single): restore author follow controls #14

Merged
kate522 merged 1 commits from worktree/fix-single-author-follow into main 2026-08-31 05:14:45 +00:00
19 changed files with 261 additions and 615 deletions

No files matched your search

+11 -11
View File
@@ -984,17 +984,6 @@ strong, b {
.but a { color: inherit; } .but a { color: inherit; }
/* 关注控件(.follow 且无 .but):纯文字色样式,无背景色;
清除原生 button 的 UA 背景/边框,并保持 .but 同款可点反馈 */
.follow:not(.but) {
background: transparent;
border: none;
padding: 0;
cursor: pointer;
transition: 0.15s;
}
.follow:not(.but):hover { opacity: 0.8; }
.but .icon, .but .icon,
.but > .fa:not(.fa-angle-right), .but > .fa:not(.fa-angle-right),
.but > i[class*="fa-"]:not(.fa-angle-right) { margin-right: 0.25em; } .but > i[class*="fa-"]:not(.fa-angle-right) { margin-right: 0.25em; }
@@ -2697,6 +2686,17 @@ main.container,
flex-wrap: nowrap; flex-wrap: nowrap;
white-space: nowrap; white-space: nowrap;
} }
.user-card.author .user-name > name {
overflow: visible;
}
.user-card.author .user-name > name > .display-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.user-card.author .user-name > name > .follow {
flex-shrink: 0;
}
.aksrt-author-hero__name, .aksrt-author-hero__name,
.uc-header__name { .uc-header__name {
display: inline-flex; display: inline-flex;
+1 -1
View File
@@ -5,4 +5,4 @@
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" ("attr(href) ")"}abbr[title]:after{content:" ("attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}*{box-sizing:border-box}:after,:before{box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-Line truncated *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" ("attr(href) ")"}abbr[title]:after{content:" ("attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}*{box-sizing:border-box}:after,:before{box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-Line truncated
* Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:""}.fa-accessible-icon:before{content:""}.fa-accusoft:before{content:""}.fa-acquisitions-incorporated:before{content:""}.fa-ad:before{content:""}.fa-address-book:before{content:""}.fa-address-card:before{content:""}.fa-adjust:before{content:""}.fa-adn:before{content:""}.fa-adversal:before{content:""}.fa-affiliatetheme:before{content:""}.fa-air-freshener:before{content:""}.fa-airbnb:before{content:""}.fa-algolia:before{content:""}.fa-align-center:before{content:""}.fa-align-justify:before{content:""}.fa-align-left:before{content:""}.fa-align-right:before{content:""}.fa-alipay:before{content:""}.fa-allergies:before{content:""}.fa-amazon:before{content:""}.fa-amazon-pay:before{content:""}.fa-ambulance:before{content:""}.fa-american-sign-language-interpreting:before{content:""}.fa-amilia:before{content:""}.fa-anchor:before{content:""}.fa-android:before{content:""}.fa-angellist:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angry:before{content:""}.fa-angrycreative:before{content:""}.fa-angular:before{content:""}.fa-ankh:before{content:""}.fa-app-store:before{content:""}.fa-app-store-ios:before{content:""}.fa-apper:before{content:""}.fa-apple:before{content:""}.fa-apple-alt:before{content:""}.fa-apple-pay:before{content:""}.fa-archive:before{content:""}.fa-archway:before{content:""}.fa-arrow-alt-circle-down:before{content:""}.fa-arrow-alt-circle-left:before{content:""}.fa-arrow-alt-circle-right:before{content:""}.fa-arrow-alt-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-down:before{content:""}.fLine truncated */.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:""}.fa-accessible-icon:before{content:""}.fa-accusoft:before{content:""}.fa-acquisitions-incorporated:before{content:""}.fa-ad:before{content:""}.fa-address-book:before{content:""}.fa-address-card:before{content:""}.fa-adjust:before{content:""}.fa-adn:before{content:""}.fa-adversal:before{content:""}.fa-affiliatetheme:before{content:""}.fa-air-freshener:before{content:""}.fa-airbnb:before{content:""}.fa-algolia:before{content:""}.fa-align-center:before{content:""}.fa-align-justify:before{content:""}.fa-align-left:before{content:""}.fa-align-right:before{content:""}.fa-alipay:before{content:""}.fa-allergies:before{content:""}.fa-amazon:before{content:""}.fa-amazon-pay:before{content:""}.fa-ambulance:before{content:""}.fa-american-sign-language-interpreting:before{content:""}.fa-amilia:before{content:""}.fa-anchor:before{content:""}.fa-android:before{content:""}.fa-angellist:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angry:before{content:""}.fa-angrycreative:before{content:""}.fa-angular:before{content:""}.fa-ankh:before{content:""}.fa-app-store:before{content:""}.fa-app-store-ios:before{content:""}.fa-apper:before{content:""}.fa-apple:before{content:""}.fa-apple-alt:before{content:""}.fa-apple-pay:before{content:""}.fa-archive:before{content:""}.fa-archway:before{content:""}.fa-arrow-alt-circle-down:before{content:""}.fa-arrow-alt-circle-left:before{content:""}.fa-arrow-alt-circle-right:before{content:""}.fa-arrow-alt-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-down:before{content:""}.fLine truncated
-134
View File
@@ -738,58 +738,6 @@ article.article.box-body,
} }
/* source: assets/css/frontend/single-post/author-actions.css */ /* source: assets/css/frontend/single-post/author-actions.css */
/* ===== Author Bar (inside article card) ===== */
.article-author-bar {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 16px;
}
.article-author-bar__avatar {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
}
.article-author-bar__info {
flex: 1;
min-width: 0;
}
.article-author-bar__name {
font-weight: 600;
font-size: 14px;
color: var(--color-ink);
}
.article-author-bar__name:hover {
color: var(--color-primary);
}
.article-author-bar__meta {
display: flex;
flex-wrap: wrap;
gap: 10px;
font-size: 12px;
color: var(--color-ink-4, var(--color-ink-4));
margin-top: 2px;
}
.article-author-bar__meta span {
display: inline-flex;
align-items: center;
gap: 3px;
}
.article-author-bar__line {
height: 1px;
background: var(--color-line);
margin-bottom: 20px;
}
/* ===== Content Footer ===== */ /* ===== Content Footer ===== */
.article-footer { .article-footer {
margin-top: 32px; margin-top: 32px;
@@ -1210,88 +1158,6 @@ html.dark .post-drop-meta__item:hover {
text-align: center; text-align: center;
} }
.author-box__header {
display: flex;
align-items: flex-start;
gap: 14px;
}
.author-box__avatar {
width: 56px;
height: 56px;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
border: 3px solid var(--color-primary-soft, rgba(240, 68, 148, 0.2));
}
.author-box__info {
flex: 1;
min-width: 0;
}
.author-box__name {
font-size: 1rem;
font-weight: 700;
color: var(--color-ink);
display: block;
margin-bottom: 4px;
}
.author-box__name:hover { color: var(--color-primary); }
.author-box__bio {
font-size: 13px;
color: var(--color-ink-3, var(--color-ink-4));
line-height: 1.5;
margin: 0 0 6px;
}
.author-box__stats {
font-size: 12px;
color: var(--color-ink-4, var(--color-ink-4));
}
.author-box__stats strong {
color: var(--color-ink);
margin-right: 2px;
}
.author-box__posts {
margin-top: 14px;
padding-top: 12px;
border-top: 1px solid var(--color-line);
}
.author-box__posts-title {
font-size: 12px;
font-weight: 600;
color: var(--color-ink-3, var(--color-ink-4));
margin: 0 0 8px;
}
.author-box__posts ul {
list-style: none;
margin: 0;
padding: 0;
}
.author-box__posts li { padding: 3px 0; }
.author-box__posts a {
font-size: 13px;
color: var(--color-ink);
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.author-box__posts a:hover { color: var(--color-primary); }
.author-box__posts a::before { content: '\2022'; color: var(--color-primary); }
/* ===== legacy single-metabox / author bar ===== */ /* ===== legacy single-metabox / author bar ===== */
.article-avatar .user-info { .article-avatar .user-info {
width: 100%; width: 100%;
+1 -1
View File
@@ -1 +1 @@
.relative{position:relative}.flex{display:flex}.flex.ac,.ac{align-items:center}.flex.jc,.jc{justify-content:center}.flex.jsb,.jsb{justify-content:space-between}.flex.at,.at{align-items:flex-start}.flex.ae,.ae{align-items:flex-end}.flex0{flex:0 0 auto}.flex1{flex:1 1 auto;min-width:0}.flex.column{flex-direction:column}.flex.wrap{flex-wrap:wrap}.flex.flex-row,.flex-row{flex-direction:row}.flex.jse,.jse{justify-content:space-evenly}.flex.jsa,.jsa{justify-content:space-around}.flex>.flex1,.flex .flex1{flex:1;overflow:hidden;min-width:0}.relative-h{position:relative;height:100%}.padding-10{padding:10px}.font-bold{font-weight:700}.mt6{margin-top:6px}.gutters-5{margin:-5px}.gutters-5>*{padding:5px}@media(max-width:767px){.flex.flex-row.flex-col-sm-2{flex-wrap:wrap}.flex.flex-row.flex-col-sm-2>*{flex-basis:50%}}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}.abs-right{position:absolute;right:0;top:0}.abs-center{position:absolute;left:0;width:100%;top:50%;right:.7em;transform:translateY(-50%);z-index:1}.abs-center.left-top,.abs-center.right-top{transform:unset;top:0}.abs-center.right-top{left:auto;width:auto;text-align:right}.abs-center.left-top{text-align:left}.abs-center.conter-bottom,.abs-center.conter-conter{text-align:center}.abs-center.right-top,.abs-center.right-bottom,.abs-center.right-conter{text-align:right}.abs-center.conter-bottom,.abs-center.right-bottom,.abs-center.left-bottom{top:auto;transform:unset;bottom:0}.abs-center.left-bottom{left:0;right:auto;text-align:left}.abs-center.right-bottom,.abs-center.right-conter{left:auto;right:0;text-align:right}.graphic,.page-cover{text-shadow:0 0 5px rgba(0,0,0,.2);--main-color: #fff;color:#fff;position:relative;overflow:hidden;box-shadow:0 0 10px var(--main-shadow, rgba(116, 116, 116, .08));padding:0 0 70%;border-radius:var(--main-radius, var(--radius, 8px))}.graphic>.fit-cover,.graphic>img.fit-cover{position:absolute;width:100%;height:100%;object-fit:cover;inset:0}.fit-cover{object-fit:cover;max-width:100%}.title-h-left{position:relative;padding-bottom:8px}.title-h-left:before{transition:.4s;transform-origin:left;position:absolute;content:"";width:40px;height:3px;background:var(--theme-color, var(--focus-color, #f04494));left:0;bottom:3px;border-radius:5px;box-shadow:1px 1px 3px -1px var(--theme-color, var(--focus-color, #f04494))}.line-form-line,.line-form-line:before{position:absolute;bottom:0;left:0;height:1px;width:100%;transition:.8s;background:var(--main-border-color, rgba(50, 50, 50, .06))}.line-form-line:before{content:"";width:0;background:var(--focus-color, #f04494)}.avatar-img{position:relative;display:inline-block;flex-shrink:0;--this-size: 38px;width:var(--this-size);height:var(--this-size)}.avatar-img .avatar,.avatar-img img{width:100%;height:100%;border-radius:50%;object-fit:cover}.avatar-lg{--this-size: 80px}.avatar-md{--this-size: 55px}.avatar-mini{--this-size: 20px}.shrink0{flex-shrink:0}.opacity8{opacity:.8}.muted-color{color:var(--muted-color, var(--color-ink-3))}.muted-2-color{color:var(--muted-2-color, var(--color-ink-4))}.muted-3-color{color:var(--muted-3-color, #b1b1b1)}.muted-4-color{color:var(--muted-4-color, #d2d2d2)}.text-center{text-align:center}.em09{font-size:.9em}.em12{font-size:1.2em}.px12-sm{font-size:12px}.ml3{margin-left:3px}.ml6{margin-left:6px}.ml10{margin-left:10px}.mr3{margin-right:3px}.mr6{margin-right:6px}.mt10{margin-top:10px}.mt20{margin-top:20px}.mb10{margin-bottom:10px}.mb20{margin-bottom:20px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.text-ellipsis-2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.main-bg{background-color:var(--main-bg-color, var(--surface-1))}.separator{position:relative;letter-spacing:.08em}.icon-circle+.icon-circle:before{content:"·";display:inline-block;margin:0 .45em;opacity:.55}.article-avatar name,.article-avatar .name,.user-name{display:inline-flex;align-items:center;gap:4px;min-width:0;max-width:100%}.pull-right{float:right}.pull-left{float:left}body.single main.container .content-layout{display:block;min-width:0}body.single main.container .content-layout>*{min-width:0;max-width:100%}body.single main.container .content-layout>.breadcrumb,body.single main.container .content-layout>ul.breadcrumb,body.single main.container .content-layout>.breadcrumb-nav,body.single main.container .content-layout>.breadcrumbs-wrap{position:relative;z-index:1;margin-top:0;margin-bottom:12px;padding-top:2px}body.single .sidebar .aksrt-panel,body.single .sidebar .widget{margin-bottom:15px}body.single main.container{box-sizing:border-box}.article,article.article.box-body,.article.main-bg.box-body{padding:0 30px;overflow:hidden}@media(max-width:767px){.article,article.article.box-body,.article.main-bg.box-body{padding:0 15px}.article-header .article-title{font-size:18px}}.entry-header,.article-header{margin-bottom:10px;padding-bottom:0;border-bottom:none;background:tranLine truncated .relative{position:relative}.flex{display:flex}.flex.ac,.ac{align-items:center}.flex.jc,.jc{justify-content:center}.flex.jsb,.jsb{justify-content:space-between}.flex.at,.at{align-items:flex-start}.flex.ae,.ae{align-items:flex-end}.flex0{flex:0 0 auto}.flex1{flex:1 1 auto;min-width:0}.flex.column{flex-direction:column}.flex.wrap{flex-wrap:wrap}.flex.flex-row,.flex-row{flex-direction:row}.flex.jse,.jse{justify-content:space-evenly}.flex.jsa,.jsa{justify-content:space-around}.flex>.flex1,.flex .flex1{flex:1;overflow:hidden;min-width:0}.relative-h{position:relative;height:100%}.padding-10{padding:10px}.font-bold{font-weight:700}.mt6{margin-top:6px}.gutters-5{margin:-5px}.gutters-5>*{padding:5px}@media(max-width:767px){.flex.flex-row.flex-col-sm-2{flex-wrap:wrap}.flex.flex-row.flex-col-sm-2>*{flex-basis:50%}}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}.abs-right{position:absolute;right:0;top:0}.abs-center{position:absolute;left:0;width:100%;top:50%;right:.7em;transform:translateY(-50%);z-index:1}.abs-center.left-top,.abs-center.right-top{transform:unset;top:0}.abs-center.right-top{left:auto;width:auto;text-align:right}.abs-center.left-top{text-align:left}.abs-center.conter-bottom,.abs-center.conter-conter{text-align:center}.abs-center.right-top,.abs-center.right-bottom,.abs-center.right-conter{text-align:right}.abs-center.conter-bottom,.abs-center.right-bottom,.abs-center.left-bottom{top:auto;transform:unset;bottom:0}.abs-center.left-bottom{left:0;right:auto;text-align:left}.abs-center.right-bottom,.abs-center.right-conter{left:auto;right:0;text-align:right}.graphic,.page-cover{text-shadow:0 0 5px rgba(0,0,0,.2);--main-color: #fff;color:#fff;position:relative;overflow:hidden;box-shadow:0 0 10px var(--main-shadow, rgba(116, 116, 116, .08));padding:0 0 70%;border-radius:var(--main-radius, var(--radius, 8px))}.graphic>.fit-cover,.graphic>img.fit-cover{position:absolute;width:100%;height:100%;object-fit:cover;inset:0}.fit-cover{object-fit:cover;max-width:100%}.title-h-left{position:relative;padding-bottom:8px}.title-h-left:before{transition:.4s;transform-origin:left;position:absolute;content:"";width:40px;height:3px;background:var(--theme-color, var(--focus-color, #f04494));left:0;bottom:3px;border-radius:5px;box-shadow:1px 1px 3px -1px var(--theme-color, var(--focus-color, #f04494))}.line-form-line,.line-form-line:before{position:absolute;bottom:0;left:0;height:1px;width:100%;transition:.8s;background:var(--main-border-color, rgba(50, 50, 50, .06))}.line-form-line:before{content:"";width:0;background:var(--focus-color, #f04494)}.avatar-img{position:relative;display:inline-block;flex-shrink:0;--this-size: 38px;width:var(--this-size);height:var(--this-size)}.avatar-img .avatar,.avatar-img img{width:100%;height:100%;border-radius:50%;object-fit:cover}.avatar-lg{--this-size: 80px}.avatar-md{--this-size: 55px}.avatar-mini{--this-size: 20px}.shrink0{flex-shrink:0}.opacity8{opacity:.8}.muted-color{color:var(--muted-color, var(--color-ink-3))}.muted-2-color{color:var(--muted-2-color, var(--color-ink-4))}.muted-3-color{color:var(--muted-3-color, #b1b1b1)}.muted-4-color{color:var(--muted-4-color, #d2d2d2)}.text-center{text-align:center}.em09{font-size:.9em}.em12{font-size:1.2em}.px12-sm{font-size:12px}.ml3{margin-left:3px}.ml6{margin-left:6px}.ml10{margin-left:10px}.mr3{margin-right:3px}.mr6{margin-right:6px}.mt10{margin-top:10px}.mt20{margin-top:20px}.mb10{margin-bottom:10px}.mb20{margin-bottom:20px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.text-ellipsis-2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.main-bg{background-color:var(--main-bg-color, var(--surface-1))}.separator{position:relative;letter-spacing:.08em}.icon-circle+.icon-circle:before{content:"·";display:inline-block;margin:0 .45em;opacity:.55}.article-avatar name,.article-avatar .name,.user-name{display:inline-flex;align-items:center;gap:4px;min-width:0;max-width:100%}.pull-right{float:right}.pull-left{float:left}body.single main.container .content-layout{display:block;min-width:0}body.single main.container .content-layout>*{min-width:0;max-width:100%}body.single main.container .content-layout>.breadcrumb,body.single main.container .content-layout>ul.breadcrumb,body.single main.container .content-layout>.breadcrumb-nav,body.single main.container .content-layout>.breadcrumbs-wrap{position:relative;z-index:1;margin-top:0;margin-bottom:12px;padding-top:2px}body.single .sidebar .aksrt-panel,body.single .sidebar .widget{margin-bottom:15px}body.single main.container{box-sizing:border-box}.article,article.article.box-body,.article.main-bg.box-body{padding:0 30px;overflow:hidden}@media(max-width:767px){.article,article.article.box-body,.article.main-bg.box-body{padding:0 15px}.article-header .article-title{font-size:18px}}.entry-header,.article-header{margin-bottom:10px;padding-bottom:0;border-bottom:none;background:tranLine truncated
-11
View File
@@ -178,17 +178,6 @@
.but a { color: inherit; } .but a { color: inherit; }
/* 关注控件(.follow 且无 .but):纯文字色样式,无背景色;
清除原生 button 的 UA 背景/边框,并保持 .but 同款可点反馈 */
.follow:not(.but) {
background: transparent;
border: none;
padding: 0;
cursor: pointer;
transition: 0.15s;
}
.follow:not(.but):hover { opacity: 0.8; }
.but .icon, .but .icon,
.but > .fa:not(.fa-angle-right), .but > .fa:not(.fa-angle-right),
.but > i[class*="fa-"]:not(.fa-angle-right) { margin-right: 0.25em; } .but > i[class*="fa-"]:not(.fa-angle-right) { margin-right: 0.25em; }
+11
View File
@@ -259,6 +259,17 @@ main.container,
flex-wrap: nowrap; flex-wrap: nowrap;
white-space: nowrap; white-space: nowrap;
} }
.user-card.author .user-name > name {
overflow: visible;
}
.user-card.author .user-name > name > .display-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.user-card.author .user-name > name > .follow {
flex-shrink: 0;
}
.aksrt-author-hero__name, .aksrt-author-hero__name,
.uc-header__name { .uc-header__name {
display: inline-flex; display: inline-flex;
@@ -1,55 +1,3 @@
/* ===== Author Bar (inside article card) ===== */
.article-author-bar {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 16px;
}
.article-author-bar__avatar {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
}
.article-author-bar__info {
flex: 1;
min-width: 0;
}
.article-author-bar__name {
font-weight: 600;
font-size: 14px;
color: var(--color-ink);
}
.article-author-bar__name:hover {
color: var(--color-primary);
}
.article-author-bar__meta {
display: flex;
flex-wrap: wrap;
gap: 10px;
font-size: 12px;
color: var(--color-ink-4, var(--color-ink-4));
margin-top: 2px;
}
.article-author-bar__meta span {
display: inline-flex;
align-items: center;
gap: 3px;
}
.article-author-bar__line {
height: 1px;
background: var(--color-line);
margin-bottom: 20px;
}
/* ===== Content Footer ===== */ /* ===== Content Footer ===== */
.article-footer { .article-footer {
margin-top: 32px; margin-top: 32px;
@@ -470,88 +418,6 @@ html.dark .post-drop-meta__item:hover {
text-align: center; text-align: center;
} }
.author-box__header {
display: flex;
align-items: flex-start;
gap: 14px;
}
.author-box__avatar {
width: 56px;
height: 56px;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
border: 3px solid var(--color-primary-soft, rgba(240, 68, 148, 0.2));
}
.author-box__info {
flex: 1;
min-width: 0;
}
.author-box__name {
font-size: 1rem;
font-weight: 700;
color: var(--color-ink);
display: block;
margin-bottom: 4px;
}
.author-box__name:hover { color: var(--color-primary); }
.author-box__bio {
font-size: 13px;
color: var(--color-ink-3, var(--color-ink-4));
line-height: 1.5;
margin: 0 0 6px;
}
.author-box__stats {
font-size: 12px;
color: var(--color-ink-4, var(--color-ink-4));
}
.author-box__stats strong {
color: var(--color-ink);
margin-right: 2px;
}
.author-box__posts {
margin-top: 14px;
padding-top: 12px;
border-top: 1px solid var(--color-line);
}
.author-box__posts-title {
font-size: 12px;
font-weight: 600;
color: var(--color-ink-3, var(--color-ink-4));
margin: 0 0 8px;
}
.author-box__posts ul {
list-style: none;
margin: 0;
padding: 0;
}
.author-box__posts li { padding: 3px 0; }
.author-box__posts a {
font-size: 13px;
color: var(--color-ink);
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.author-box__posts a:hover { color: var(--color-primary); }
.author-box__posts a::before { content: '\2022'; color: var(--color-primary); }
/* ===== legacy single-metabox / author bar ===== */ /* ===== legacy single-metabox / author bar ===== */
.article-avatar .user-info { .article-avatar .user-info {
width: 100%; width: 100%;
+58 -59
View File
@@ -4508,31 +4508,60 @@ tbquire.config({
/** /**
* AKSRT Follow — 前台关注交互 * AKSRT Follow — 前台关注交互
* *
* 监听 [data-aksrt-follow] 按钮点击,切换关注状态。
*
* @package AKSRT * @package AKSRT
*/ */
(function () { (function () {
'use strict'; 'use strict';
var API_ROOT = (function () { var API_ROOT = (function () {
var d = window.aksrtData || {}; var data = window.aksrtData || {};
var raw = d.apiUrl || d.restUrl || d.rest_url || '/index.php?rest_route=/aksrt/v1'; var raw = data.apiUrl || data.restUrl || data.rest_url || '/index.php?rest_route=/aksrt/v1';
return String(raw).replace(/\/$/, ''); return String(raw).replace(/\/$/, '');
})(); })();
var NONCE = (window.aksrtData && window.aksrtData.restNonce) || ''; var NONCE = (window.aksrtData && window.aksrtData.restNonce) || '';
function buttonsFor(userId) {
return Array.prototype.slice.call(document.querySelectorAll('[data-aksrt-follow="' + userId + '"]'));
}
function setLoading(buttons, loading) {
buttons.forEach(function (button) {
button.disabled = loading;
button.classList.toggle('is-loading', loading);
});
}
function updateButton(button, isFollowing) {
var icon = button.querySelector('i');
var label = button.querySelector('[data-aksrt-follow-label]');
if (!label) return;
button.classList.toggle('is-following', isFollowing);
if (icon) {
icon.className = isFollowing ? 'fa fas fa-heart em09' : 'fa far fa-heart em09';
}
label.textContent = isFollowing ? '已关注' : '关注';
button.title = isFollowing ? '点击取消关注' : '关注该用户';
}
function updateFollowerCount(count) {
var countEl = document.querySelector('.aksrt-user-home__stat-value[data-followers]');
if (countEl && count !== undefined) {
countEl.textContent = count;
}
}
// 初始关注状态由服务端渲染(is-following class + 文案),无需逐按钮查询。
function initFollowButtons() { function initFollowButtons() {
document.addEventListener('click', function (e) { document.addEventListener('click', function (event) {
var btn = e.target.closest('[data-aksrt-follow]'); var button = event.target.closest('[data-aksrt-follow]');
if (!btn) return; if (!button) return;
e.preventDefault(); event.preventDefault();
var targetUserId = parseInt(btn.getAttribute('data-aksrt-follow')); var targetUserId = parseInt(button.getAttribute('data-aksrt-follow'), 10);
if (!targetUserId) return; if (!targetUserId || button.disabled) return;
btn.disabled = true; var matchingButtons = buttonsFor(targetUserId);
setLoading(matchingButtons, true);
fetch(API_ROOT + '/follow/toggle', { fetch(API_ROOT + '/follow/toggle', {
method: 'POST', method: 'POST',
@@ -4542,64 +4571,34 @@ tbquire.config({
}, },
body: JSON.stringify({ target_user_id: targetUserId }), body: JSON.stringify({ target_user_id: targetUserId }),
}) })
.then(function (res) { return res.json(); }) .then(function (response) { return response.json(); })
.then(function (result) { .then(function (result) {
if (result.success && result.data) { if (!result.success || !result.data) {
var isFollowing = result.data.is_following;
updateFollowButton(btn, isFollowing, result.data.follower_count);
notyf(isFollowing ? '关注成功' : '已取消关注', 'success');
} else {
notyf(result.message || '操作失败', 'danger'); notyf(result.message || '操作失败', 'danger');
return;
} }
var isFollowing = Boolean(result.data.is_following);
matchingButtons.forEach(function (matchingButton) {
updateButton(matchingButton, isFollowing);
});
updateFollowerCount(result.data.follower_count);
if (!isFollowing) {
var managementItem = button.closest('.uc-follow-management__item');
if (managementItem) managementItem.remove();
}
notyf(isFollowing ? '关注成功' : '已取消关注', 'success');
}) })
.catch(function () { .catch(function () {
notyf('网络错误,请重试', 'danger'); notyf('网络错误,请重试', 'danger');
}) })
.finally(function () { .finally(function () {
btn.disabled = false; setLoading(matchingButtons, false);
}); });
}); });
} }
function updateFollowButton(btn, isFollowing, count) {
var icon = btn.querySelector('i');
var text = btn.querySelector('span');
function setLabel(label) {
if (text) {
text.textContent = label;
return;
}
// Fallback when markup has bare text nodes next to the icon.
var nodes = Array.prototype.slice.call(btn.childNodes);
var textNode = nodes.filter(function (n) { return n.nodeType === 3 && n.textContent.trim() !== ''; })[0];
if (textNode) {
textNode.textContent = ' ' + label + ' ';
}
}
if (isFollowing) {
btn.classList.add('is-following');
if (icon) icon.className = 'fa fas fa-heart';
setLabel('已关注');
btn.title = '点击取消关注';
} else {
btn.classList.remove('is-following');
if (icon) icon.className = 'fa fas fa-heart';
setLabel('关注');
btn.title = '关注该用户';
}
if (!isFollowing && btn.closest('.uc-follow-management__item')) {
btn.closest('.uc-follow-management__item').remove();
}
// Update follower count display if exists
var countEl = document.querySelector('.aksrt-user-home__stat-value[data-followers]');
if (countEl && count !== undefined) {
countEl.textContent = count;
}
}
if (document.readyState === 'loading') { if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initFollowButtons); document.addEventListener('DOMContentLoaded', initFollowButtons);
} else { } else {
+58 -59
View File
@@ -1,31 +1,60 @@
/** /**
* AKSRT Follow — 前台关注交互 * AKSRT Follow — 前台关注交互
* *
* 监听 [data-aksrt-follow] 按钮点击,切换关注状态。
*
* @package AKSRT * @package AKSRT
*/ */
(function () { (function () {
'use strict'; 'use strict';
var API_ROOT = (function () { var API_ROOT = (function () {
var d = window.aksrtData || {}; var data = window.aksrtData || {};
var raw = d.apiUrl || d.restUrl || d.rest_url || '/index.php?rest_route=/aksrt/v1'; var raw = data.apiUrl || data.restUrl || data.rest_url || '/index.php?rest_route=/aksrt/v1';
return String(raw).replace(/\/$/, ''); return String(raw).replace(/\/$/, '');
})(); })();
var NONCE = (window.aksrtData && window.aksrtData.restNonce) || ''; var NONCE = (window.aksrtData && window.aksrtData.restNonce) || '';
function buttonsFor(userId) {
return Array.prototype.slice.call(document.querySelectorAll('[data-aksrt-follow="' + userId + '"]'));
}
function setLoading(buttons, loading) {
buttons.forEach(function (button) {
button.disabled = loading;
button.classList.toggle('is-loading', loading);
});
}
function updateButton(button, isFollowing) {
var icon = button.querySelector('i');
var label = button.querySelector('[data-aksrt-follow-label]');
if (!label) return;
button.classList.toggle('is-following', isFollowing);
if (icon) {
icon.className = isFollowing ? 'fa fas fa-heart em09' : 'fa far fa-heart em09';
}
label.textContent = isFollowing ? '已关注' : '关注';
button.title = isFollowing ? '点击取消关注' : '关注该用户';
}
function updateFollowerCount(count) {
var countEl = document.querySelector('.aksrt-user-home__stat-value[data-followers]');
if (countEl && count !== undefined) {
countEl.textContent = count;
}
}
// 初始关注状态由服务端渲染(is-following class + 文案),无需逐按钮查询。
function initFollowButtons() { function initFollowButtons() {
document.addEventListener('click', function (e) { document.addEventListener('click', function (event) {
var btn = e.target.closest('[data-aksrt-follow]'); var button = event.target.closest('[data-aksrt-follow]');
if (!btn) return; if (!button) return;
e.preventDefault(); event.preventDefault();
var targetUserId = parseInt(btn.getAttribute('data-aksrt-follow')); var targetUserId = parseInt(button.getAttribute('data-aksrt-follow'), 10);
if (!targetUserId) return; if (!targetUserId || button.disabled) return;
btn.disabled = true; var matchingButtons = buttonsFor(targetUserId);
setLoading(matchingButtons, true);
fetch(API_ROOT + '/follow/toggle', { fetch(API_ROOT + '/follow/toggle', {
method: 'POST', method: 'POST',
@@ -35,64 +64,34 @@
}, },
body: JSON.stringify({ target_user_id: targetUserId }), body: JSON.stringify({ target_user_id: targetUserId }),
}) })
.then(function (res) { return res.json(); }) .then(function (response) { return response.json(); })
.then(function (result) { .then(function (result) {
if (result.success && result.data) { if (!result.success || !result.data) {
var isFollowing = result.data.is_following;
updateFollowButton(btn, isFollowing, result.data.follower_count);
notyf(isFollowing ? '关注成功' : '已取消关注', 'success');
} else {
notyf(result.message || '操作失败', 'danger'); notyf(result.message || '操作失败', 'danger');
return;
} }
var isFollowing = Boolean(result.data.is_following);
matchingButtons.forEach(function (matchingButton) {
updateButton(matchingButton, isFollowing);
});
updateFollowerCount(result.data.follower_count);
if (!isFollowing) {
var managementItem = button.closest('.uc-follow-management__item');
if (managementItem) managementItem.remove();
}
notyf(isFollowing ? '关注成功' : '已取消关注', 'success');
}) })
.catch(function () { .catch(function () {
notyf('网络错误,请重试', 'danger'); notyf('网络错误,请重试', 'danger');
}) })
.finally(function () { .finally(function () {
btn.disabled = false; setLoading(matchingButtons, false);
}); });
}); });
} }
function updateFollowButton(btn, isFollowing, count) {
var icon = btn.querySelector('i');
var text = btn.querySelector('span');
function setLabel(label) {
if (text) {
text.textContent = label;
return;
}
// Fallback when markup has bare text nodes next to the icon.
var nodes = Array.prototype.slice.call(btn.childNodes);
var textNode = nodes.filter(function (n) { return n.nodeType === 3 && n.textContent.trim() !== ''; })[0];
if (textNode) {
textNode.textContent = ' ' + label + ' ';
}
}
if (isFollowing) {
btn.classList.add('is-following');
if (icon) icon.className = 'fa fas fa-heart';
setLabel('已关注');
btn.title = '点击取消关注';
} else {
btn.classList.remove('is-following');
if (icon) icon.className = 'fa fas fa-heart';
setLabel('关注');
btn.title = '关注该用户';
}
if (!isFollowing && btn.closest('.uc-follow-management__item')) {
btn.closest('.uc-follow-management__item').remove();
}
// Update follower count display if exists
var countEl = document.querySelector('.aksrt-user-home__stat-value[data-followers]');
if (countEl && count !== undefined) {
countEl.textContent = count;
}
}
if (document.readyState === 'loading') { if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initFollowButtons); document.addEventListener('DOMContentLoaded', initFollowButtons);
} else { } else {
+4 -7
View File
@@ -68,13 +68,10 @@ if (!function_exists('aksrt_resolve_single_post_display_settings')) :
if (!array_key_exists('breadcrumbs_home', $settings) && array_key_exists('breadcrumbs_home_text', $settings)) { if (!array_key_exists('breadcrumbs_home', $settings) && array_key_exists('breadcrumbs_home_text', $settings)) {
$settings['breadcrumbs_home'] = (string) $settings['breadcrumbs_home_text']; $settings['breadcrumbs_home'] = (string) $settings['breadcrumbs_home_text'];
} }
if (!array_key_exists('prevnext', $settings) && array_key_exists('prevnext_s', $settings)) { if (!array_key_exists('prevnext', $settings) && array_key_exists('prevnext_s', $settings)) {
$settings['prevnext'] = !empty($settings['prevnext_s']); $settings['prevnext'] = !empty($settings['prevnext_s']);
} }
if (!array_key_exists('authordesc', $settings) && array_key_exists('authordesc_s', $settings)) { $meta = class_exists('\AKSRT\Core\PostMetaBox') ? \AKSRT\Core\PostMetaBox::get_meta($post->ID) : [];
$settings['authordesc'] = !empty($settings['authordesc_s']);
}
$meta = class_exists('\AKSRT\Core\PostMetaBox') ? \AKSRT\Core\PostMetaBox::get_meta($post->ID) : [];
if (!empty($meta['article_maxheight_xz'])) { if (!empty($meta['article_maxheight_xz'])) {
$settings['maxheight_enabled'] = true; $settings['maxheight_enabled'] = true;
} elseif (empty($settings['maxheight_enabled'])) { } elseif (empty($settings['maxheight_enabled'])) {
+5 -20
View File
@@ -241,27 +241,12 @@ if (!function_exists('aksrt_author_minicard')) :
]) ])
: '<a href="' . esc_url($home) . '">' . esc_html($user->display_name) . '</a>'; : '<a href="' . esc_url($home) . '">' . esc_html($user->display_name) . '</a>';
// Follow control (separate from name, legacy places both in dt). // Follow control (separate from name, legacy places both in dt).
// 服务端直接输出真实关注状态(legacy parity: zib_get_user_follow 恒渲染当前态)。 $follow = function_exists('aksrt_get_user_follow')
$follow = ''; ? aksrt_get_user_follow('focus-color px12 ml10 follow flex0 but', $user_id)
$current = get_current_user_id(); : '';
if ($current !== $user_id) {
$is_following = false;
if (is_user_logged_in() && class_exists('\AKSRT\User\Follow')) {
$is_following = \AKSRT\User\Follow::get_instance()->is_following($current, $user_id);
}
$follow_label = $is_following ? __('已关注', 'aksrt') : __('关注', 'aksrt');
$follow_title = $is_following ? __('点击取消关注', 'aksrt') : __('关注该用户', 'aksrt');
$follow_state = $is_following ? ' is-following' : '';
if (is_user_logged_in()) {
$follow = '<button type="button" class="focus-color px12 ml10 follow flex0 but' . $follow_state . '" data-aksrt-follow="' . (int) $user_id . '" title="' . esc_attr($follow_title) . '"><i class="fa fas fa-heart em09" aria-hidden="true"></i> ' . esc_html($follow_label) . '</button>';
} else {
$login = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url();
$follow = '<a class="focus-color px12 ml10 follow flex0 but" href="' . esc_url($login) . '"><i class="fa fas fa-heart em09" aria-hidden="true"></i> ' . esc_html__('关注', 'aksrt') . '</a>';
}
}
$desc = function_exists('aksrt_get_user_description') ? aksrt_get_user_description($user_id) : trim((string) get_user_meta($user_id, 'description', true)); $desc = function_exists('aksrt_get_user_description') ? aksrt_get_user_description($user_id) : trim((string) get_user_meta($user_id, 'description', true));
$blur = ''; $blur = '';
if ($blur_bg) { if ($blur_bg) {
+38 -16
View File
@@ -119,6 +119,37 @@ if (!function_exists('aksrt_render_user_identity_chips')) {
} }
} }
if (!function_exists('aksrt_get_user_follow')) {
/**
* Render the canonical user follow control.
*/
function aksrt_get_user_follow(string $class, int $follow_id, ?string $text = null, ?string $ok_text = null, ?string $guest_text = null): string {
$current_user_id = get_current_user_id();
if ($follow_id <= 0 || $current_user_id === $follow_id) {
return '';
}
$text = $text ?? __('关注', 'aksrt');
$ok_text = $ok_text ?? __('已关注', 'aksrt');
$guest_text = $guest_text ?? $text;
$class = trim($class);
if (!is_user_logged_in()) {
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url();
return '<a class="' . esc_attr($class) . '" href="' . esc_url($login_url) . '"><i class="fa far fa-heart em09" aria-hidden="true"></i> <span>' . esc_html($guest_text) . '</span></a>';
}
$is_following = class_exists('\AKSRT\User\Follow')
&& \AKSRT\User\Follow::get_instance()->is_following($current_user_id, $follow_id);
$state_class = $is_following ? ' is-following' : '';
$title = $is_following ? __('点击取消关注', 'aksrt') : __('关注该用户', 'aksrt');
$label = $is_following ? $ok_text : $text;
$icon_class = $is_following ? 'fa fas fa-heart em09' : 'fa far fa-heart em09';
return '<a href="javascript:;" class="' . esc_attr($class . $state_class) . '" data-aksrt-follow="' . $follow_id . '" title="' . esc_attr($title) . '"><i class="' . esc_attr($icon_class) . '" aria-hidden="true"></i> <span data-aksrt-follow-label>' . esc_html($label) . '</span></a>';
}
}
if (!function_exists('aksrt_get_user_name')) { if (!function_exists('aksrt_get_user_name')) {
/** /**
* legacy parity: name link + auth + wear medal + level + optional follow. * legacy parity: name link + auth + wear medal + level + optional follow.
@@ -155,7 +186,9 @@ if (!function_exists('aksrt_get_user_name')) {
return ''; return '';
} }
$home = function_exists('get_author_posts_url') ? get_author_posts_url($user_id) : ''; $home = function_exists('aksrt_get_user_home_url')
? aksrt_get_user_home_url($user_id)
: get_author_posts_url($user_id);
$display = $user->display_name; $display = $user->display_name;
$vip_html = ''; $vip_html = '';
if (!empty($args['vip']) && function_exists('aksrt_render_vip_badge')) { if (!empty($args['vip']) && function_exists('aksrt_render_vip_badge')) {
@@ -220,22 +253,11 @@ if (!function_exists('aksrt_get_user_name')) {
} }
} }
$follow_html = ''; $follow_html = !empty($args['follow'])
if (!empty($args['follow']) && get_current_user_id() !== $user_id) { ? aksrt_get_user_follow('focus-color ml10 follow flex0', $user_id)
if (is_user_logged_in()) { : '';
// 服务端直接输出真实关注状态(legacy parity: zib_get_user_follow 恒渲染当前态)。
$is_following = class_exists('\AKSRT\User\Follow') && \AKSRT\User\Follow::get_instance()->is_following(get_current_user_id(), $user_id);
$follow_label = $is_following ? __('已关注', 'aksrt') : __('关注', 'aksrt');
$follow_title = $is_following ? __('点击取消关注', 'aksrt') : __('关注该用户', 'aksrt');
$follow_state = $is_following ? ' is-following' : '';
$follow_html = '<button type="button" class="focus-color ml10 follow flex0' . $follow_state . '" data-aksrt-follow="' . (int) $user_id . '" title="' . esc_attr($follow_title) . '"><i class="fa fas fa-heart em09" aria-hidden="true"></i> ' . esc_html($follow_label) . '</button>';
} else {
$login = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url();
$follow_html = '<a class="focus-color ml10 follow flex0" href="' . esc_url($login) . '"><i class="fa fas fa-heart em09" aria-hidden="true"></i> ' . esc_html__('关注', 'aksrt') . '</a>';
}
}
// Order: name → auth → wear medal → level → follow (legacy). // Order: name → auth → wear medal → level → follow (legacy).
$html = '<name class="' . esc_attr((string) $args['class']) . '">' . $name_link . $vip_html . $auth_html . $medal_html . $level_html . $follow_html . '</name>'; $html = '<name class="' . esc_attr((string) $args['class']) . '">' . $name_link . $vip_html . $auth_html . $medal_html . $level_html . $follow_html . '</name>';
/** /**
* Filter rendered user name chrome. * Filter rendered user name chrome.
+7 -14
View File
@@ -156,13 +156,10 @@ if (!function_exists('aksrt_single_render_box_header')) :
<?php endif; ?> <?php endif; ?>
<?php <?php
// Author bar always shows in header (legacy). get_template_part('templates/parts/single-author-bar', null, [
// `authordesc` only controls the after-box author card. 'show_time' => empty($settings['hide_time']),
aksrt_single_render_author_bar([ 'meta_html' => (string) ($ctx['meta_box_html'] ?? ''),
'show_actions' => true, ]);
'show_time' => empty($settings['hide_time']),
'meta_html' => (string) ($ctx['meta_box_html'] ?? ''),
]);
?> ?>
</div> </div>
<?php <?php
@@ -681,13 +678,9 @@ if (!function_exists('aksrt_single_render_after_box')) :
]); ]);
} }
// Accept both `authordesc` (Settings DTO) and legacy `authordesc_s`. if (!empty($settings['authordesc'])) {
$show_author = array_key_exists('authordesc', $settings) aksrt_single_render_author_card($ctx);
? !empty($settings['authordesc']) }
: !empty($settings['authordesc_s']);
if ($show_author) {
aksrt_single_render_author_card($ctx);
}
aksrt_single_render_prevnext($ctx); aksrt_single_render_prevnext($ctx);
aksrt_single_render_related($ctx); aksrt_single_render_related($ctx);
-17
View File
@@ -137,23 +137,6 @@ if (!function_exists('aksrt_single_is_docs_page')) :
} }
endif; endif;
if (!function_exists('aksrt_single_render_author_bar')) :
/**
* Render author bar from a real args array (no ambient query vars).
*
* @param array<string,mixed> $args Partial args.
*/
function aksrt_single_render_author_bar(array $args = []): void {
$args = wp_parse_args($args, [
'extra_class' => '',
'show_actions' => false,
'show_bio' => false,
'meta_items' => [],
]);
get_template_part('templates/parts/single-author-bar', null, $args);
}
endif;
if (!function_exists('aksrt_single')) : if (!function_exists('aksrt_single')) :
/** /**
* Compose header + article + after-box (legacy equivalent). * Compose header + article + after-box (legacy equivalent).
@@ -47,7 +47,7 @@ $result = $follow
<div class="uc-follow-management__identity"><a href="<?php echo esc_url($home_url); ?>"><?php echo esc_html((string) ($item['display_name'] ?? '')); ?></a><span><?php echo esc_html(sprintf(__('关注于 %s', 'aksrt'), get_date_from_gmt((string) ($item['created_at'] ?? ''), get_option('date_format')))); ?></span></div> <div class="uc-follow-management__identity"><a href="<?php echo esc_url($home_url); ?>"><?php echo esc_html((string) ($item['display_name'] ?? '')); ?></a><span><?php echo esc_html(sprintf(__('关注于 %s', 'aksrt'), get_date_from_gmt((string) ($item['created_at'] ?? ''), get_option('date_format')))); ?></span></div>
<div class="uc-follow-management__actions"> <div class="uc-follow-management__actions">
<a class="btn-ghost btn-sm" href="<?php echo esc_url($home_url); ?>"><?php esc_html_e('主页', 'aksrt'); ?></a> <a class="btn-ghost btn-sm" href="<?php echo esc_url($home_url); ?>"><?php esc_html_e('主页', 'aksrt'); ?></a>
<?php if ($active_list === 'following') : ?><button type="button" class="btn-outline btn-sm is-following" data-aksrt-follow="<?php echo esc_attr((string) $member_id); ?>"><i class="fa fas fa-heart" aria-hidden="true"></i><span><?php esc_html_e('已关注', 'aksrt'); ?></span></button><?php endif; ?> <?php if ($active_list === 'following') : ?><button type="button" class="btn-outline btn-sm is-following" data-aksrt-follow="<?php echo esc_attr((string) $member_id); ?>"><i class="fa fas fa-heart" aria-hidden="true"></i><span data-aksrt-follow-label><?php esc_html_e('已关注', 'aksrt'); ?></span></button><?php endif; ?>
</div> </div>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
+3 -4
View File
@@ -218,12 +218,11 @@ class PostDisplay {
'breadcrumbs_single_s' => $breadcrumbs, 'breadcrumbs_single_s' => $breadcrumbs,
'breadcrumbs_home_text' => $breadcrumbs_home, 'breadcrumbs_home_text' => $breadcrumbs_home,
'breadcrumbs_single_text' => $breadcrumbs_single_text, 'breadcrumbs_single_text' => $breadcrumbs_single_text,
// Canonical + legacy prev/next / author / time. // Canonical + legacy prev/next / time; canonical author card flag.
'prevnext' => $prevnext, 'prevnext' => $prevnext,
'prevnext_s' => $prevnext, 'prevnext_s' => $prevnext,
'authordesc' => $authordesc, 'authordesc' => $authordesc,
'authordesc_s' => $authordesc, 'hide_time' => $hide_time,
'hide_time' => $hide_time,
'single_hide_time_s' => $hide_time, 'single_hide_time_s' => $hide_time,
'article_image_cover' => !isset($settings['post_article_image_cover']) || !empty($settings['post_article_image_cover']), 'article_image_cover' => !isset($settings['post_article_image_cover']) || !empty($settings['post_article_image_cover']),
'article_image_cover_scale'=> max(10, min(100, (int) ($settings['post_article_image_cover_scale'] ?? 35))), 'article_image_cover_scale'=> max(10, min(100, (int) ($settings['post_article_image_cover_scale'] ?? 35))),
+40 -109
View File
@@ -1,14 +1,10 @@
<?php <?php
/** /**
* Shared author info bar for single post content (legacy article-avatar / user-info). * Article header author bar.
* *
* Contract: get_template_part(..., null, $args) * Contract: get_template_part(..., null, $args)
* show_actions bool Follow / PM buttons + meta row * show_time bool Relative publish/update time (default true)
* show_bio bool Append bio after time * meta_html string Prebuilt single-metabox HTML
* show_time bool Relative publish/update time (default true)
* meta_html string Prebuilt legacy single-metabox HTML
* meta_items array Legacy text meta items (fallback)
* extra_class string
* *
* @package AKSRT * @package AKSRT
*/ */
@@ -16,78 +12,61 @@
defined('ABSPATH') || exit; defined('ABSPATH') || exit;
$args = is_array($args ?? null) ? $args : []; $args = is_array($args ?? null) ? $args : [];
$extra_class = (string) ($args['extra_class'] ?? '');
$show_actions = !empty($args['show_actions']);
$show_bio = !empty($args['show_bio']);
$show_time = !array_key_exists('show_time', $args) || !empty($args['show_time']); $show_time = !array_key_exists('show_time', $args) || !empty($args['show_time']);
$meta_html = (string) ($args['meta_html'] ?? ''); $meta_html = (string) ($args['meta_html'] ?? '');
$meta_items = is_array($args['meta_items'] ?? null) ? array_values(array_filter($args['meta_items'], static function ($meta_item) {
if (is_array($meta_item)) {
return !empty($meta_item['text']);
}
return is_string($meta_item) && $meta_item !== '';
})) : [];
$author_id = (int) get_the_author_meta('ID'); $author_id = (int) get_the_author_meta('ID');
$author_name = get_the_author(); $author_name = get_the_author();
$author_url = function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($author_id) : get_author_posts_url($author_id); $author_url = function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($author_id) : get_author_posts_url($author_id);
$modified_ts = (int) get_the_modified_time('U'); $modified_ts = (int) get_the_modified_time('U');
$published_ts = (int) get_the_time('U'); $published_ts = (int) get_the_time('U');
$now = (int) current_time('timestamp');
$use_modified = $modified_ts > $published_ts; $use_modified = $modified_ts > $published_ts;
$rel_base = $use_modified ? $modified_ts : $published_ts; $rel_base = $use_modified ? $modified_ts : $published_ts;
$rel_label = $use_modified ? __('更新', 'aksrt') : __('发布', 'aksrt'); $rel_label = $use_modified ? __('更新', 'aksrt') : __('发布', 'aksrt');
$abs_fmt = $use_modified $abs_fmt = $use_modified
? sprintf(__('%s更新', 'aksrt'), get_the_modified_time('Y年m月d日 H:i')) ? sprintf(__('%s更新', 'aksrt'), get_the_modified_time('Y年m月d日 H:i'))
: sprintf(__('%s发布', 'aksrt'), get_the_time('Y年m月d日 H:i')); : sprintf(__('%s发布', 'aksrt'), get_the_time('Y年m月d日 H:i'));
$time_text = human_time_diff($rel_base, $now) . $rel_label; $time_text = human_time_diff($rel_base, (int) current_time('timestamp')) . $rel_label;
$description = function_exists('aksrt_get_user_description')
$classes = trim('article-avatar ' . $extra_class); ? aksrt_get_user_description($author_id)
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink()); : trim((string) get_the_author_meta('description'));
$is_self = is_user_logged_in() && get_current_user_id() === $author_id; $name_html = aksrt_get_user_name([
'id' => $author_id,
// Identity: aksrt_get_user_name is the canonical renderer (legacy order). 'class' => 'name flex ac flex1',
$name_html = ''; 'name_class' => '',
if (function_exists('aksrt_get_user_name')) { 'vip' => true,
$name_html = aksrt_get_user_name([ 'medal' => true,
'id' => $author_id, 'auth' => true,
'class' => 'name flex ac flex1', 'level' => true,
'name_class' => '', 'follow' => false,
'vip' => true, ]);
'medal' => true, $follow_html = aksrt_get_user_follow('px12-sm ml10 follow but c-red', $author_id);
'auth' => true, $reward_button = get_current_user_id() !== $author_id && function_exists('aksrt_get_rewards_button')
'level' => true, ? aksrt_get_rewards_button($author_id, 'ml6 but c-yellow px12-sm', get_the_ID())
'follow' => false, : '';
]);
}
?> ?>
<div class="<?php echo esc_attr($classes); ?>"> <div class="article-avatar">
<div class="user-info flex ac article-avatar"> <div class="user-info flex ac article-avatar">
<a href="<?php echo esc_url($author_url); ?>"> <a href="<?php echo esc_url($author_url); ?>">
<span class="avatar-img"> <span class="avatar-img">
<?php if (function_exists('aksrt_get_avatar_html')) : ?> <?php if (function_exists('aksrt_get_avatar_html')) : ?>
<?php echo aksrt_get_avatar_html($author_id, 42, ['class' => 'avatar avatar-id-' . $author_id]); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <?php echo aksrt_get_avatar_html($author_id, 42, ['class' => 'avatar avatar-id-' . $author_id]); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php else : ?> <?php else : ?>
<?php echo get_avatar($author_id, 42, '', esc_attr($author_name), ['class' => 'avatar avatar-id-' . $author_id]); ?> <?php echo get_avatar($author_id, 42, '', esc_attr($author_name), ['class' => 'avatar avatar-id-' . $author_id]); ?>
<?php endif; ?> <?php endif; ?>
</span> </span>
</a> </a>
<div class="user-right flex flex1 ac jsb ml10"> <div class="user-right flex flex1 ac jsb ml10">
<div class="flex1"> <div class="flex1">
<?php if ($name_html !== '') : ?> <?php echo $name_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php echo $name_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php else : ?>
<span class="name flex ac flex1">
<a class="display-name text-ellipsis" href="<?php echo esc_url($author_url); ?>"><?php echo esc_html($author_name); ?></a>
</span>
<?php endif; ?>
<div class="px12-sm muted-2-color text-ellipsis"> <div class="px12-sm muted-2-color text-ellipsis">
<?php if ($show_time) : ?> <?php if ($show_time) : ?>
<span class="icon-circle" title="<?php echo esc_attr($abs_fmt); ?>" data-toggle="tooltip"><?php echo esc_html($time_text); ?></span> <span class="icon-circle" title="<?php echo esc_attr($abs_fmt); ?>" data-toggle="tooltip"><?php echo esc_html($time_text); ?></span>
<?php elseif ($description !== '') : ?>
<span class="icon-circle"><?php echo esc_html($description); ?></span>
<?php endif; ?> <?php endif; ?>
<?php <?php
// Article detail IP 归属地 (extension display: post).
$post_city = function_exists('aksrt_get_post_author_city_badge_html') $post_city = function_exists('aksrt_get_post_author_city_badge_html')
? aksrt_get_post_author_city_badge_html($author_id, 'badg badg-sm') ? aksrt_get_post_author_city_badge_html($author_id, 'badg badg-sm')
: ''; : '';
@@ -95,68 +74,20 @@ if (function_exists('aksrt_get_user_name')) {
echo $post_city; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $post_city; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} }
?> ?>
<?php if ($show_bio) : ?>
<?php $bio = function_exists('aksrt_get_user_description') ? aksrt_get_user_description($author_id) : trim((string) get_the_author_meta('description')); ?>
<?php if ($bio !== '') : ?>
<span class="icon-circle"><?php echo esc_html($bio); ?></span>
<?php endif; ?>
<?php endif; ?>
</div> </div>
</div> </div>
<?php if ($show_actions) : ?> <div class="flex0 user-action">
<div class="flex0 user-action"> <?php echo $follow_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php if (!$is_self) : ?> <?php if ($reward_button !== '') : ?>
<?php if (is_user_logged_in()) : ?> <?php echo $reward_button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php <?php aksrt_render_rewards_modal_for_user($author_id, get_the_ID()); ?>
// 服务端直接输出真实关注状态(legacy parity: zib_get_user_follow 恒渲染当前态)。 <?php endif; ?>
$is_following = class_exists('\AKSRT\User\Follow') && \AKSRT\User\Follow::get_instance()->is_following(get_current_user_id(), $author_id); </div>
$follow_label = $is_following ? __('已关注', 'aksrt') : __('关注', 'aksrt');
$follow_title = $is_following ? __('点击取消关注', 'aksrt') : __('关注该用户', 'aksrt');
?>
<button type="button" class="px12-sm ml10 follow c-red<?php echo $is_following ? ' is-following' : ''; ?>" data-aksrt-follow="<?php echo (int) $author_id; ?>" title="<?php echo esc_attr($follow_title); ?>">
<i class="fa fas fa-heart em09" aria-hidden="true"></i> <span><?php echo esc_html($follow_label); ?></span>
</button>
<?php
$reward_button = function_exists('aksrt_get_rewards_button')
? aksrt_get_rewards_button($author_id, 'ml6 but c-yellow px12-sm', get_the_ID())
: '';
if ($reward_button !== '') {
echo $reward_button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
aksrt_render_rewards_modal_for_user($author_id, get_the_ID());
}
?>
<?php else : ?>
<a href="<?php echo esc_url($login_url); ?>" class="px12-sm ml10 follow c-red">
<i class="fa fas fa-heart em09" aria-hidden="true"></i> <?php esc_html_e('关注', 'aksrt'); ?>
</a>
<?php endif; ?>
<?php endif; ?>
</div>
<?php endif; ?>
</div> </div>
</div> </div>
<?php if ($show_actions) : ?> <div class="single-meta-row">
<div class="single-meta-row"> <i class="line-form-line" aria-hidden="true"></i>
<i class="line-form-line" aria-hidden="true"></i> <?php echo $meta_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php if ($meta_html !== '') : ?> </div>
<?php echo $meta_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php elseif (!empty($meta_items)) : ?>
<div class="flex ac single-metabox">
<div class="post-metas">
<?php foreach ($meta_items as $meta_item) : ?>
<?php
$meta_text = is_array($meta_item) ? (string) ($meta_item['text'] ?? '') : (string) $meta_item;
$meta_icon = is_array($meta_item) ? (string) ($meta_item['icon'] ?? '') : '';
if ($meta_text === '') {
continue;
}
?>
<span class="item meta-view"><?php if ($meta_icon !== '') : ?><i class="<?php echo esc_attr($meta_icon); ?>" aria-hidden="true"></i> <?php endif; ?><?php echo esc_html($meta_text); ?></span>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div> </div>
+2 -17
View File
@@ -156,23 +156,8 @@ $unread_count = $is_own ? aksrt_get_user_unread_notification_count($user_id) : 0
</a> </a>
<?php endif; ?> <?php endif; ?>
<?php else : ?> <?php else : ?>
<?php if ($show_follow) : ?> <?php if ($show_follow) : ?>
<?php if (is_user_logged_in()) : ?> <?php echo aksrt_get_user_follow('btn-outline btn-sm aksrt-author-hero__follow-btn', (int) $user_id, null, null, __('登录后关注', 'aksrt')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php
$hero_following = class_exists('\AKSRT\User\Follow')
? \AKSRT\User\Follow::get_instance()->is_following(get_current_user_id(), (int) $user_id)
: false;
?>
<button type="button" class="btn-outline btn-sm aksrt-author-hero__follow-btn<?php echo $hero_following ? ' is-following' : ''; ?>" data-aksrt-follow="<?php echo (int) $user_id; ?>" title="<?php echo $hero_following ? esc_attr__('点击取消关注', 'aksrt') : esc_attr__('关注该用户', 'aksrt'); ?>">
<i class="fa fas fa-heart" aria-hidden="true"></i>
<span><?php echo esc_html($hero_following ? __('已关注', 'aksrt') : __('关注', 'aksrt')); ?></span>
</button>
<?php else : ?>
<a href="<?php echo esc_url(aksrt_get_login_url($home_url)); ?>" class="btn-outline btn-sm aksrt-author-hero__follow-btn">
<i class="fa fas fa-heart" aria-hidden="true"></i>
<span><?php esc_html_e('登录后关注', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<?php endif; ?> <?php endif; ?>
<?php endif; ?> <?php endif; ?>
@@ -259,6 +259,12 @@ test('after-box author card mirrors legacy user-card structure', () => {
const userCard = read('inc/helpers/aksrt-user-card.php'); const userCard = read('inc/helpers/aksrt-user-card.php');
const css = read('assets/css/frontend/single-post/related-toc.css'); const css = read('assets/css/frontend/single-post/related-toc.css');
const authorActions = read('assets/css/frontend/single-post/author-actions.css'); const authorActions = read('assets/css/frontend/single-post/author-actions.css');
const base = read('assets/css/frontend/base.css');
const follow = read('assets/js/follow.js');
const authorBar = read('templates/parts/single-author-bar.php');
const single = read('inc/helpers/aksrt-single.php');
const settings = read('src/Settings/PostDisplay.php');
const frontendTags = read('inc/helpers/aksrt-frontend-tags.php');
assert.match(render, /avatar-img avatar-lg/); assert.match(render, /avatar-img avatar-lg/);
assert.match(render, /'vip'\s+=>\s+false/); assert.match(render, /'vip'\s+=>\s+false/);
@@ -280,6 +286,21 @@ test('after-box author card mirrors legacy user-card structure', () => {
assert.match(css, /^\.zib-widget \{/m); assert.match(css, /^\.zib-widget \{/m);
assert.doesNotMatch(css, /relates-thumb \.graphic\.style-3 \.graphic-img/); assert.doesNotMatch(css, /relates-thumb \.graphic\.style-3 \.graphic-img/);
assert.doesNotMatch(authorActions, /\.user-card-author|\.user-card \.author|user-card-posts/); assert.doesNotMatch(authorActions, /\.user-card-author|\.user-card \.author|user-card-posts/);
assert.match(identity, /function aksrt_get_user_follow\(/);
assert.match(identity, /data-aksrt-follow-label/);
assert.match(identity, /aksrt_get_user_follow\('focus-color ml10 follow flex0', \$user_id\)/);
assert.match(authorBar, /aksrt_get_user_follow\('px12-sm ml10 follow but c-red', \$author_id\)/);
assert.doesNotMatch(authorBar, /Follow::get_instance|is_following|show_actions|show_bio|extra_class|meta_items/);
assert.doesNotMatch(single, /aksrt_single_render_author_bar/);
assert.match(base, /\.user-card\.author \.user-name > name\s*\{[^}]*overflow:\s*visible;/s);
assert.match(base, /\.user-card\.author \.user-name > name > \.follow\s*\{[^}]*flex-shrink:\s*0;/s);
assert.match(follow, /querySelectorAll\('\[data-aksrt-follow="' \+ userId/);
assert.match(follow, /matchingButtons\.forEach/);
assert.match(follow, /\[data-aksrt-follow-label\]/);
assert.doesNotMatch(follow, /childNodes|textNode|Fallback when markup/);
assert.doesNotMatch(settings, /'authordesc_s'\s*=>/);
assert.doesNotMatch(frontendTags, /array_key_exists\('authordesc_s'/);
assert.doesNotMatch(authorActions, /article-author-bar__|author-box__/);
}); });
test('AJAX pagination can recover, caps auto loading and rehydrates appended media', () => { test('AJAX pagination can recover, caps auto loading and rehydrates appended media', () => {