forked from newthuhole/hole_thu_frontend
improvements
- add sidebar-stack - add control-btn-label - better locating dz - enable reply_rev when 1 reply - replace latest_post_id when page=1
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
<link rel="icon" href="%PUBLIC_URL%/static/favicon/256.png">
|
<link rel="icon" href="%PUBLIC_URL%/static/favicon/256.png">
|
||||||
<meta name="format-detection" content="telephone=no">
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
|
||||||
<link rel="stylesheet" href="%PUBLIC_URL%/static/fonts_6/icomoon.css" />
|
<link rel="stylesheet" href="%PUBLIC_URL%/static/fonts_7/icomoon.css" />
|
||||||
|
|
||||||
<meta name="mobile-web-app-capable" content="yes">
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<link rel="shortcut icon" href="%PUBLIC_URL%/static/favicon/256.png">
|
<link rel="shortcut icon" href="%PUBLIC_URL%/static/favicon/256.png">
|
||||||
|
|||||||
101
public/static/fonts_7/icomoon.css
Normal file
101
public/static/fonts_7/icomoon.css
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'icomoon';
|
||||||
|
src:
|
||||||
|
url('icomoon.ttf?8qh3rt') format('truetype'),
|
||||||
|
url('icomoon.woff?8qh3rt') format('woff'),
|
||||||
|
url('icomoon.svg?8qh3rt#icomoon') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
/* use !important to prevent issues with browser extensions that change fonts */
|
||||||
|
/*noinspection CssNoGenericFontName*/
|
||||||
|
font-family: 'icomoon' !important;
|
||||||
|
speak: none;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
line-height: 1;
|
||||||
|
vertical-align: -.0625em;
|
||||||
|
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-send:before {
|
||||||
|
content: "\e900";
|
||||||
|
}
|
||||||
|
.icon-textfile:before {
|
||||||
|
content: "\e926";
|
||||||
|
}
|
||||||
|
.icon-history:before {
|
||||||
|
content: "\e94d";
|
||||||
|
}
|
||||||
|
.icon-reply:before {
|
||||||
|
content: "\e96b";
|
||||||
|
}
|
||||||
|
.icon-quote:before {
|
||||||
|
content: "\e977";
|
||||||
|
}
|
||||||
|
.icon-loading:before {
|
||||||
|
content: "\e979";
|
||||||
|
}
|
||||||
|
.icon-login:before {
|
||||||
|
content: "\e98d";
|
||||||
|
}
|
||||||
|
.icon-settings:before {
|
||||||
|
content: "\e994";
|
||||||
|
}
|
||||||
|
.icon-stats:before {
|
||||||
|
content: "\e99b";
|
||||||
|
}
|
||||||
|
.icon-locate:before {
|
||||||
|
content: "\e9b3";
|
||||||
|
}
|
||||||
|
.icon-upload:before {
|
||||||
|
content: "\e9c3";
|
||||||
|
}
|
||||||
|
.icon-flag:before {
|
||||||
|
content: "\e9cc";
|
||||||
|
}
|
||||||
|
.icon-attention:before {
|
||||||
|
content: "\e9d3";
|
||||||
|
}
|
||||||
|
.icon-star:before {
|
||||||
|
content: "\e9d7";
|
||||||
|
}
|
||||||
|
.icon-star-ok:before {
|
||||||
|
content: "\e9d9";
|
||||||
|
}
|
||||||
|
.icon-plus:before {
|
||||||
|
content: "\ea0a";
|
||||||
|
}
|
||||||
|
.icon-about:before {
|
||||||
|
content: "\ea0c";
|
||||||
|
}
|
||||||
|
.icon-close:before {
|
||||||
|
content: "\ea0d";
|
||||||
|
}
|
||||||
|
.icon-logout:before {
|
||||||
|
content: "\ea14";
|
||||||
|
}
|
||||||
|
.icon-refresh:before {
|
||||||
|
content: "\ea2e";
|
||||||
|
}
|
||||||
|
.icon-forward:before {
|
||||||
|
content: "\ea42";
|
||||||
|
}
|
||||||
|
.icon-back:before {
|
||||||
|
content: "\ea44";
|
||||||
|
}
|
||||||
|
.icon-order-rev:before {
|
||||||
|
content: "\ea46";
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
.icon-github:before {
|
||||||
|
content: "\eab0";
|
||||||
|
}
|
||||||
34
public/static/fonts_7/icomoon.svg
Normal file
34
public/static/fonts_7/icomoon.svg
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<metadata>Generated by IcoMoon</metadata>
|
||||||
|
<defs>
|
||||||
|
<font id="icomoon" horiz-adv-x="1024">
|
||||||
|
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||||
|
<missing-glyph horiz-adv-x="1024" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="512" d="" />
|
||||||
|
<glyph unicode="" glyph-name="send" horiz-adv-x="1025" d="M1008 944.571c12-8.571 17.714-22.286 15.429-36.571l-146.286-877.714c-1.714-10.857-8.571-20-18.286-25.714-5.143-2.857-11.429-4.571-17.714-4.571-4.571 0-9.143 1.143-13.714 2.857l-258.857 105.714-138.286-168.571c-6.857-8.571-17.143-13.143-28-13.143-4 0-8.571 0.571-12.571 2.286-14.286 5.143-24 18.857-24 34.286v199.429l493.714 605.143-610.857-528.571-225.714 92.571c-13.143 5.143-21.714 17.143-22.857 31.429-0.571 13.714 6.286 26.857 18.286 33.714l950.857 548.571c5.714 3.429 12 5.143 18.286 5.143 7.429 0 14.857-2.286 20.571-6.286z" />
|
||||||
|
<glyph unicode="" glyph-name="textfile" d="M917.806 730.924c-22.212 30.292-53.174 65.7-87.178 99.704s-69.412 64.964-99.704 87.178c-51.574 37.82-76.592 42.194-90.924 42.194h-496c-44.112 0-80-35.888-80-80v-864c0-44.112 35.888-80 80-80h736c44.112 0 80 35.888 80 80v624c0 14.332-4.372 39.35-42.194 90.924zM785.374 785.374c30.7-30.7 54.8-58.398 72.58-81.374h-153.954v153.946c22.984-17.78 50.678-41.878 81.374-72.572zM896 16c0-8.672-7.328-16-16-16h-736c-8.672 0-16 7.328-16 16v864c0 8.672 7.328 16 16 16 0 0 495.956 0.002 496 0v-224c0-17.672 14.326-32 32-32h224v-624zM736 128h-448c-17.672 0-32 14.326-32 32s14.328 32 32 32h448c17.674 0 32-14.326 32-32s-14.326-32-32-32zM736 256h-448c-17.672 0-32 14.326-32 32s14.328 32 32 32h448c17.674 0 32-14.326 32-32s-14.326-32-32-32zM736 384h-448c-17.672 0-32 14.326-32 32s14.328 32 32 32h448c17.674 0 32-14.326 32-32s-14.326-32-32-32z" />
|
||||||
|
<glyph unicode="" glyph-name="history" horiz-adv-x="1088" d="M640 896c247.424 0 448-200.576 448-448s-200.576-448-448-448v96c94.024 0 182.418 36.614 248.902 103.098s103.098 154.878 103.098 248.902c0 94.022-36.614 182.418-103.098 248.902s-154.878 103.098-248.902 103.098c-94.022 0-182.418-36.614-248.902-103.098-51.14-51.138-84.582-115.246-97.306-184.902h186.208l-224-256-224 256h164.57c31.060 217.102 217.738 384 443.43 384zM832 512v-128h-256v320h128v-192z" />
|
||||||
|
<glyph unicode="" glyph-name="reply" d="M512 896c282.77 0 512-186.25 512-416 0-229.752-229.23-416-512-416-27.156 0-53.81 1.734-79.824 5.044-109.978-109.978-241.25-129.7-368.176-132.596v26.916c68.536 33.578 128 94.74 128 164.636 0 9.754-0.758 19.33-2.164 28.696-115.796 76.264-189.836 192.754-189.836 323.304 0 229.75 229.23 416 512 416z" />
|
||||||
|
<glyph unicode="" glyph-name="quote" d="M225 512c123.712 0 224-100.29 224-224 0-123.712-100.288-224-224-224s-224 100.288-224 224l-1 32c0 247.424 200.576 448 448 448v-128c-85.474 0-165.834-33.286-226.274-93.726-11.634-11.636-22.252-24.016-31.83-37.020 11.438 1.8 23.16 2.746 35.104 2.746zM801 512c123.71 0 224-100.29 224-224 0-123.712-100.29-224-224-224s-224 100.288-224 224l-1 32c0 247.424 200.576 448 448 448v-128c-85.474 0-165.834-33.286-226.274-93.726-11.636-11.636-22.254-24.016-31.832-37.020 11.44 1.8 23.16 2.746 35.106 2.746z" />
|
||||||
|
<glyph unicode="" glyph-name="loading" d="M728.992 448c137.754 87.334 231.008 255.208 231.008 448 0 21.676-1.192 43.034-3.478 64h-889.042c-2.29-20.968-3.48-42.326-3.48-64 0-192.792 93.254-360.666 231.006-448-137.752-87.334-231.006-255.208-231.006-448 0-21.676 1.19-43.034 3.478-64h889.042c2.288 20.966 3.478 42.324 3.478 64 0.002 192.792-93.252 360.666-231.006 448zM160 0c0 186.912 80.162 345.414 224 397.708v100.586c-143.838 52.29-224 210.792-224 397.706v0h704c0-186.914-80.162-345.416-224-397.706v-100.586c143.838-52.294 224-210.796 224-397.708h-704zM619.626 290.406c-71.654 40.644-75.608 93.368-75.626 125.366v64.228c0 31.994 3.804 84.914 75.744 125.664 38.504 22.364 71.808 56.348 97.048 98.336h-409.582c25.266-42.032 58.612-76.042 97.166-98.406 71.654-40.644 75.606-93.366 75.626-125.366v-64.228c0-31.992-3.804-84.914-75.744-125.664-72.622-42.18-126.738-125.684-143.090-226.336h501.67c-16.364 100.708-70.53 184.248-143.212 226.406z" />
|
||||||
|
<glyph unicode="" glyph-name="login" d="M704 960c-176.73 0-320-143.268-320-320 0-20.026 1.858-39.616 5.376-58.624l-389.376-389.376v-192c0-35.346 28.654-64 64-64h64v64h128v128h128v128h128l83.042 83.042c34.010-12.316 70.696-19.042 108.958-19.042 176.73 0 320 143.268 320 320s-143.27 320-320 320zM799.874 639.874c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96z" />
|
||||||
|
<glyph unicode="" glyph-name="settings" d="M933.79 349.75c-53.726 93.054-21.416 212.304 72.152 266.488l-100.626 174.292c-28.75-16.854-62.176-26.518-97.846-26.518-107.536 0-194.708 87.746-194.708 195.99h-201.258c0.266-33.41-8.074-67.282-25.958-98.252-53.724-93.056-173.156-124.702-266.862-70.758l-100.624-174.292c28.97-16.472 54.050-40.588 71.886-71.478 53.638-92.908 21.512-211.92-71.708-266.224l100.626-174.292c28.65 16.696 61.916 26.254 97.4 26.254 107.196 0 194.144-87.192 194.7-194.958h201.254c-0.086 33.074 8.272 66.57 25.966 97.218 53.636 92.906 172.776 124.594 266.414 71.012l100.626 174.29c-28.78 16.466-53.692 40.498-71.434 71.228zM512 240.668c-114.508 0-207.336 92.824-207.336 207.334 0 114.508 92.826 207.334 207.336 207.334 114.508 0 207.332-92.826 207.332-207.334-0.002-114.51-92.824-207.334-207.332-207.334z" />
|
||||||
|
<glyph unicode="" glyph-name="stats" d="M128 64h896v-128h-1024v1024h128zM288 128c-53.020 0-96 42.98-96 96s42.98 96 96 96c2.828 0 5.622-0.148 8.388-0.386l103.192 171.986c-9.84 15.070-15.58 33.062-15.58 52.402 0 53.020 42.98 96 96 96s96-42.98 96-96c0-19.342-5.74-37.332-15.58-52.402l103.192-171.986c2.766 0.238 5.56 0.386 8.388 0.386 2.136 0 4.248-0.094 6.35-0.23l170.356 298.122c-10.536 15.408-16.706 34.036-16.706 54.11 0 53.020 42.98 96 96 96s96-42.98 96-96c0-53.020-42.98-96-96-96-2.14 0-4.248 0.094-6.35 0.232l-170.356-298.124c10.536-15.406 16.706-34.036 16.706-54.11 0-53.020-42.98-96-96-96s-96 42.98-96 96c0 19.34 5.74 37.332 15.578 52.402l-103.19 171.984c-2.766-0.238-5.56-0.386-8.388-0.386s-5.622 0.146-8.388 0.386l-103.192-171.986c9.84-15.068 15.58-33.060 15.58-52.4 0-53.020-42.98-96-96-96z" />
|
||||||
|
<glyph unicode="" glyph-name="locate" d="M1024 512h-100.924c-27.64 178.24-168.836 319.436-347.076 347.076v100.924h-128v-100.924c-178.24-27.64-319.436-168.836-347.076-347.076h-100.924v-128h100.924c27.64-178.24 168.836-319.436 347.076-347.076v-100.924h128v100.924c178.24 27.64 319.436 168.836 347.076 347.076h100.924v128zM792.822 512h-99.762c-19.284 54.55-62.51 97.778-117.060 117.060v99.762c107.514-24.49 192.332-109.31 216.822-216.822zM512 384c-35.346 0-64 28.654-64 64s28.654 64 64 64c35.346 0 64-28.654 64-64s-28.654-64-64-64zM448 728.822v-99.762c-54.55-19.282-97.778-62.51-117.060-117.060h-99.762c24.49 107.512 109.31 192.332 216.822 216.822zM231.178 384h99.762c19.282-54.55 62.51-97.778 117.060-117.060v-99.762c-107.512 24.49-192.332 109.308-216.822 216.822zM576 167.178v99.762c54.55 19.284 97.778 62.51 117.060 117.060h99.762c-24.49-107.514-109.308-192.332-216.822-216.822z" />
|
||||||
|
<glyph unicode="" glyph-name="upload" d="M892.268 573.51c2.444 11.11 3.732 22.648 3.732 34.49 0 88.366-71.634 160-160 160-14.222 0-28.014-1.868-41.132-5.352-24.798 77.352-97.29 133.352-182.868 133.352-87.348 0-161.054-58.336-184.326-138.17-22.742 6.622-46.792 10.17-71.674 10.17-141.384 0-256-114.616-256-256 0-141.388 114.616-256 256-256h128v-192h256v192h224c88.366 0 160 71.632 160 160 0 78.72-56.854 144.162-131.732 157.51zM576 320v-192h-128v192h-160l224 224 224-224h-160z" />
|
||||||
|
<glyph unicode="" glyph-name="flag" d="M0 960h128v-1024h-128v1024zM832 316.998c82.624 0 154.57 19.984 192 49.5v512c-37.43-29.518-109.376-49.502-192-49.502s-154.57 19.984-192 49.502v-512c37.43-29.516 109.376-49.5 192-49.5zM608 927.472c-46.906 19.94-115.52 32.528-192 32.528-96.396 0-180.334-19.984-224-49.502v-512c43.666 29.518 127.604 49.502 224 49.502 76.48 0 145.094-12.588 192-32.528v512z" />
|
||||||
|
<glyph unicode="" glyph-name="attention" d="M256 832v-896l320 320 320-320v896zM768 960h-640v-896l64 64v768h576z" />
|
||||||
|
<glyph unicode="" glyph-name="star" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-223.462-117.48 42.676 248.83-180.786 176.222 249.84 36.304 111.732 226.396 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" />
|
||||||
|
<glyph unicode="" glyph-name="star-ok" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538z" />
|
||||||
|
<glyph unicode="" glyph-name="plus" d="M992 576h-352v352c0 17.672-14.328 32-32 32h-192c-17.672 0-32-14.328-32-32v-352h-352c-17.672 0-32-14.328-32-32v-192c0-17.672 14.328-32 32-32h352v-352c0-17.672 14.328-32 32-32h192c17.672 0 32 14.328 32 32v352h352c17.672 0 32 14.328 32 32v192c0 17.672-14.328 32-32 32z" />
|
||||||
|
<glyph unicode="" glyph-name="about" d="M448 656c0 26.4 21.6 48 48 48h32c26.4 0 48-21.6 48-48v-32c0-26.4-21.6-48-48-48h-32c-26.4 0-48 21.6-48 48v32zM640 192h-256v64h64v192h-64v64h192v-256h64zM512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 32c-229.75 0-416 186.25-416 416s186.25 416 416 416 416-186.25 416-416-186.25-416-416-416z" />
|
||||||
|
<glyph unicode="" glyph-name="close" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 32c-229.75 0-416 186.25-416 416s186.25 416 416 416 416-186.25 416-416-186.25-416-416-416zM672 704l-160-160-160 160-96-96 160-160-160-160 96-96 160 160 160-160 96 96-160 160 160 160z" />
|
||||||
|
<glyph unicode="" glyph-name="logout" d="M768 320v128h-320v128h320v128l192-192zM704 384v-256h-320v-192l-384 192v832h704v-320h-64v256h-512l256-128v-576h256v192z" />
|
||||||
|
<glyph unicode="" glyph-name="refresh" d="M889.68 793.68c-93.608 102.216-228.154 166.32-377.68 166.32-282.77 0-512-229.23-512-512h96c0 229.75 186.25 416 416 416 123.020 0 233.542-53.418 309.696-138.306l-149.696-149.694h352v352l-134.32-134.32zM928 448c0-229.75-186.25-416-416-416-123.020 0-233.542 53.418-309.694 138.306l149.694 149.694h-352v-352l134.32 134.32c93.608-102.216 228.154-166.32 377.68-166.32 282.77 0 512 229.23 512 512h-96z" />
|
||||||
|
<glyph unicode="" glyph-name="forward" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 32c-229.75 0-416 186.25-416 416s186.25 416 416 416 416-186.25 416-416-186.25-416-416-416zM354.744 253.256l90.512-90.512 285.254 285.256-285.256 285.254-90.508-90.508 194.744-194.746z" />
|
||||||
|
<glyph unicode="" glyph-name="back" d="M512-64c282.77 0 512 229.23 512 512s-229.23 512-512 512-512-229.23-512-512 229.23-512 512-512zM512 864c229.75 0 416-186.25 416-416s-186.25-416-416-416-416 186.25-416 416 186.25 416 416 416zM669.256 642.744l-90.512 90.512-285.254-285.256 285.256-285.254 90.508 90.508-194.744 194.746z" />
|
||||||
|
<glyph unicode="" glyph-name="order-rev" d="M704 448v-384h64v384h160l-192 192-192-192zM64 768h96v-64h-96v64zM192 768h96v-64h-96v64zM320 768h64v-96h-64v96zM64 544h64v-96h-64v96zM160 512h96v-64h-96v64zM288 512h96v-64h-96v64zM64 672h64v-96h-64v96zM320 640h64v-96h-64v96zM320 256v-192h-192v192h192zM384 320h-320v-320h320v320z" />
|
||||||
|
<glyph unicode="" glyph-name="github" d="M512.008 947.358c-282.738 0-512.008-229.218-512.008-511.998 0-226.214 146.704-418.132 350.136-485.836 25.586-4.738 34.992 11.11 34.992 24.632 0 12.204-0.48 52.542-0.696 95.324-142.448-30.976-172.504 60.41-172.504 60.41-23.282 59.176-56.848 74.916-56.848 74.916-46.452 31.778 3.51 31.124 3.51 31.124 51.4-3.61 78.476-52.766 78.476-52.766 45.672-78.27 119.776-55.64 149.004-42.558 4.588 33.086 17.852 55.68 32.506 68.464-113.73 12.942-233.276 56.85-233.276 253.032 0 55.898 20.004 101.574 52.76 137.428-5.316 12.9-22.854 64.972 4.952 135.5 0 0 43.006 13.752 140.84-52.49 40.836 11.348 84.636 17.036 128.154 17.234 43.502-0.198 87.336-5.886 128.256-17.234 97.734 66.244 140.656 52.49 140.656 52.49 27.872-70.528 10.35-122.6 5.036-135.5 32.82-35.856 52.694-81.532 52.694-137.428 0-196.654-119.778-239.95-233.79-252.624 18.364-15.89 34.724-47.046 34.724-94.812 0-68.508-0.596-123.644-0.596-140.508 0-13.628 9.222-29.594 35.172-24.566 203.322 67.776 349.842 259.626 349.842 485.768 0 282.78-229.234 511.998-511.992 511.998z" />
|
||||||
|
</font></defs></svg>
|
||||||
|
After Width: | Height: | Size: 12 KiB |
BIN
public/static/fonts_7/icomoon.ttf
Normal file
BIN
public/static/fonts_7/icomoon.ttf
Normal file
Binary file not shown.
BIN
public/static/fonts_7/icomoon.woff
Normal file
BIN
public/static/fonts_7/icomoon.woff
Normal file
Binary file not shown.
48
src/App.js
48
src/App.js
@@ -17,8 +17,7 @@ class App extends Component {
|
|||||||
load_config();
|
load_config();
|
||||||
listen_darkmode({default: undefined, light: false, dark: true}[window.config.color_scheme]);
|
listen_darkmode({default: undefined, light: false, dark: true}[window.config.color_scheme]);
|
||||||
this.state={
|
this.state={
|
||||||
sidebar_title: null,
|
sidebar_stack: [[null,null]], // list of [status, content]
|
||||||
sidebar_content: null, // determine status of sidebar
|
|
||||||
mode: 'list', // list, single, search, attention
|
mode: 'list', // list, single, search, attention
|
||||||
search_text: null,
|
search_text: null,
|
||||||
flow_render_key: +new Date(),
|
flow_render_key: +new Date(),
|
||||||
@@ -41,20 +40,39 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
on_pressure() {
|
on_pressure() {
|
||||||
if(this.state.sidebar_title!==null)
|
if(this.state.sidebar_stack.length>1)
|
||||||
this.setState((prevState)=>({
|
this.show_sidebar(null,null,'clear');
|
||||||
sidebar_title: null,
|
|
||||||
sidebar_content: prevState.sidebar_content,
|
|
||||||
}));
|
|
||||||
else
|
else
|
||||||
this.set_mode('list',null);
|
this.set_mode('list',null);
|
||||||
}
|
}
|
||||||
|
|
||||||
show_sidebar(title,content) {
|
show_sidebar(title,content,mode='push') {
|
||||||
this.setState({
|
if(mode==='push') {
|
||||||
sidebar_title: title,
|
this.setState((prevState)=>({
|
||||||
sidebar_content: content,
|
sidebar_stack: prevState.sidebar_stack.concat([[title,content]]),
|
||||||
});
|
}));
|
||||||
|
} else if(mode==='pop') {
|
||||||
|
this.setState((prevState)=>{
|
||||||
|
let ns=prevState.sidebar_stack.slice();
|
||||||
|
ns.pop();
|
||||||
|
return {
|
||||||
|
sidebar_stack: ns,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else if(mode==='replace') {
|
||||||
|
this.setState((prevState)=>{
|
||||||
|
let ns=prevState.sidebar_stack.slice();
|
||||||
|
ns.pop();
|
||||||
|
return {
|
||||||
|
sidebar_stack: ns.concat([[title,content]]),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else if(mode==='clear') {
|
||||||
|
this.setState({
|
||||||
|
sidebar_stack: [[null,null]],
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
throw new Error('bad show_sidebar mode');
|
||||||
}
|
}
|
||||||
|
|
||||||
set_mode(mode,search_text) {
|
set_mode(mode,search_text) {
|
||||||
@@ -102,11 +120,7 @@ class App extends Component {
|
|||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
)}</TokenCtx.Consumer>
|
)}</TokenCtx.Consumer>
|
||||||
<Sidebar do_close={()=>{
|
<Sidebar show_sidebar={this.show_sidebar_bound} stack={this.state.sidebar_stack} />
|
||||||
this.setState({
|
|
||||||
sidebar_title: null,
|
|
||||||
});
|
|
||||||
}} content={this.state.sidebar_content} title={this.state.sidebar_title} />
|
|
||||||
</TokenCtx.Provider>
|
</TokenCtx.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
72
src/Flows.js
72
src/Flows.js
@@ -19,10 +19,12 @@ const QUOTE_BLACKLIST=['23333','233333','66666','666666','10086','10000','100000
|
|||||||
|
|
||||||
window.LATEST_POST_ID=parseInt(localStorage['_LATEST_POST_ID'],10)||0;
|
window.LATEST_POST_ID=parseInt(localStorage['_LATEST_POST_ID'],10)||0;
|
||||||
|
|
||||||
|
const DZ_NAME='洞主';
|
||||||
|
|
||||||
function load_single_meta(show_sidebar,token,parents) {
|
function load_single_meta(show_sidebar,token,parents) {
|
||||||
return (pid)=>{
|
return (pid)=>{
|
||||||
let title_elem=<FlowSidebarTitle pid={pid} parents={parents} show_sidebar={show_sidebar} token={token} />;
|
let color_picker=new ColorPicker();
|
||||||
const color_picker=new ColorPicker();
|
let title_elem='树洞 #'+pid;
|
||||||
show_sidebar(
|
show_sidebar(
|
||||||
title_elem,
|
title_elem,
|
||||||
<div className="box box-tip">
|
<div className="box box-tip">
|
||||||
@@ -46,7 +48,8 @@ function load_single_meta(show_sidebar,token,parents) {
|
|||||||
info={single.data} replies={replies.data} attention={replies.attention}
|
info={single.data} replies={replies.data} attention={replies.attention}
|
||||||
token={token} show_sidebar={show_sidebar} color_picker={color_picker}
|
token={token} show_sidebar={show_sidebar} color_picker={color_picker}
|
||||||
deletion_detect={localStorage['DELETION_DETECT']==='on'} parents={parents}
|
deletion_detect={localStorage['DELETION_DETECT']==='on'} parents={parents}
|
||||||
/>
|
/>,
|
||||||
|
'replace'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.catch((e)=>{
|
.catch((e)=>{
|
||||||
@@ -56,7 +59,8 @@ function load_single_meta(show_sidebar,token,parents) {
|
|||||||
<div className="box box-tip">
|
<div className="box box-tip">
|
||||||
<p><a onClick={()=>load_single_meta(show_sidebar,token,parents)(pid)}>重新加载</a></p>
|
<p><a onClick={()=>load_single_meta(show_sidebar,token,parents)(pid)}>重新加载</a></p>
|
||||||
<p>{''+e}</p>
|
<p>{''+e}</p>
|
||||||
</div>
|
</div>,
|
||||||
|
'replace'
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@@ -142,6 +146,11 @@ class FlowItem extends PureComponent {
|
|||||||
<div className="flow-item-dot" />
|
<div className="flow-item-dot" />
|
||||||
}
|
}
|
||||||
<div className="box-header">
|
<div className="box-header">
|
||||||
|
{!!this.props.do_filter_name &&
|
||||||
|
<span className="reply-header-badge clickable" onClick={()=>{this.props.do_filter_name(DZ_NAME);}}>
|
||||||
|
<span className="icon icon-locate" />
|
||||||
|
</span>
|
||||||
|
}
|
||||||
{!!parseInt(props.info.likenum,10) &&
|
{!!parseInt(props.info.likenum,10) &&
|
||||||
<span className="box-header-badge">
|
<span className="box-header-badge">
|
||||||
{props.info.likenum}
|
{props.info.likenum}
|
||||||
@@ -334,18 +343,20 @@ class FlowSidebar extends PureComponent {
|
|||||||
// key for lazyload elem
|
// key for lazyload elem
|
||||||
let view_mode_key=(this.state.rev ? 'y-' : 'n-')+(this.state.filter_name||'null');
|
let view_mode_key=(this.state.rev ? 'y-' : 'n-')+(this.state.filter_name||'null');
|
||||||
|
|
||||||
let replies_cnt={};
|
let replies_cnt={[DZ_NAME]:1};
|
||||||
replies_to_show.forEach((r)=>{
|
replies_to_show.forEach((r)=>{
|
||||||
if(replies_cnt[r.name]===undefined)
|
if(replies_cnt[r.name]===undefined)
|
||||||
replies_cnt[r.name]=0;
|
replies_cnt[r.name]=0;
|
||||||
replies_cnt[r.name]++;
|
replies_cnt[r.name]++;
|
||||||
});
|
});
|
||||||
|
|
||||||
let main_thread_elem=(
|
// hide main thread when filtered
|
||||||
|
let main_thread_elem=(this.state.filter_name && this.state.filter_name!==DZ_NAME) ? null : (
|
||||||
<ClickHandler callback={(e)=>{this.show_reply_bar('',e);}}>
|
<ClickHandler callback={(e)=>{this.show_reply_bar('',e);}}>
|
||||||
<FlowItem info={this.state.info} attention={this.state.attention} img_clickable={true}
|
<FlowItem info={this.state.info} attention={this.state.attention} img_clickable={true}
|
||||||
color_picker={this.color_picker} show_pid={show_pid} replies={this.state.replies}
|
color_picker={this.color_picker} show_pid={show_pid} replies={this.state.replies}
|
||||||
set_variant={(variant)=>{this.set_variant(null,variant);}}
|
set_variant={(variant)=>{this.set_variant(null,variant);}}
|
||||||
|
do_filter_name={replies_cnt[DZ_NAME]>1 ? this.set_filter_name.bind(this) : null}
|
||||||
/>
|
/>
|
||||||
</ClickHandler>
|
</ClickHandler>
|
||||||
);
|
);
|
||||||
@@ -364,7 +375,7 @@ class FlowSidebar extends PureComponent {
|
|||||||
<a onClick={this.load_replies.bind(this)}>
|
<a onClick={this.load_replies.bind(this)}>
|
||||||
<span className="icon icon-refresh" /><label>刷新</label>
|
<span className="icon icon-refresh" /><label>刷新</label>
|
||||||
</a>
|
</a>
|
||||||
{(this.state.replies.length>1 || this.state.rev) &&
|
{(this.state.replies.length>=1 || this.state.rev) &&
|
||||||
<span>
|
<span>
|
||||||
|
|
||||||
<a onClick={this.toggle_rev.bind(this)}>
|
<a onClick={this.toggle_rev.bind(this)}>
|
||||||
@@ -386,6 +397,15 @@ class FlowSidebar extends PureComponent {
|
|||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
{!!this.state.filter_name &&
|
||||||
|
<div className="box box-tip flow-item filter-name-bar">
|
||||||
|
<p>
|
||||||
|
<span style={{float: 'left'}}><a onClick={()=>{this.set_filter_name(null)}}>还原</a></span>
|
||||||
|
<span className="icon icon-locate" /> 当前只看
|
||||||
|
<ColoredSpan colors={this.color_picker.get(this.state.filter_name)}>{this.state.filter_name}</ColoredSpan>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
{!this.state.rev &&
|
{!this.state.rev &&
|
||||||
main_thread_elem
|
main_thread_elem
|
||||||
}
|
}
|
||||||
@@ -400,15 +420,6 @@ class FlowSidebar extends PureComponent {
|
|||||||
{parseInt(this.state.info.reply)-this.state.replies.length} 条回复被删除
|
{parseInt(this.state.info.reply)-this.state.replies.length} 条回复被删除
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{!!this.state.filter_name &&
|
|
||||||
<div className="box box-tip flow-item filter-name-bar">
|
|
||||||
<p>
|
|
||||||
<span style={{float: 'left'}}><a onClick={()=>{this.set_filter_name(null)}}>还原</a></span>
|
|
||||||
<span className="icon icon-locate" /> 当前只看
|
|
||||||
<ColoredSpan colors={this.color_picker.get(this.state.filter_name)}>{this.state.filter_name}</ColoredSpan>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{replies_to_show.map((reply)=>(
|
{replies_to_show.map((reply)=>(
|
||||||
<LazyLoad key={reply.cid+view_mode_key} offset={1500} height="5em" overflow={true} once={true}>
|
<LazyLoad key={reply.cid+view_mode_key} offset={1500} height="5em" overflow={true} once={true}>
|
||||||
<ClickHandler callback={(e)=>{this.show_reply_bar(reply.name,e);}}>
|
<ClickHandler callback={(e)=>{this.show_reply_bar(reply.name,e);}}>
|
||||||
@@ -433,24 +444,6 @@ class FlowSidebar extends PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function FlowSidebarTitle(props) {
|
|
||||||
let last_pid=props.parents.length ? props.parents[props.parents.length-1] : null;
|
|
||||||
return (
|
|
||||||
<span>
|
|
||||||
树洞
|
|
||||||
{!!last_pid &&
|
|
||||||
<span>
|
|
||||||
<a onClick={()=>load_single_meta(props.show_sidebar,props.token,props.parents.slice(0,-1))(last_pid)}>
|
|
||||||
#{last_pid}
|
|
||||||
</a>
|
|
||||||
→
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
#{props.pid}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
class FlowItemRow extends PureComponent {
|
class FlowItemRow extends PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -499,7 +492,7 @@ class FlowItemRow extends PureComponent {
|
|||||||
|
|
||||||
show_sidebar() {
|
show_sidebar() {
|
||||||
this.props.show_sidebar(
|
this.props.show_sidebar(
|
||||||
<FlowSidebarTitle pid={this.state.info.pid} parents={[]} show_sidebar={this.props.show_sidebar} token={this.props.token} />,
|
'树洞 #'+this.state.info.pid,
|
||||||
<FlowSidebar key={+new Date()}
|
<FlowSidebar key={+new Date()}
|
||||||
info={this.state.info} replies={this.state.replies} attention={this.state.attention} sync_state={this.setState.bind(this)}
|
info={this.state.info} replies={this.state.replies} attention={this.state.attention} sync_state={this.setState.bind(this)}
|
||||||
token={this.props.token} show_sidebar={this.props.show_sidebar} color_picker={this.color_picker}
|
token={this.props.token} show_sidebar={this.props.show_sidebar} color_picker={this.color_picker}
|
||||||
@@ -692,11 +685,14 @@ export class Flow extends PureComponent {
|
|||||||
if(this.state.mode==='list') {
|
if(this.state.mode==='list') {
|
||||||
API.get_list(page,this.props.token)
|
API.get_list(page,this.props.token)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(page===1)
|
if(page===1 && json.data.length) { // update latest_post_id
|
||||||
|
let max_id=-1;
|
||||||
json.data.forEach((x)=>{
|
json.data.forEach((x)=>{
|
||||||
if(parseInt(x.pid,10)>(parseInt(localStorage['_LATEST_POST_ID'],10)||0))
|
if(parseInt(x.pid,10)>max_id)
|
||||||
localStorage['_LATEST_POST_ID']=x.pid;
|
max_id=parseInt(x.pid,10);
|
||||||
});
|
});
|
||||||
|
localStorage['_LATEST_POST_ID']=''+max_id;
|
||||||
|
}
|
||||||
this.setState((prev,props)=>({
|
this.setState((prev,props)=>({
|
||||||
chunks: {
|
chunks: {
|
||||||
title: 'News Feed',
|
title: 'News Feed',
|
||||||
|
|||||||
@@ -5,26 +5,39 @@ export class Sidebar extends PureComponent {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.sidebar_ref=React.createRef();
|
this.sidebar_ref=React.createRef();
|
||||||
|
this.do_close_bound=this.do_close.bind(this);
|
||||||
|
this.do_back_bound=this.do_back.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(nextProps) {
|
componentDidUpdate(nextProps) {
|
||||||
if(this.props.content!==nextProps.content) {
|
if(this.props.stack!==nextProps.stack) {
|
||||||
//console.log('sidebar top');
|
//console.log('sidebar top');
|
||||||
if(this.sidebar_ref.current)
|
if(this.sidebar_ref.current)
|
||||||
this.sidebar_ref.current.scrollTop=0;
|
this.sidebar_ref.current.scrollTop=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_close() {
|
||||||
|
this.props.show_sidebar(null,null,'clear');
|
||||||
|
}
|
||||||
|
do_back() {
|
||||||
|
this.props.show_sidebar(null,null,'pop');
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let [cur_title,cur_content]=this.props.stack[this.props.stack.length-1];
|
||||||
return (
|
return (
|
||||||
<div className={this.props.title!==null ? 'sidebar-on' : ''}>
|
<div className={cur_title!==null ? 'sidebar-on' : ''}>
|
||||||
<div className="sidebar-shadow" onClick={this.props.do_close} onTouchEnd={(e)=>{e.preventDefault();e.target.click();}} />
|
<div className="sidebar-shadow" onClick={this.do_back_bound} onTouchEnd={(e)=>{e.preventDefault();e.target.click();}} />
|
||||||
<div ref={this.sidebar_ref} className="sidebar">
|
<div ref={this.sidebar_ref} className="sidebar">
|
||||||
{this.props.content}
|
{cur_content}
|
||||||
</div>
|
</div>
|
||||||
<div className="sidebar-title">
|
<div className="sidebar-title">
|
||||||
<a className="no-underline" onClick={this.props.do_close}> <span className="icon icon-back" /> </a>
|
<a className="no-underline" onClick={this.do_close_bound}> <span className="icon icon-close" /> </a>
|
||||||
{this.props.title}
|
{this.props.stack.length>2 &&
|
||||||
|
<a className="no-underline" onClick={this.do_back_bound}> <span className="icon icon-back" /> </a>
|
||||||
|
}
|
||||||
|
{cur_title}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.control-btn {
|
.control-btn {
|
||||||
flex: 0 0 2em;
|
flex: 0 0 4.5em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: black;
|
color: black;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
@@ -32,6 +32,17 @@
|
|||||||
background-color: #555555;
|
background-color: #555555;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
.control-btn-label {
|
||||||
|
margin-left: .25em;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 900px) {
|
||||||
|
.control-btn {
|
||||||
|
flex: 0 0 2em;
|
||||||
|
}
|
||||||
|
.control-btn-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.root-dark-mode .control-btn {
|
.root-dark-mode .control-btn {
|
||||||
color: var(--foreground-dark);
|
color: var(--foreground-dark);
|
||||||
@@ -42,11 +53,6 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-btn .icon:before {
|
|
||||||
margin: .5em;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-search {
|
.control-search {
|
||||||
flex: auto;
|
flex: auto;
|
||||||
color: black;
|
color: black;
|
||||||
|
|||||||
@@ -132,10 +132,12 @@ class ControlBar extends PureComponent {
|
|||||||
<div className="control-bar">
|
<div className="control-bar">
|
||||||
<a className="no-underline control-btn" onClick={this.do_refresh_bound}>
|
<a className="no-underline control-btn" onClick={this.do_refresh_bound}>
|
||||||
<span className="icon icon-refresh" />
|
<span className="icon icon-refresh" />
|
||||||
|
<span className="control-btn-label">最新</span>
|
||||||
</a>
|
</a>
|
||||||
{!!token &&
|
{!!token &&
|
||||||
<a className="no-underline control-btn" onClick={this.do_attention_bound}>
|
<a className="no-underline control-btn" onClick={this.do_attention_bound}>
|
||||||
<span className="icon icon-attention" />
|
<span className="icon icon-attention" />
|
||||||
|
<span className="control-btn-label">关注</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
<input className="control-search" value={this.state.search_text} placeholder="搜索 或 #PID"
|
<input className="control-search" value={this.state.search_text} placeholder="搜索 或 #PID"
|
||||||
@@ -168,6 +170,7 @@ class ControlBar extends PureComponent {
|
|||||||
)
|
)
|
||||||
}}>
|
}}>
|
||||||
<span className={'icon icon-'+(token ? 'about' : 'login')} />
|
<span className={'icon icon-'+(token ? 'about' : 'login')} />
|
||||||
|
<span className="control-btn-label">{token ? '账户' : '登录'}</span>
|
||||||
</a>
|
</a>
|
||||||
{!!token &&
|
{!!token &&
|
||||||
<a className="no-underline control-btn" onClick={()=>{
|
<a className="no-underline control-btn" onClick={()=>{
|
||||||
@@ -180,6 +183,7 @@ class ControlBar extends PureComponent {
|
|||||||
)
|
)
|
||||||
}}>
|
}}>
|
||||||
<span className="icon icon-plus" />
|
<span className="icon icon-plus" />
|
||||||
|
<span className="control-btn-label">发表</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user