├── README.md ├── flarum.ext.css ├── flarum └── core │ ├── src │ ├── Api │ │ └── JsonApiResponse.php │ └── Locale │ │ └── LocaleServiceProvider.php │ └── views │ └── frontend │ └── app.blade.php ├── fof └── upload │ ├── resources │ └── templates │ │ ├── audio.blade.php │ │ ├── image.blade.php │ │ ├── text.blade.php │ │ └── video.blade.php │ └── src │ ├── Providers │ └── DownloadProvider.php │ └── Templates │ ├── AudioTemplate.php │ ├── TextTemplate.php │ └── VideoTemplate.php └── hack.sh /README.md: -------------------------------------------------------------------------------- 1 | ## 用於 [vivaldi.club](https://vivaldi.club) 的一些 hack 2 | 3 | ### 需求 4 | 5 | - Flarum v0.1.0-beta.12 6 | 7 | ### HACK 8 | 9 | - 增加介面語言自動適配 10 | - 增加簡繁自動轉換 11 | - 增加中日韓字符註冊支援 12 | - 增加 @ 中日韓用戶名支援 13 | - 增加用戶頭像彩色邊框 14 | - 增加用戶 UID 展示 15 | - 增加用戶 UID 至 PostStream 屬性 16 | - 增加發帖人 UserAgent 展示 17 | - 增加 Vivaldi 用戶 PO 文專屬標記 18 | - 增加 [vivaldi://](vivaldi://about/) scheme 支援 19 | - 移除用戶名最小長度限制 20 | - 移除標題最小字數限制 21 | - 移除貼文字數限制 22 | - 移除論壇創建人灌水限制 23 | - 移除首頁節點列表中的次節點 24 | - 移除固頂貼預覽 25 | - 移除論壇連結 slug 26 | - 更改相對時間為絕對時間 27 | - 更改英文數位記法為中文數位記法 28 | - 更改用戶資料頁連結中的用戶名為 UID 29 | - 更改 font-awesome 加載位置 30 | - 更改 [reflar/level-ranks](https://github.com/reflar/level-ranks) 的計算方式,與 [antoinefr/flarum-ext-money](https://github.com/antoinefr/flarum-ext-money) 保持一致 31 | - 更改 [reflar/level-ranks](https://github.com/reflar/level-ranks) 升級經驗算法為 log(n) 32 | - 更改 [flagrow/upload](https://github.com/flagrow/upload) 文件大小為二進位前綴 33 | - 更改 [flagrow/upload](https://github.com/flagrow/upload) 異常提示,增加 MimeType 34 | - 更改 [flagrow/sitemap](https://github.com/flagrow/sitemap) 連結格式 35 | - 阻止 [flarum/pusher](https://github.com/flarum/pusher) 啟用後隱藏刷新按鈕 36 | - 阻止 [flagrow/split](https://github.com/flagrow/split) 生成 slug 37 | - 阻止 [fof/secure-https](https://github.com/FriendsOfFlarum/secure-https) 代理 HTTPS 內容 38 | - 客制 [BBCode](https://github.com/Csineneo/vivaldi-club-bbcode) 39 | - 客制 [flarum/core](https://github.com/flarum/core) 頁面模板 40 | - 客制 [flagrow/upload](https://github.com/flagrow/upload) 內容展示模板 41 | 42 | ### 演示站點 43 | 44 | - [Vivaldi Club](https://vivaldi.club) 45 | -------------------------------------------------------------------------------- /flarum.ext.css: -------------------------------------------------------------------------------- 1 | /* webfonts */ 2 | /* Font Awesome */ 3 | @font-face { 4 | font-family: "FAB"; 5 | font-style: normal; 6 | font-weight: normal; 7 | src: url(../fonts/fa-brands-400.eot); 8 | src: url(../fonts/fa-brands-400.eot?#iefix) format("embedded-opentype"), 9 | url(../fonts/fa-brands-400.woff2) format("woff2"), 10 | url(../fonts/fa-brands-400.woff) format("woff"), 11 | url(../fonts/fa-brands-400.ttf) format("truetype"), 12 | url(../fonts/fa-brands-400.svg#fontawesome) format("svg") 13 | } 14 | @font-face { 15 | font-family: "FAS"; 16 | font-style: normal; 17 | font-weight: 900; 18 | src: url(../fonts/fa-solid-900.eot); 19 | src: url(../fonts/fa-solid-900.eot?#iefix) format("embedded-opentype"), 20 | url(../fonts/fa-solid-900.woff2) format("woff2"), 21 | url(../fonts/fa-solid-900.woff) format("woff"), 22 | url(../fonts/fa-solid-900.ttf) format("truetype"), 23 | url(../fonts/fa-solid-900.svg#fontawesome) format("svg") 24 | } 25 | .fa { font-family: FAB, FAS; } 26 | .fab { font-family: FAB; } 27 | .fas { font-family: FAS; font-weight: 900; } 28 | 29 | /* latin-ext */ 30 | @font-face { 31 | font-family: 'Source Code Pro'; 32 | font-style: normal; 33 | font-weight: 400; 34 | src: local('Source Code Pro'), local('SourceCodePro-Regular'), url(https://fonts.gstatic.com/s/sourcecodepro/v8/HI_SiYsKILxRpg3hIP6sJ7fM7PqlM-vWnsUnxlC9.woff2) format('woff2'); 35 | unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; 36 | } 37 | /* latin */ 38 | @font-face { 39 | font-family: 'Source Code Pro'; 40 | font-style: normal; 41 | font-weight: 400; 42 | src: local('Source Code Pro'), local('SourceCodePro-Regular'), url(https://fonts.gstatic.com/s/sourcecodepro/v8/HI_SiYsKILxRpg3hIP6sJ7fM7PqlPevWnsUnxg.woff2) format('woff2'); 43 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; 44 | } 45 | /* latin-ext */ 46 | @font-face { 47 | font-family: 'Raleway'; 48 | font-style: normal; 49 | font-weight: 400; 50 | src: local('Raleway'), local('Raleway-Regular'), url(https://fonts.gstatic.com/s/raleway/v12/1Ptug8zYS_SKggPNyCMIT4ttDfCmxA.woff2) format('woff2'); 51 | unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; 52 | } 53 | /* latin */ 54 | @font-face { 55 | font-family: 'Raleway'; 56 | font-style: normal; 57 | font-weight: 400; 58 | src: local('Raleway'), local('Raleway-Regular'), url(https://fonts.gstatic.com/s/raleway/v12/1Ptug8zYS_SKggPNyC0IT4ttDfA.woff2) format('woff2'); 59 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; 60 | } 61 | 62 | * { tab-size: 4; } 63 | :target { background-color: #e3f5ff; } 64 | ::selection { color: #f3f; } 65 | body { font-family: Raleway, FAB, FAS, 'System Latin'; font-size: 15px; line-height: 1.5em; text-rendering: optimizeLegibility; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: subpixel-antialiased; -webkit-tap-highlight-color: rgba(158, 217, 248, .3); } 66 | code { white-space: pre-wrap; font-family: 'Source Code Pro', 'System Mono'; } 67 | li.item-joined, li.item-lastSeen { display: block; line-height: 1.7; } 68 | li.item-lastSeen .online { display: inline-block; } 69 | input.FormControl { color: #998f66 !important; } 70 | small { color: transparent; font-size: 7px; line-height: 1em; width: 100%; margin-top: 20px; word-break: break-all; clear: both; display: block; overflow: hidden; text-overflow: ellipsis; white-space: pre-wrap; } 71 | small:hover { color: #f3f; } 72 | #footer { margin: 1em auto; padding-top: 3em; text-align: center; color: #7c7c7c; width: 61.8%;} 73 | .viv-icon { float: right; width: 150px; box-shadow: 0 0 1px #ccc; } 74 | .tofu-snapshot { margin-bottom: 2em; padding: 12px 16px; color: #ad6c00; background: #fff2ae; line-height: 1.5; border-radius: 4px; } 75 | .Badge--group--10 { display: none !important; } 76 | .DiscussionList-loadMore .Button { width: 100%; } 77 | .Post { padding-bottom: 3px; } 78 | .Post-footer { margin-bottom: 0; } 79 | .Post-mentionedBy-preview { width: 640px !important; } 80 | .PostUser-level { margin-bottom: 20px; } 81 | .Search-input input { width: 125px; } 82 | .TagsPage .item-flagrow-ad { display: none !important; } 83 | .item-discussion-views { width: 33px; margin-right: -70px; } 84 | .item-discussion-views::before { margin-left: -22px; } 85 | .item-terminalPost { font-size: 13px; } 86 | .item-money:before { content: "\f530"; } 87 | .uid-1 { border-color: #e03c8a !important; } 88 | .upl-image-tpl { border: 1px solid #CB1B4567; margin: 16px; } 89 | .upl-image-tpl figcaption { background-color: #CB1B45; color: #fff; height: 2em; line-height: 2em; padding: 0 .5em; } 90 | .upl-image-title i { margin-right: .3em; } 91 | .upl-image-size i { margin: 0 .3em 0 1em; } 92 | .upl-image-link { float: right; } 93 | .upl-image-link a { color: #fff; border-bottom: none; } 94 | 95 | /* Dark Mode */ 96 | body.dark .Dropdown-menu > li > a:hover, 97 | body.dark .Dropdown-menu > li > button:hover, 98 | { color: #CB1B45 } 99 | body.dark .Dropdown-menu > li > a, 100 | body.dark .Dropdown-menu > li > button, 101 | body.dark .DiscussionListItem-count 102 | { background-color: transparent !important; } 103 | body.dark .DiscussionListItem-title { color: #ccc; } 104 | 105 | /* Tag Icon */ 106 | .TagHero .Hero-title:before, .TagLabel > span:before { height: 22px; margin-right: 0.3em; display: inline-block; font-family: FAS; font-size: 85%; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 107 | .TagLinkButton > .TagIcon { width: 18px !important; height: 18px !important; } 108 | .TagLinkButton > span:before { color: #fff; height: 22px; display: block; font-family: FAS; font-size: 85%; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 109 | /* vivaldi */ 110 | .TagHero[style*='rgb(203, 27, 69)'] .Hero-title:before, 111 | .TagLabel[style*='rgb(203, 27, 69)'] > span:before, 112 | .TagLinkButton span[style*='rgb(203, 27, 69)']:before 113 | { content: "\f004"; } 114 | /* browser */ 115 | .TagHero[style*='rgb(88, 178, 220)'] .Hero-title:before, 116 | .TagLabel[style*='rgb(88, 178, 220)'] > span:before, 117 | .TagLinkButton span[style*='rgb(88, 178, 220)']:before 118 | { content: "\f268"; font-family: FAB; } 119 | /* opera */ 120 | .TagHero[style*='rgb(255, 75, 75)'] .Hero-title:before, 121 | .TagLabel[style*='rgb(255, 75, 75)'] > span:before, 122 | .TagLinkButton span[style*='rgb(255, 75, 75)']:before 123 | { content: "\f26a"; font-family: FAB; } 124 | /* flarum*/ 125 | .TagHero[style*='rgb(231, 103, 46)'] .Hero-title:before, 126 | .TagLabel[style*='rgb(231, 103, 46)'] > span:before, 127 | .TagLinkButton span[style*='rgb(231, 103, 46)']:before 128 | { content: "\f120"; } 129 | /* robot */ 130 | .TagHero[style*='rgb(178, 143, 206)'] .Hero-title:before, 131 | .TagLabel[style*='rgb(178, 143, 206)'] > span:before, 132 | .TagLinkButton span[style*='rgb(178, 143, 206)']:before 133 | { content: "\f17b"; font-family: FAB; } 134 | /* inner */ 135 | .TagHero[style*='rgb(67, 67, 67)'] .Hero-title:before, 136 | .TagLabel[style*='rgb(67, 67, 67)'] > span:before, 137 | .TagLinkButton span[style*='rgb(67, 67, 67)']:before 138 | { content: "\f21b"; } 139 | /* pool */ 140 | .TagHero[style*='rgb(102, 186, 183)'] .Hero-title:before, 141 | .TagLabel[style*='rgb(102, 186, 183)'] > span:before, 142 | .TagLinkButton span[style*='rgb(102, 186, 183)']:before 143 | { content: "\f0f4"; } 144 | /* share */ 145 | .TagHero[style*='rgb(241, 124, 103)'] .Hero-title:before, 146 | .TagLabel[style*='rgb(241, 124, 103)'] > span:before, 147 | .TagLinkButton span[style*='rgb(241, 124, 103)']:before 148 | { content: "\f06b"; } 149 | /* help */ 150 | .TagHero[style*='rgb(202, 122, 44)'] .Hero-title:before, 151 | .TagLabel[style*='rgb(202, 122, 44)'] > span:before, 152 | .TagLinkButton span[style*='rgb(202, 122, 44)']:before 153 | { content: "\f059"; } 154 | /* hardware */ 155 | .TagHero[style*='rgb(134, 193, 102)'] .Hero-title:before, 156 | .TagLabel[style*='rgb(134, 193, 102)'] > span:before, 157 | .TagLinkButton span[style*='rgb(134, 193, 102)']:before 158 | { content: "\f108"; } 159 | /* software */ 160 | .TagHero[style*='rgb(93, 172, 129)'] .Hero-title:before, 161 | .TagLabel[style*='rgb(93, 172, 129)'] > span:before, 162 | .TagLinkButton span[style*='rgb(93, 172, 129)']:before 163 | { content: "\f085"; } 164 | /* xyz */ 165 | .TagHero[style*='rgb(225, 107, 140)'] .Hero-title:before, 166 | .TagLabel[style*='rgb(225, 107, 140)'] > span:before, 167 | .TagLinkButton span[style*='rgb(225, 107, 140)']:before 168 | { content: "\f0a1"; } 169 | /* sandbox */ 170 | .TagHero[style*='rgb(135, 135, 135)'] .Hero-title:before, 171 | .TagLabel[style*='rgb(135, 135, 135)'] > span:before, 172 | .TagLinkButton span[style*='rgb(135, 135, 135)']:before 173 | { content: "\f0c3"; } 174 | /* contributor */ 175 | .TagHero[style*='rgb(255, 136, 153)'] .Hero-title:before, 176 | .TagLabel[style*='rgb(255, 136, 153)'] > span:before, 177 | .TagLinkButton span[style*='rgb(255, 136, 153)']:before 178 | { content: "\f4c0"; } 179 | 180 | /* xts badge */ 181 | @-webkit-keyframes fa-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(359deg); } } 182 | @keyframes fa-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(359deg); } } 183 | i.fa-spinner { -webkit-animation: fa-spin 1s infinite steps(8); animation: fa-spin 1s infinite steps(8); } 184 | 185 | /* mobile */ 186 | @media(max-width:1000px) { 187 | [class^=item-group], .viv-icon, .IndexPage-nav a img, .item-onlineUsers, .item-flagrow-ad { display: none !important; } 188 | li.item-session { padding-left: 12px; } 189 | #footer { width: 100%; } 190 | .item-discussion-views { right: 90px; } 191 | } 192 | -------------------------------------------------------------------------------- /flarum/core/src/Api/JsonApiResponse.php: -------------------------------------------------------------------------------- 1 | jsonSerialize(), 256), $ccconfig); 48 | opencc_close($ccconfig); 49 | parent::__construct(json_decode($cctext), $status, $headers, $encodingOptions); 50 | } else { 51 | // The call to jsonSerialize prevents rare issues with json_encode() failing with a 52 | // syntax error even though Document implements the JsonSerializable interface. 53 | // See https://github.com/flarum/core/issues/685 54 | parent::__construct($document->jsonSerialize(), $status, $headers, $encodingOptions); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /flarum/core/src/Locale/LocaleServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Flarum\Locale; 13 | 14 | use Flarum\Event\ConfigureLocales; 15 | use Flarum\Foundation\AbstractServiceProvider; 16 | use Flarum\Settings\SettingsRepositoryInterface; 17 | use Illuminate\Contracts\Events\Dispatcher; 18 | use Illuminate\Contracts\Translation\Translator as TranslatorContract; 19 | use Symfony\Component\Translation\MessageSelector; 20 | use Symfony\Component\Translation\TranslatorInterface; 21 | 22 | class LocaleServiceProvider extends AbstractServiceProvider 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function boot(Dispatcher $events) 28 | { 29 | $locales = $this->app->make('flarum.locales'); 30 | 31 | // tofu $locales->addLocale($this->getDefaultLocale(), 'Default'); 32 | switch ($this->getDefaultLocale()) { 33 | case 'zh-hant': 34 | $locales->addLocale('zh-hant', '正體中文'); 35 | break; 36 | case 'zh-hans': 37 | $locales->addLocale('zh-hans', '简体中文'); 38 | break; 39 | default: 40 | $locales->addLocale('en', 'English'); 41 | } 42 | 43 | $events->dispatch(new ConfigureLocales($locales)); 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function register() 50 | { 51 | $this->app->singleton(LocaleManager::class); 52 | $this->app->alias(LocaleManager::class, 'flarum.locales'); 53 | 54 | $this->app->singleton('translator', function () { 55 | $translator = new Translator($this->getDefaultLocale(), new MessageSelector()); 56 | $translator->setFallbackLocales(['en']); 57 | $translator->addLoader('prefixed_yaml', new PrefixedYamlFileLoader()); 58 | 59 | return $translator; 60 | }); 61 | $this->app->alias('translator', Translator::class); 62 | $this->app->alias('translator', TranslatorContract::class); 63 | $this->app->alias('translator', TranslatorInterface::class); 64 | } 65 | 66 | private function getDefaultLocale(): string 67 | { 68 | $lang=""; 69 | if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { 70 | preg_match('/^([a-z\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches); 71 | $lang = strtolower($matches[1]); 72 | } 73 | switch ($lang) { 74 | case 'zh-tw': 75 | case 'zh-hk': 76 | case 'zh': 77 | return 'zh-hant'; 78 | break; 79 | case 'zh-cn': 80 | case 'zh-sg': 81 | return 'zh-hans'; 82 | break; 83 | default: 84 | return 'en'; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /flarum/core/views/frontend/app.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ $title }} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {!! $head !!} 31 | 32 | 33 | 34 | 47 | 48 | 49 | 50 | {!! $layout !!} 51 | 52 | 53 |
54 | 55 | 59 | 60 | {!! $js !!} 61 | 62 | 76 | 80 | {!! $foot !!} 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /fof/upload/resources/templates/audio.blade.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | {SIMPLETEXT1} 5 | {SIMPLETEXT2} 6 | 7 |
8 |
9 | -------------------------------------------------------------------------------- /fof/upload/resources/templates/image.blade.php: -------------------------------------------------------------------------------- 1 |
2 | {SIMPLETEXT1} 3 |
4 | {SIMPLETEXT1} 5 | {SIMPLETEXT2} 6 | 7 |
8 |
9 | -------------------------------------------------------------------------------- /fof/upload/resources/templates/text.blade.php: -------------------------------------------------------------------------------- 1 |
2 |

 3 |   
4 | {SIMPLETEXT1} 5 | {SIMPLETEXT2} 6 | 7 |
8 |
9 | 10 | -------------------------------------------------------------------------------- /fof/upload/resources/templates/video.blade.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | {SIMPLETEXT1} 5 | {SIMPLETEXT2} 6 | 7 |
8 |
9 | -------------------------------------------------------------------------------- /fof/upload/src/Providers/DownloadProvider.php: -------------------------------------------------------------------------------- 1 | app->make(DefaultDownloader::class) 22 | ); 23 | 24 | $this->loadViewsFrom(__DIR__ . '/../../resources/templates', 'fof-upload.templates'); 25 | 26 | /** @var Settings $settings */ 27 | $settings = $this->app->make(Settings::class); 28 | 29 | $settings->addRenderTemplate($this->app->make(FileTemplate::class)); 30 | $settings->addRenderTemplate($this->app->make(ImageTemplate::class)); 31 | $settings->addRenderTemplate($this->app->make(ImagePreviewTemplate::class)); 32 | $settings->addRenderTemplate($this->app->make(AudioTemplate::class)); 33 | $settings->addRenderTemplate($this->app->make(VideoTemplate::class)); 34 | $settings->addRenderTemplate($this->app->make(TextTemplate::class)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /fof/upload/src/Templates/AudioTemplate.php: -------------------------------------------------------------------------------- 1 | getView('fof-upload.templates::audio'); 36 | } 37 | 38 | /** 39 | * The bbcode to be parsed. 40 | * 41 | * @return string 42 | */ 43 | public function bbcode() 44 | { 45 | return '[upl-audio uuid={IDENTIFIER} size={SIMPLETEXT2} url={URL}]{SIMPLETEXT1}[/upl-audio]'; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /fof/upload/src/Templates/TextTemplate.php: -------------------------------------------------------------------------------- 1 | getView('fof-upload.templates::text'); 36 | } 37 | 38 | /** 39 | * The bbcode to be parsed. 40 | * 41 | * @return string 42 | */ 43 | public function bbcode() 44 | { 45 | return '[upl-text uuid={IDENTIFIER} size={SIMPLETEXT2} url={URL}]{SIMPLETEXT1}[/upl-text]'; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /fof/upload/src/Templates/VideoTemplate.php: -------------------------------------------------------------------------------- 1 | getView('fof-upload.templates::video'); 36 | } 37 | 38 | /** 39 | * The bbcode to be parsed. 40 | * 41 | * @return string 42 | */ 43 | public function bbcode() 44 | { 45 | return '[upl-video uuid={IDENTIFIER} size={SIMPLETEXT2} url={URL}]{SIMPLETEXT1}[/upl-video]'; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /hack.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | GITHUB_ROOT="https://raw.githubusercontent.com/Csineneo/flarum-hack/master" 4 | 5 | # 簡繁語言包及 BBCode 6 | composer require csineneo/lang-traditional-chinese 7 | composer require csineneo/lang-simplified-chinese 8 | composer require csineneo/vivaldi-club-bbcode 9 | 10 | # 其他 11 | composer require dem13n/nickname-changer 12 | composer require antoinefr/flarum-ext-money 13 | composer require reflar/level-ranks 14 | composer require flagrow/sitemap 15 | composer require fof/upload 16 | composer require fof/split 17 | composer require fof/secure-https 18 | 19 | 20 | # 用戶端語言識別 21 | wget -qO "vendor/flarum/core/src/Locale/LocaleServiceProvider.php" \ 22 | "$GITHUB_ROOT/flarum/core/src/Locale/LocaleServiceProvider.php" 23 | 24 | # 簡繁自動轉換 25 | wget -qO "vendor/flarum/core/src/Api/JsonApiResponse.php" \ 26 | "$GITHUB_ROOT/flarum/core/src/Api/JsonApiResponse.php" 27 | 28 | # 允許註冊中文名 29 | sed -i "s#a-z0-9_-#-_a-z0-9\\\x7f-\\\xff#" \ 30 | vendor/flarum/core/src/User/UserValidator.php 31 | 32 | # 支援 @ 中文名 33 | sed -i "s#a-z0-9_-#-_a-zA-Z0-9\\\x7f-\\\xff#" \ 34 | vendor/flarum/mentions/src/ConfigureMentions.php 35 | 36 | # 取消標題及用戶名最小長度限制 37 | sed -i 's#min:3#min:1#' \ 38 | vendor/flarum/core/src/User/UserValidator.php \ 39 | vendor/flarum/core/src/Discussion/DiscussionValidator.php 40 | 41 | # 加大貼文字數 42 | # ALTER TABLE `posts` CHANGE `content` `content` mediumtext COLLATE 'utf8mb4_unicode_ci' NULL COMMENT ' ' AFTER `type`; 43 | sed -i 's#65535#2147483647#' \ 44 | vendor/flarum/core/src/Post/PostValidator.php 45 | 46 | # 不限制管理員灌水 47 | sed -i -r "s#(isFlooding = )#\1\$actor->id == '1' ? false : #" \ 48 | vendor/flarum/core/src/Post/Floodgate.php 49 | 50 | # 支援 vivaldi:// scheme 51 | sed -i "/Autoemail/i\\\t\\t\$configurator->urlConfig->allowScheme('vivaldi');" \ 52 | vendor/s9e/text-formatter/src/Configurator/Bundles/Fatdown.php 53 | sed -i "/new SchemeList/a\\\t\\t\$this->allowedSchemes[] = 'vivaldi';" \ 54 | vendor/s9e/text-formatter/src/Configurator/UrlConfig.php 55 | sed -i 's#ftp|https#ftp|vivaldi|https#g' \ 56 | vendor/s9e/text-formatter/src/Bundles/Fatdown.php 57 | 58 | # 顯示發帖人 UA 59 | # SQL: ALTER TABLE tbl_posts ADD user_agent varchar(255); 60 | sed -i 's#\$ipAddress)#\$ipAddress\, string \$userAgent)#; /->ipAddress/a\\t\t\t\t$this->userAgent = $userAgent;' \ 61 | vendor/flarum/core/src/Discussion/Command/StartDiscussion.php 62 | sed -i -r '/new PostReply/s/(ipAddress)/\1, $userAgent/; /->ipAddress/a\\t\t\t\t$userAgent = $command->userAgent;' \ 63 | vendor/flarum/core/src/Discussion/Command/StartDiscussionHandler.php 64 | sed -i -e '/new StartDiscussion/s/)$/, \$userAgent)/' \ 65 | -e "/ipAddress =/a\\\t\t\t\t\$userAgent = Arr::get(\$request->getServerParams(), 'HTTP_USER_AGENT', '');" \ 66 | vendor/flarum/core/src/Api/Controller/CreateDiscussionController.php 67 | sed -i -r 's#(ipAddress = null)#\1, string $userAgent#; /->ipAddress/a\\t\t\t\t$this->userAgent = $userAgent;' \ 68 | vendor/flarum/core/src/Post/Command/PostReply.php 69 | sed -i -r 's#(ipAddress)$#\1,#; /ipAddress/a\\t\t\t\t\t\t$command->userAgent' \ 70 | vendor/flarum/core/src/Post/Command/PostReplyHandler.php 71 | sed -i -e 's#ipAddress)#ipAddress, $userAgent)#' \ 72 | -e "/ADDR/a\\\t\t\t\t\$userAgent = Arr::get(\$request->getServerParams(), 'HTTP_USER_AGENT', '');" \ 73 | vendor/flarum/core/src/Api/Controller/CreatePostController.php 74 | sed -i -e '/ip_address/a\\t\t\t\t$post->user_agent = $userAgent;' \ 75 | -e 's#ipAddress)#ipAddress, $userAgent)#' \ 76 | vendor/flarum/core/src/Post/CommentPost.php 77 | sed -i "/contentHtml/a\\\t\t\t\t\t\t\$attributes['userAgent'] = \$post->user_agent;" \ 78 | vendor/flarum/core/src/Api/Serializer/BasicPostSerializer.php 79 | sed -i -r 's#(footerItems\(\).toArray\(\)\)\))#\1,m("small",{className:"ua"},e.props.post.data.attributes.userAgent\)#' \ 80 | vendor/flarum/core/js/dist/forum.js 81 | 82 | # 透過 Vivaldi PO 文享專屬 banner 83 | #sed -i -r "s#(t.stopPropagation\(\)}}\)\))#\1,/Vivaldi/.test(t.data.attributes.userAgent)?m('img',{className:'viv-icon',src:'https://awk.tw/assets/images/viv-badge.png'}):''#" \ 84 | # vendor/flarum/core/js/dist/forum.js 85 | 86 | # URL 美化,移除 slug 87 | sed -i '/discussion->slug/d' \ 88 | vendor/flarum/core/src/Api/Serializer/BasicDiscussionSerializer.php 89 | sed -i -r 's#(discussion->id).*$#\1#' \ 90 | vendor/flarum/core/views/frontend/content/index.blade.php 91 | sed -i '/idWithSlug =/s/\..*$/;/' \ 92 | vendor/flarum/core/src/Forum/Content/Discussion.php 93 | sed -i 's#+(i.trim()?"-"+i:"")##' \ 94 | vendor/flarum/core/js/dist/forum.js 95 | 96 | # 改為使用 UID 訪問用戶頁面 97 | sed -i 's#username:e\.username#username:e.id#g' \ 98 | vendor/flarum/core/js/dist/forum.js \ 99 | vendor/flarum/mentions/js/dist/forum.js 100 | 101 | # 允許搜尋長度小於三個字符的 ID 102 | sed -i 's#length>=3\&#length>=1\&#' \ 103 | vendor/flarum/core/js/dist/forum.js 104 | 105 | # 在用戶卡片及用戶頁面中展示 UID 106 | sed -i -r 's#(UserCard-info"},)#\1Object(T.a)("UID:\\t\\t"+t.id()),#' \ 107 | vendor/flarum/core/js/dist/forum.js 108 | 109 | # 新增 UID 至 PostStream 110 | sed -i -r 's#(=i.contentType)#\1(),u["user-id"]=i.user().id#' \ 111 | vendor/flarum/core/js/dist/forum.js 112 | 113 | # 以絕對時間顯示 114 | sed -i "s#-2592e6#-864e5#; s#D MMM#LLLL#; s#MMM 'YY#LLLL#" \ 115 | vendor/flarum/core/js/dist/forum.js \ 116 | vendor/flarum/core/js/dist/admin.js 117 | sed -i 's#D MMM#L#g' \ 118 | vendor/flarum/statistics/js/dist/admin.js 119 | 120 | # 使用中文數位記法 121 | sed -i 's#t>=1e3#t>=1e4#; s#(t\/1e3)#(t/1e4)#; s#kilo_text#ten_kilo_text#' \ 122 | vendor/flarum/core/js/dist/admin.js \ 123 | vendor/flarum/core/js/dist/forum.js 124 | sed -i '/kilo_text/a\ ten_kilo_text: 0K' \ 125 | vendor/flarum/lang-english/locale/core.yml 126 | 127 | # 為頭像增加彩色邊框 128 | sed -i -r 's#"(}\),Object\(Ot)# uid-"+e.id(),style:"border:solid "+e.color()\1#' \ 129 | vendor/flarum/core/js/dist/forum.js 130 | 131 | # 首頁節點列表不顯示次節點 132 | sed -i 's#o.splice(0,3).forEach(s),##' \ 133 | vendor/flarum/tags/js/dist/forum.js 134 | 135 | # 啟用 Pusher 後不隱藏刷新按鈕 136 | sed -i 's#Object(o.extend)(p.a.prototype,"actionItems",(function(e){e.remove("refresh")})),##' \ 137 | vendor/flarum/pusher/js/dist/forum.js 138 | 139 | # 固頂貼不顯示預覽 140 | sed -i "/'includeFirstPost'/d" \ 141 | vendor/flarum/sticky/src/Listener/AddApiAttributes.php 142 | sed -i 's#Object(f.extend)(S.a.prototype,"requestParams",(function(t){t.include.push("firstPost")})),##' \ 143 | vendor/flarum/sticky/js/dist/forum.js 144 | 145 | # 更改 font-awesome 加載位置 146 | sed -i 's#\./#https://awk.tw/assets/#' \ 147 | vendor/flarum/core/less/common/common.less 148 | 149 | # 更改 reflar/level-ranks 升級經驗算法為 log(n) 150 | sed -i 's#r\/135),s=100\/135\*(r-135\*n)#Math.log(r)),s=Math.log(r).toFixed(4).split(".")[1]/100#' \ 151 | vendor/reflar/level-ranks/js/dist/forum.js 152 | 153 | # 確保 antoinefr/flarum-ext-money 與 reflar/level-ranks 的計算方式一致 154 | # n = 5*discussionCount + commentCount 155 | sed -i -r 's#21.*(t.discussionCount)#t.commentCount()+5*\1#' \ 156 | vendor/reflar/level-ranks/js/dist/forum.js 157 | sed -i -r 's#(money\]",)(this.props.user.data.attributes.)money#\1\2discussionCount*5+\2commentCount#g' \ 158 | vendor/antoinefr/flarum-ext-money/js/dist/forum.js 159 | 160 | # 使得 tooltip 在滑鼠右側彈出避免遮擋 161 | sed -i -r 's#(placement:")top#\1right#' \ 162 | vendor/flarum/core/js/dist/forum.js 163 | 164 | # 更改 flagrow/sitemap 連結格式,移除 slug,使用 UID 訪問用戶頁面 165 | sed -i -e "s# . '-' . \$discussion->slug##; s# . '-' . \$page->slug##; s#username#id#" \ 166 | vendor/flagrow/sitemap/src/SitemapGenerator.php 167 | 168 | # 更改 fof/upload 文件大小為二進位前綴 169 | sed -i 's#kB#KiB#; s#MB#MiB#; s#GB#GiB#; s#TB#TiB#; s#PB#PiB#; s#EB#EiB#; s#ZB#ZiB#; s#YB#YiB#' \ 170 | vendor/fof/upload/src/File.php 171 | 172 | # 為異常提示增加 MimeType 173 | sed -i -r "s#(this type)#\1 ('.\$upload->getClientMimeType().')#" \ 174 | vendor/fof/upload/src/Commands/UploadHandler.php 175 | 176 | # 阻止 amaurycarrade/flarum-ext-syndication 生成 slug 177 | sed -i "s# . '-' . \$discussion->attributes->slug##" \ 178 | vendor/amaurycarrade/flarum-ext-syndication/src/Controller/DiscussionFeedController.php \ 179 | vendor/amaurycarrade/flarum-ext-syndication/src/Controller/DiscussionsActivityFeedController.php 180 | 181 | # 阻止 fof/split 生成 slug 182 | sed -i 's#-{\$slug}##' \ 183 | vendor/fof/split/src/Posts/DiscussionSplitPost.php 184 | sed -i 's#-{\$event->discussion->slug}##' \ 185 | vendor/fof/split/src/Listeners/UpdateSplitTitleAfterDiscussionWasRenamed.php 186 | 187 | # 阻止 fof/secure-https 代理 HTTPS 內容,並清理原始碼 188 | sed -i -e '/proxyUrl . urlencode/d; /proxyUrl/a\\t\t\t\treturn substr(\$attrValue, 0, 5 ) === "http:" ? \$proxyUrl . urlencode(\$attrValue) : \$attrValue;' \ 189 | vendor/fof/secure-https/src/Listeners/ModifyContentHtml.php 190 | sed -i "s#\$imgurl, -3#strrchr(\$imgurl, '.'), 1#" \ 191 | vendor/fof/secure-https/src/Api/Controllers/GetImageUrlController.php 192 | 193 | # 客制 fof/upload 內容展示模板 194 | for f in \ 195 | fof/upload/resources/templates/image.blade.php \ 196 | fof/upload/resources/templates/audio.blade.php \ 197 | fof/upload/resources/templates/video.blade.php \ 198 | fof/upload/resources/templates/text.blade.php \ 199 | fof/upload/src/Templates/AudioTemplate.php \ 200 | fof/upload/src/Templates/VideoTemplate.php \ 201 | fof/upload/src/Templates/TextTemplate.php \ 202 | fof/upload/src/Providers/DownloadProvider.php 203 | do 204 | wget -qO "vendor/$f" "$GITHUB_ROOT/$f" 205 | done 206 | 207 | # 客制頁面模板 208 | wget -qO "vendor/flarum/core/views/frontend/app.blade.php" \ 209 | "$GITHUB_ROOT/flarum/core/views/frontend/app.blade.php" 210 | 211 | --------------------------------------------------------------------------------