Merge branch '2.x' into dk/info-v2
Some checks failed
Backend Tests / run (push) Has been cancelled
Frontend Workflow / run (push) Has been cancelled
Static Code Analysis / run (push) Has been cancelled

This commit is contained in:
Daniël Klabbers 2025-01-28 11:02:41 +01:00
commit 8f6e46346a
84 changed files with 231 additions and 136 deletions

View File

@ -18,7 +18,7 @@ trim_trailing_whitespace = false
[*.{php,xml,json}]
indent_size = 4
[{tsconfig.json,prettierrc.json}]
[{tsconfig.json,prettierrc.json,package.json}]
indent_size = 2
[*.neon]

View File

@ -1,5 +1,29 @@
# Changelog
## [v2.0.0-beta.2](https://github.com/flarum/framework/compare/v2.0.0-beta.1...v2.0.0-beta.2)
### Fixed
- (em) incorrect extension compatibility check [#4155]
- (webpack) produces incorrect ext namespace (a7d584f8e1ec650035dafd660a70586d1d0d6bb9)
- bad modal alert text alignment [#4152]
- beta.1 early bugs (a81d13e26c1c2191859493de2ad45a515ad07b90)
- code split fails with common module [#4151]
- composer no longer autofocusing [#4149]
- conditional renders 0 (1cd644d27feb4eeea5cbaedd009a3af2643af396)
- custom styles from 1.x can crash the app [#4159]
- discussion page renders before loading is finished [#4158]
- discussion posts not always properly loaded [#4156]
- fixed side nav missing top spacing [#4147]
- invisible dropdown text when header is colored (958dec594486cbc14cf8f922db324a8ffc0245e3)
- lazy module import always returns default module [#4148]
- mistakenly removed code (33121ed1cc260bf967f0b8c4d10ab5099410bac0)
- select input cuts off [#4157]
- tag selection icon alignment [#4153]
- unexpected subscription breaks rendering [#4150]
- use correct human time format key [#4154]
### Changed
- (mentions) only access related mentions if loaded (9fe17b3c24c5b9236e419a00c1230b2994b8c009)
- extensibility improvements (00426c85e38efc91554af33644b088e72b3b3c1b)
## [v2.0.0-beta.1](https://github.com/flarum/framework/compare/v1.8.9...v2.0.0-beta.1)
### Changed
- php 8.4 [#4103]

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1",
"flarum/core": "^2.0.0-beta.2",
"flarum/approval": "^2.0"
},
"autoload": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1",
"flarum/core": "^2.0.0-beta.2",
"flarum/flags": "^2.0"
},
"autoload": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"extra": {
"branch-alias": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -7,7 +7,7 @@
],
"license": "MIT",
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"extra": {
"branch-alias": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"extra": {
"branch-alias": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -7,7 +7,7 @@
"type": "flarum-extension",
"license": "MIT",
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"authors": [
{

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -22,7 +22,7 @@
"source": "https://github.com/flarum/extension-manager"
},
"require": {
"flarum/core": "^2.0.0-beta.1",
"flarum/core": "^2.0.0-beta.2",
"composer/composer": "^2.7"
},
"require-dev": {

View File

@ -19,8 +19,8 @@ export default class ExternalExtension extends Model {
locale: () => string;
latestFlarumVersionSupported: () => string;
downloads: () => number;
isSupported: () => boolean;
readonly installed = false;
isSupported(): boolean;
isProductionReady(): boolean;
toLocalExtension(): Extension;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -22,21 +22,9 @@ export default class ExternalExtension extends Model {
locale = Model.attribute<string>('locale');
latestFlarumVersionSupported = Model.attribute<string>('latestFlarumVersionSupported');
downloads = Model.attribute<number>('downloads');
isSupported = Model.attribute<boolean>('isSupported');
readonly installed = false;
public isSupported(): boolean {
const currentVersion = app.data.settings.version;
const latestCompatibleVersion = this.latestFlarumVersionSupported();
// If stability is not the same, it's not compatible.
if (currentVersion.split('-')[1] !== latestCompatibleVersion.split('-')[1]) {
return false;
}
// Minor versions are compatible.
return currentVersion.split('.')[0] === latestCompatibleVersion.split('.')[0];
}
public isProductionReady(): boolean {
return isProductionReady(this.highestVersion());
}

View File

@ -9,6 +9,7 @@
namespace Flarum\ExtensionManager\Api\Resource;
use Composer\Semver\Semver;
use Flarum\Api\Endpoint;
use Flarum\Api\Resource\AbstractResource;
use Flarum\Api\Resource\Contracts\Countable;
@ -81,6 +82,11 @@ class ExternalExtensionResource extends AbstractResource implements Listable, Pa
Schema\Boolean::make('compatibleWithLatestFlarum')
->property('compatible_with_latest_flarum'),
Schema\Integer::make('downloads'),
Schema\Boolean::make('isSupported')
->get(function (Extension $extension) {
return Semver::satisfies(Application::VERSION, $extension->latest_flarum_version_supported);
}),
];
}

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1",
"flarum/core": "^2.0.0-beta.2",
"pusher/pusher-php-server": "^7.2"
},
"require-dev": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -51,7 +51,7 @@ export default class SubscriptionMenu<CustomAttrs extends ISubscriptionMenuAttrs
const discussion = this.attrs.discussion;
const subscription = discussion.subscription();
const buttonAttrs = this.possibleButtonAttrs[subscription];
const buttonAttrs = this.possibleButtonAttrs[subscription ?? 'null'] ?? this.possibleButtonAttrs.null;
const preferences = app.session.user!.preferences()!;
const notifyEmail = preferences['notify_newPost_email'];

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^2.0.0-beta.1"
"flarum/core": "^2.0.0-beta.2"
},
"autoload": {
"psr-4": {

View File

@ -3,8 +3,6 @@
width: 16px;
height: 16px;
display: inline-block;
vertical-align: -3px;
margin-left: 1px;
background: var(--color, var(--control-bg));
&.untagged {

View File

@ -57,6 +57,8 @@
position: absolute;
inset: 0;
display: none;
align-items: center;
justify-content: center;
background-color: transparent;
}
@ -76,6 +78,8 @@
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
display: flex;
align-items: center;
&.pinned:not(.child) {
padding-top: 10px;
@ -99,16 +103,9 @@
background: var(--control-bg);
}
.icon::before {
display: inline-block;
width: 16px;
text-align: center;
vertical-align: middle;
}
&.selected {
.SelectTagListItem-checkIcon {
display: inline-block;
display: inline-flex;
color: var(--muted-color);
font-size: 14px;
}
@ -123,10 +120,12 @@
}
.SelectTagListItem-icon {
position: relative;
display: inline-block;
vertical-align: top;
margin-top: 3px;
display: inline-flex;
align-items: center;
justify-content: center;
margin-left: 0;
height: 16px;
width: 16px;
}
.SelectTagListItem-name {
display: inline-block;

View File

@ -44,7 +44,7 @@
opacity: 1;
}
@media @tablet-up {
.IndexPage, .UserPage {
.IndexPage, .UserPage, .DiscussionList--floatingTags {
.DiscussionListItem-title {
margin-right: 155px;
}

View File

@ -69,11 +69,7 @@ export default class AdminApplication extends Application {
* @internal
*/
registry: AdminRegistry;
extensionCategories: {
feature: number;
theme: number;
language: number;
};
extensionCategories: Record<string, number>;
history: IHistory;
search: SearchManager<SearchState>;
/**

View File

@ -1,6 +1,7 @@
/// <reference types="mithril" />
import SettingsModal from './SettingsModal';
import SettingsModal, { type ISettingsModalAttrs } from './SettingsModal';
import Mithril from 'mithril';
export default class EditCustomCssModal extends SettingsModal {
oninit(vnode: Mithril.Vnode<ISettingsModalAttrs, this>): void;
className(): string;
title(): string | any[];
form(): JSX.Element[];

View File

@ -10,6 +10,7 @@
* - `placeholder`
* - `disabled`
* - `preview`
* - `onTextEditorBuilt`
*/
export default class TextEditor extends Component<import("../Component").ComponentAttrs, undefined> {
constructor();

View File

@ -19,8 +19,11 @@ export default class Composer extends Component<import("../../common/Component")
*/
active: boolean | undefined;
prevPosition: any;
textEditorBuilt: boolean | undefined;
view(): JSX.Element;
onupdate(vnode: any): void;
onTextEditorBuilt(): void;
updateContainer(): void;
oncreate(vnode: any): void;
handlers: {} | undefined;
onremove(vnode: any): void;

View File

@ -10,6 +10,7 @@ export interface IComposerBodyAttrs extends ComponentAttrs {
user: any;
confirmExit: string;
disabled: boolean;
onTextEditorBuilt?: Function | null;
}
/**
* The `ComposerBody` component handles the body, or the content, of the

View File

@ -10,6 +10,7 @@
* - `titlePlaceholder`
*/
export default class DiscussionComposer extends ComposerBody<import("./ComposerBody").IComposerBodyAttrs> {
static focusOnSelector: () => string;
static initAttrs(attrs: any): void;
constructor();
oninit(vnode: any): void;

2
framework/core/js/dist/admin.js generated vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
framework/core/js/dist/forum.js generated vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
"use strict";(self.webpackChunkflarum_core=self.webpackChunkflarum_core||[]).push([[814],{6296:(s,e,t)=>{t.d(e,{A:()=>u});var o=t(8805),i=t(5710),r=t(43);class n extends i.A{handler(){return this.attrs.when()||void 0}oncreate(s){super.oncreate(s),this.boundHandler=this.handler.bind(this),$(window).on("beforeunload",this.boundHandler)}onremove(s){super.onremove(s),$(window).off("beforeunload",this.boundHandler)}view(s){return m("[",null,s.children)}}flarum.reg.add("core","common/components/ConfirmDocumentUnload",n);var a=t(1611),d=t(5673),l=t(6064),c=t(4268),h=t(7891);class u extends i.A{constructor(){super(...arguments),(0,o.A)(this,"loading",!1),(0,o.A)(this,"composer",void 0),(0,o.A)(this,"jumpToPreview",void 0)}oninit(s){super.oninit(s),this.composer=this.attrs.composer,this.attrs.confirmExit&&this.composer.preventClosingWhen((()=>this.hasChanges()),this.attrs.confirmExit),this.composer.fields.content(this.attrs.originalContent||"")}view(){return m(n,{when:this.hasChanges.bind(this)},m("div",{className:(0,c.A)("ComposerBody",this.attrs.className)},m(h.A,{user:this.attrs.user,className:"ComposerBody-avatar"}),m("div",{className:"ComposerBody-content"},m("ul",{className:"ComposerBody-header"},(0,d.A)(this.headerItems().toArray())),m("div",{className:"ComposerBody-editor"},m(a.A,{submitLabel:this.attrs.submitLabel,placeholder:this.attrs.placeholder,disabled:this.loading||this.attrs.disabled,composer:this.composer,preview:this.jumpToPreview?.bind(this),onchange:this.composer.fields.content,onsubmit:this.onsubmit.bind(this),value:this.composer.fields.content()}))),m(r.A,{display:"unset",containerClassName:(0,c.A)("ComposerBody-loading",this.loading&&"active"),size:"large"})))}hasChanges(){const s=this.composer.fields.content();return Boolean(s)&&s!==this.attrs.originalContent}headerItems(){return new l.A}loaded(){this.loading=!1,m.redraw()}}(0,o.A)(u,"focusOnSelector",null),flarum.reg.add("core","forum/components/ComposerBody",u)},1201:(s,e,t)=>{t.r(e),t.d(e,{default:()=>a});var o=t(3554),i=t(6296),r=t(117),n=t(4311);class a extends i.A{static initAttrs(s){super.initAttrs(s),s.placeholder=s.placeholder||(0,r.A)(o.A.translator.trans("core.forum.composer_discussion.body_placeholder")),s.submitLabel=s.submitLabel||o.A.translator.trans("core.forum.composer_discussion.submit_button"),s.confirmExit=s.confirmExit||(0,r.A)(o.A.translator.trans("core.forum.composer_discussion.discard_confirmation")),s.titlePlaceholder=s.titlePlaceholder||(0,r.A)(o.A.translator.trans("core.forum.composer_discussion.title_placeholder")),s.className="ComposerBody--discussion"}oninit(s){super.oninit(s),this.composer.fields.title=this.composer.fields.title||(0,n.A)(""),this.title=this.composer.fields.title}headerItems(){const s=super.headerItems();return s.add("title",m("h3",null,o.A.translator.trans("core.forum.composer_discussion.title")),100),s.add("discussionTitle",m("h3",null,m("input",{className:"FormControl",bidi:this.title,placeholder:this.attrs.titlePlaceholder,disabled:!!this.attrs.disabled,onkeydown:this.onkeydown.bind(this)}))),s}onkeydown(s){13===s.which&&(s.preventDefault(),this.composer.editor.moveCursorTo(0)),s.redraw=!1}hasChanges(){return this.title()||this.composer.fields.content()}data(){return{title:this.title(),content:this.composer.fields.content()}}onsubmit(){this.loading=!0;const s=this.data();o.A.store.createRecord("discussions").save(s).then((s=>{this.composer.hide(),o.A.discussions.refresh(),m.route.set(o.A.route.discussion(s))}),this.loaded.bind(this))}}flarum.reg.add("core","forum/components/DiscussionComposer",a)}}]);
"use strict";(self.webpackChunkflarum_core=self.webpackChunkflarum_core||[]).push([[814],{6296:(s,e,t)=>{t.d(e,{A:()=>u});var o=t(8805),i=t(5710),r=t(43);class n extends i.A{handler(){return this.attrs.when()||void 0}oncreate(s){super.oncreate(s),this.boundHandler=this.handler.bind(this),$(window).on("beforeunload",this.boundHandler)}onremove(s){super.onremove(s),$(window).off("beforeunload",this.boundHandler)}view(s){return m("[",null,s.children)}}flarum.reg.add("core","common/components/ConfirmDocumentUnload",n);var a=t(1611),d=t(5673),l=t(6064),c=t(4268),h=t(7891);class u extends i.A{constructor(){super(...arguments),(0,o.A)(this,"loading",!1),(0,o.A)(this,"composer",void 0),(0,o.A)(this,"jumpToPreview",void 0)}oninit(s){super.oninit(s),this.composer=this.attrs.composer,this.attrs.confirmExit&&this.composer.preventClosingWhen((()=>this.hasChanges()),this.attrs.confirmExit),this.composer.fields.content(this.attrs.originalContent||"")}view(){return m(n,{when:this.hasChanges.bind(this)},m("div",{className:(0,c.A)("ComposerBody",this.attrs.className)},m(h.A,{user:this.attrs.user,className:"ComposerBody-avatar"}),m("div",{className:"ComposerBody-content"},m("ul",{className:"ComposerBody-header"},(0,d.A)(this.headerItems().toArray())),m("div",{className:"ComposerBody-editor"},m(a.A,{submitLabel:this.attrs.submitLabel,placeholder:this.attrs.placeholder,disabled:this.loading||this.attrs.disabled,composer:this.composer,preview:this.jumpToPreview?.bind(this),onchange:this.composer.fields.content,onsubmit:this.onsubmit.bind(this),value:this.composer.fields.content(),onTextEditorBuilt:this.attrs.onTextEditorBuilt}))),m(r.A,{display:"unset",containerClassName:(0,c.A)("ComposerBody-loading",this.loading&&"active"),size:"large"})))}hasChanges(){const s=this.composer.fields.content();return Boolean(s)&&s!==this.attrs.originalContent}headerItems(){return new l.A}loaded(){this.loading=!1,m.redraw()}}(0,o.A)(u,"focusOnSelector",null),flarum.reg.add("core","forum/components/ComposerBody",u)},1201:(s,e,t)=>{t.r(e),t.d(e,{default:()=>d});var o=t(8805),i=t(3554),r=t(6296),n=t(117),a=t(4311);class d extends r.A{static initAttrs(s){super.initAttrs(s),s.placeholder=s.placeholder||(0,n.A)(i.A.translator.trans("core.forum.composer_discussion.body_placeholder")),s.submitLabel=s.submitLabel||i.A.translator.trans("core.forum.composer_discussion.submit_button"),s.confirmExit=s.confirmExit||(0,n.A)(i.A.translator.trans("core.forum.composer_discussion.discard_confirmation")),s.titlePlaceholder=s.titlePlaceholder||(0,n.A)(i.A.translator.trans("core.forum.composer_discussion.title_placeholder")),s.className="ComposerBody--discussion"}oninit(s){super.oninit(s),this.composer.fields.title=this.composer.fields.title||(0,a.A)(""),this.title=this.composer.fields.title}headerItems(){const s=super.headerItems();return s.add("title",m("h3",null,i.A.translator.trans("core.forum.composer_discussion.title")),100),s.add("discussionTitle",m("h3",null,m("input",{className:"FormControl DiscussionComposer-title",bidi:this.title,placeholder:this.attrs.titlePlaceholder,disabled:!!this.attrs.disabled,onkeydown:this.onkeydown.bind(this)}))),s}onkeydown(s){13===s.which&&(s.preventDefault(),this.composer.editor.moveCursorTo(0)),s.redraw=!1}hasChanges(){return this.title()||this.composer.fields.content()}data(){return{title:this.title(),content:this.composer.fields.content()}}onsubmit(){this.loading=!0;const s=this.data();i.A.store.createRecord("discussions").save(s).then((s=>{this.composer.hide(),i.A.discussions.refresh(),m.route.set(i.A.route.discussion(s))}),this.loaded.bind(this))}}(0,o.A)(d,"focusOnSelector",(()=>".DiscussionComposer-title")),flarum.reg.add("core","forum/components/DiscussionComposer",d)}}]);
//# sourceMappingURL=DiscussionComposer.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
"use strict";(self.webpackChunkflarum_core=self.webpackChunkflarum_core||[]).push([[948],{6296:(t,s,e)=>{e.d(s,{A:()=>h});var o=e(8805),r=e(5710),i=e(43);class n extends r.A{handler(){return this.attrs.when()||void 0}oncreate(t){super.oncreate(t),this.boundHandler=this.handler.bind(this),$(window).on("beforeunload",this.boundHandler)}onremove(t){super.onremove(t),$(window).off("beforeunload",this.boundHandler)}view(t){return m("[",null,t.children)}}flarum.reg.add("core","common/components/ConfirmDocumentUnload",n);var a=e(1611),c=e(5673),d=e(6064),l=e(4268),u=e(7891);class h extends r.A{constructor(){super(...arguments),(0,o.A)(this,"loading",!1),(0,o.A)(this,"composer",void 0),(0,o.A)(this,"jumpToPreview",void 0)}oninit(t){super.oninit(t),this.composer=this.attrs.composer,this.attrs.confirmExit&&this.composer.preventClosingWhen((()=>this.hasChanges()),this.attrs.confirmExit),this.composer.fields.content(this.attrs.originalContent||"")}view(){return m(n,{when:this.hasChanges.bind(this)},m("div",{className:(0,l.A)("ComposerBody",this.attrs.className)},m(u.A,{user:this.attrs.user,className:"ComposerBody-avatar"}),m("div",{className:"ComposerBody-content"},m("ul",{className:"ComposerBody-header"},(0,c.A)(this.headerItems().toArray())),m("div",{className:"ComposerBody-editor"},m(a.A,{submitLabel:this.attrs.submitLabel,placeholder:this.attrs.placeholder,disabled:this.loading||this.attrs.disabled,composer:this.composer,preview:this.jumpToPreview?.bind(this),onchange:this.composer.fields.content,onsubmit:this.onsubmit.bind(this),value:this.composer.fields.content()}))),m(i.A,{display:"unset",containerClassName:(0,l.A)("ComposerBody-loading",this.loading&&"active"),size:"large"})))}hasChanges(){const t=this.composer.fields.content();return Boolean(t)&&t!==this.attrs.originalContent}headerItems(){return new d.A}loaded(){this.loading=!1,m.redraw()}}(0,o.A)(h,"focusOnSelector",null),flarum.reg.add("core","forum/components/ComposerBody",h)},4191:(t,s,e)=>{e.r(s),e.d(s,{default:()=>d});var o=e(3554),r=e(6296),i=e(3092),n=e(7709),a=e(7479);function c(t){o.A.composer.isFullScreen()&&(o.A.composer.minimize(),t.stopPropagation())}class d extends r.A{static initAttrs(t){super.initAttrs(t),t.submitLabel=t.submitLabel||o.A.translator.trans("core.forum.composer_edit.submit_button"),t.confirmExit=t.confirmExit||o.A.translator.trans("core.forum.composer_edit.discard_confirmation"),t.originalContent=t.originalContent||t.post.content(),t.user=t.user||t.post.user(),t.post.editedContent=t.originalContent}headerItems(){const t=super.headerItems(),s=this.attrs.post;return t.add("title",m("h3",null,m(a.A,{name:"fas fa-pencil-alt"})," ",m(n.A,{href:o.A.route.discussion(s.discussion(),s.number()),onclick:c},o.A.translator.trans("core.forum.composer_edit.post_link",{number:s.number(),discussion:s.discussion().title()})))),t}jumpToPreview(t){c(t),m.route.set(o.A.route.post(this.attrs.post))}data(){return{content:this.composer.fields.content()}}onsubmit(){const t=this.attrs.post.discussion();this.loading=!0;const s=this.data();this.attrs.post.save(s).then((s=>{if(o.A.viewingDiscussion(t))o.A.current.get("stream").goToNumber(s.number());else{const t=o.A.alerts.show({type:"success",controls:[m(i.A,{className:"Button Button--link",onclick:()=>{m.route.set(o.A.route.post(s)),o.A.alerts.dismiss(t)}},o.A.translator.trans("core.forum.composer_edit.view_button"))]},o.A.translator.trans("core.forum.composer_edit.edited_message"))}this.composer.hide()}),this.loaded.bind(this))}}flarum.reg.add("core","forum/components/EditPostComposer",d)}}]);
"use strict";(self.webpackChunkflarum_core=self.webpackChunkflarum_core||[]).push([[948],{6296:(t,s,e)=>{e.d(s,{A:()=>h});var o=e(8805),r=e(5710),i=e(43);class n extends r.A{handler(){return this.attrs.when()||void 0}oncreate(t){super.oncreate(t),this.boundHandler=this.handler.bind(this),$(window).on("beforeunload",this.boundHandler)}onremove(t){super.onremove(t),$(window).off("beforeunload",this.boundHandler)}view(t){return m("[",null,t.children)}}flarum.reg.add("core","common/components/ConfirmDocumentUnload",n);var a=e(1611),d=e(5673),c=e(6064),l=e(4268),u=e(7891);class h extends r.A{constructor(){super(...arguments),(0,o.A)(this,"loading",!1),(0,o.A)(this,"composer",void 0),(0,o.A)(this,"jumpToPreview",void 0)}oninit(t){super.oninit(t),this.composer=this.attrs.composer,this.attrs.confirmExit&&this.composer.preventClosingWhen((()=>this.hasChanges()),this.attrs.confirmExit),this.composer.fields.content(this.attrs.originalContent||"")}view(){return m(n,{when:this.hasChanges.bind(this)},m("div",{className:(0,l.A)("ComposerBody",this.attrs.className)},m(u.A,{user:this.attrs.user,className:"ComposerBody-avatar"}),m("div",{className:"ComposerBody-content"},m("ul",{className:"ComposerBody-header"},(0,d.A)(this.headerItems().toArray())),m("div",{className:"ComposerBody-editor"},m(a.A,{submitLabel:this.attrs.submitLabel,placeholder:this.attrs.placeholder,disabled:this.loading||this.attrs.disabled,composer:this.composer,preview:this.jumpToPreview?.bind(this),onchange:this.composer.fields.content,onsubmit:this.onsubmit.bind(this),value:this.composer.fields.content(),onTextEditorBuilt:this.attrs.onTextEditorBuilt}))),m(i.A,{display:"unset",containerClassName:(0,l.A)("ComposerBody-loading",this.loading&&"active"),size:"large"})))}hasChanges(){const t=this.composer.fields.content();return Boolean(t)&&t!==this.attrs.originalContent}headerItems(){return new c.A}loaded(){this.loading=!1,m.redraw()}}(0,o.A)(h,"focusOnSelector",null),flarum.reg.add("core","forum/components/ComposerBody",h)},4191:(t,s,e)=>{e.r(s),e.d(s,{default:()=>c});var o=e(3554),r=e(6296),i=e(3092),n=e(7709),a=e(7479);function d(t){o.A.composer.isFullScreen()&&(o.A.composer.minimize(),t.stopPropagation())}class c extends r.A{static initAttrs(t){super.initAttrs(t),t.submitLabel=t.submitLabel||o.A.translator.trans("core.forum.composer_edit.submit_button"),t.confirmExit=t.confirmExit||o.A.translator.trans("core.forum.composer_edit.discard_confirmation"),t.originalContent=t.originalContent||t.post.content(),t.user=t.user||t.post.user(),t.post.editedContent=t.originalContent}headerItems(){const t=super.headerItems(),s=this.attrs.post;return t.add("title",m("h3",null,m(a.A,{name:"fas fa-pencil-alt"})," ",m(n.A,{href:o.A.route.discussion(s.discussion(),s.number()),onclick:d},o.A.translator.trans("core.forum.composer_edit.post_link",{number:s.number(),discussion:s.discussion().title()})))),t}jumpToPreview(t){d(t),m.route.set(o.A.route.post(this.attrs.post))}data(){return{content:this.composer.fields.content()}}onsubmit(){const t=this.attrs.post.discussion();this.loading=!0;const s=this.data();this.attrs.post.save(s).then((s=>{if(o.A.viewingDiscussion(t))o.A.current.get("stream").goToNumber(s.number());else{const t=o.A.alerts.show({type:"success",controls:[m(i.A,{className:"Button Button--link",onclick:()=>{m.route.set(o.A.route.post(s)),o.A.alerts.dismiss(t)}},o.A.translator.trans("core.forum.composer_edit.view_button"))]},o.A.translator.trans("core.forum.composer_edit.edited_message"))}this.composer.hide()}),this.loaded.bind(this))}}flarum.reg.add("core","forum/components/EditPostComposer",c)}}]);
//# sourceMappingURL=EditPostComposer.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
"use strict";(self.webpackChunkflarum_core=self.webpackChunkflarum_core||[]).push([[378],{6296:(s,e,t)=>{t.d(e,{A:()=>h});var o=t(8805),r=t(5710),i=t(43);class n extends r.A{handler(){return this.attrs.when()||void 0}oncreate(s){super.oncreate(s),this.boundHandler=this.handler.bind(this),$(window).on("beforeunload",this.boundHandler)}onremove(s){super.onremove(s),$(window).off("beforeunload",this.boundHandler)}view(s){return m("[",null,s.children)}}flarum.reg.add("core","common/components/ConfirmDocumentUnload",n);var a=t(1611),c=t(5673),l=t(6064),d=t(4268),u=t(7891);class h extends r.A{constructor(){super(...arguments),(0,o.A)(this,"loading",!1),(0,o.A)(this,"composer",void 0),(0,o.A)(this,"jumpToPreview",void 0)}oninit(s){super.oninit(s),this.composer=this.attrs.composer,this.attrs.confirmExit&&this.composer.preventClosingWhen((()=>this.hasChanges()),this.attrs.confirmExit),this.composer.fields.content(this.attrs.originalContent||"")}view(){return m(n,{when:this.hasChanges.bind(this)},m("div",{className:(0,d.A)("ComposerBody",this.attrs.className)},m(u.A,{user:this.attrs.user,className:"ComposerBody-avatar"}),m("div",{className:"ComposerBody-content"},m("ul",{className:"ComposerBody-header"},(0,c.A)(this.headerItems().toArray())),m("div",{className:"ComposerBody-editor"},m(a.A,{submitLabel:this.attrs.submitLabel,placeholder:this.attrs.placeholder,disabled:this.loading||this.attrs.disabled,composer:this.composer,preview:this.jumpToPreview?.bind(this),onchange:this.composer.fields.content,onsubmit:this.onsubmit.bind(this),value:this.composer.fields.content()}))),m(i.A,{display:"unset",containerClassName:(0,d.A)("ComposerBody-loading",this.loading&&"active"),size:"large"})))}hasChanges(){const s=this.composer.fields.content();return Boolean(s)&&s!==this.attrs.originalContent}headerItems(){return new l.A}loaded(){this.loading=!1,m.redraw()}}(0,o.A)(h,"focusOnSelector",null),flarum.reg.add("core","forum/components/ComposerBody",h)},6349:(s,e,t)=>{t.r(e),t.d(e,{default:()=>d});var o=t(3554),r=t(6296),i=t(3092),n=t(7709),a=t(117),c=t(7479);function l(s){o.A.composer.isFullScreen()&&(o.A.composer.minimize(),s.stopPropagation())}class d extends r.A{static initAttrs(s){super.initAttrs(s),s.placeholder=s.placeholder||(0,a.A)(o.A.translator.trans("core.forum.composer_reply.body_placeholder")),s.submitLabel=s.submitLabel||o.A.translator.trans("core.forum.composer_reply.submit_button"),s.confirmExit=s.confirmExit||(0,a.A)(o.A.translator.trans("core.forum.composer_reply.discard_confirmation"))}headerItems(){const s=super.headerItems(),e=this.attrs.discussion;return s.add("title",m("h3",null,m(c.A,{name:"fas fa-reply"})," ",m(n.A,{href:o.A.route.discussion(e),onclick:l},e.title()))),s}jumpToPreview(s){l(s),m.route.set(o.A.route.discussion(this.attrs.discussion,"reply"))}data(){return{content:this.composer.fields.content(),relationships:{discussion:this.attrs.discussion}}}onsubmit(){const s=this.attrs.discussion;this.loading=!0,m.redraw();const e=this.data();o.A.store.createRecord("posts").save(e).then((e=>{if(o.A.viewingDiscussion(s)){const s=o.A.current.get("stream");s.update().then((()=>s.goToNumber(e.number())))}else{let s;const t=m(i.A,{className:"Button Button--link",onclick:()=>{m.route.set(o.A.route.post(e)),o.A.alerts.dismiss(s)}},o.A.translator.trans("core.forum.composer_reply.view_button"));s=o.A.alerts.show({type:"success",controls:[t]},o.A.translator.trans("core.forum.composer_reply.posted_message"))}this.composer.hide()}),this.loaded.bind(this))}}flarum.reg.add("core","forum/components/ReplyComposer",d)}}]);
"use strict";(self.webpackChunkflarum_core=self.webpackChunkflarum_core||[]).push([[378],{6296:(s,e,t)=>{t.d(e,{A:()=>h});var o=t(8805),r=t(5710),i=t(43);class n extends r.A{handler(){return this.attrs.when()||void 0}oncreate(s){super.oncreate(s),this.boundHandler=this.handler.bind(this),$(window).on("beforeunload",this.boundHandler)}onremove(s){super.onremove(s),$(window).off("beforeunload",this.boundHandler)}view(s){return m("[",null,s.children)}}flarum.reg.add("core","common/components/ConfirmDocumentUnload",n);var a=t(1611),c=t(5673),l=t(6064),d=t(4268),u=t(7891);class h extends r.A{constructor(){super(...arguments),(0,o.A)(this,"loading",!1),(0,o.A)(this,"composer",void 0),(0,o.A)(this,"jumpToPreview",void 0)}oninit(s){super.oninit(s),this.composer=this.attrs.composer,this.attrs.confirmExit&&this.composer.preventClosingWhen((()=>this.hasChanges()),this.attrs.confirmExit),this.composer.fields.content(this.attrs.originalContent||"")}view(){return m(n,{when:this.hasChanges.bind(this)},m("div",{className:(0,d.A)("ComposerBody",this.attrs.className)},m(u.A,{user:this.attrs.user,className:"ComposerBody-avatar"}),m("div",{className:"ComposerBody-content"},m("ul",{className:"ComposerBody-header"},(0,c.A)(this.headerItems().toArray())),m("div",{className:"ComposerBody-editor"},m(a.A,{submitLabel:this.attrs.submitLabel,placeholder:this.attrs.placeholder,disabled:this.loading||this.attrs.disabled,composer:this.composer,preview:this.jumpToPreview?.bind(this),onchange:this.composer.fields.content,onsubmit:this.onsubmit.bind(this),value:this.composer.fields.content(),onTextEditorBuilt:this.attrs.onTextEditorBuilt}))),m(i.A,{display:"unset",containerClassName:(0,d.A)("ComposerBody-loading",this.loading&&"active"),size:"large"})))}hasChanges(){const s=this.composer.fields.content();return Boolean(s)&&s!==this.attrs.originalContent}headerItems(){return new l.A}loaded(){this.loading=!1,m.redraw()}}(0,o.A)(h,"focusOnSelector",null),flarum.reg.add("core","forum/components/ComposerBody",h)},6349:(s,e,t)=>{t.r(e),t.d(e,{default:()=>d});var o=t(3554),r=t(6296),i=t(3092),n=t(7709),a=t(117),c=t(7479);function l(s){o.A.composer.isFullScreen()&&(o.A.composer.minimize(),s.stopPropagation())}class d extends r.A{static initAttrs(s){super.initAttrs(s),s.placeholder=s.placeholder||(0,a.A)(o.A.translator.trans("core.forum.composer_reply.body_placeholder")),s.submitLabel=s.submitLabel||o.A.translator.trans("core.forum.composer_reply.submit_button"),s.confirmExit=s.confirmExit||(0,a.A)(o.A.translator.trans("core.forum.composer_reply.discard_confirmation"))}headerItems(){const s=super.headerItems(),e=this.attrs.discussion;return s.add("title",m("h3",null,m(c.A,{name:"fas fa-reply"})," ",m(n.A,{href:o.A.route.discussion(e),onclick:l},e.title()))),s}jumpToPreview(s){l(s),m.route.set(o.A.route.discussion(this.attrs.discussion,"reply"))}data(){return{content:this.composer.fields.content(),relationships:{discussion:this.attrs.discussion}}}onsubmit(){const s=this.attrs.discussion;this.loading=!0,m.redraw();const e=this.data();o.A.store.createRecord("posts").save(e).then((e=>{if(o.A.viewingDiscussion(s)){const s=o.A.current.get("stream");s.update().then((()=>s.goToNumber(e.number())))}else{let s;const t=m(i.A,{className:"Button Button--link",onclick:()=>{m.route.set(o.A.route.post(e)),o.A.alerts.dismiss(s)}},o.A.translator.trans("core.forum.composer_reply.view_button"));s=o.A.alerts.show({type:"success",controls:[t]},o.A.translator.trans("core.forum.composer_reply.posted_message"))}this.composer.hide()}),this.loaded.bind(this))}}flarum.reg.add("core","forum/components/ReplyComposer",d)}}]);
//# sourceMappingURL=ReplyComposer.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
"use strict";(self.webpackChunkflarum_core=self.webpackChunkflarum_core||[]).push([[559],{9509:(t,s,e)=>{e.r(s),e.d(s,{default:()=>h});var a=e(8805),r=e(3554),i=e(2855),o=e(3092),n=e(1005),l=e(117),d=e(6064),u=e(4311);class h extends i.A{constructor(){super(...arguments),(0,a.A)(this,"username",void 0),(0,a.A)(this,"email",void 0),(0,a.A)(this,"password",void 0)}oninit(t){super.oninit(t),this.username=(0,u.A)(this.attrs.username||""),this.email=(0,u.A)(this.attrs.email||""),this.password=(0,u.A)(this.attrs.password||"")}className(){return"Modal--small SignUpModal"}title(){return r.A.translator.trans("core.forum.sign_up.title")}content(){return[m("div",{className:"Modal-body"},this.body()),m("div",{className:"Modal-footer"},this.footer())]}isProvided(t){return this.attrs.provided?.includes(t)??!1}body(){return[!this.attrs.token&&m(n.A,null),m("div",{className:"Form Form--centered"},this.fields().toArray())]}fields(){const t=new d.A,s=(0,l.A)(r.A.translator.trans("core.forum.sign_up.username_placeholder")),e=(0,l.A)(r.A.translator.trans("core.forum.sign_up.email_placeholder")),a=(0,l.A)(r.A.translator.trans("core.forum.sign_up.password_placeholder"));return t.add("username",m("div",{className:"Form-group"},m("input",{className:"FormControl",name:"username",type:"text",placeholder:s,"aria-label":s,bidi:this.username,disabled:this.loading||this.isProvided("username")})),30),t.add("email",m("div",{className:"Form-group"},m("input",{className:"FormControl",name:"email",type:"email",placeholder:e,"aria-label":e,bidi:this.email,disabled:this.loading||this.isProvided("email")})),20),this.attrs.token||t.add("password",m("div",{className:"Form-group"},m("input",{className:"FormControl",name:"password",type:"password",autocomplete:"new-password",placeholder:a,"aria-label":a,bidi:this.password,disabled:this.loading})),10),t.add("submit",m("div",{className:"Form-group"},m(o.A,{className:"Button Button--primary Button--block",type:"submit",loading:this.loading},r.A.translator.trans("core.forum.sign_up.submit_button"))),-10),t}footer(){return[m("p",{className:"SignUpModal-logIn"},r.A.translator.trans("core.forum.sign_up.log_in_text",{a:m(o.A,{className:"Button Button--text Button--link",onclick:this.logIn.bind(this)})}))]}logIn(){const t={identification:this.email()||this.username()};r.A.modal.show((()=>e.e(226).then(e.bind(e,1793))),t)}onready(){this.attrs.username&&!this.attrs.email?this.$("[name=email]").select():this.$("[name=username]").select()}onsubmit(t){t.preventDefault(),this.loading=!0;const s=this.submitData();r.A.request({url:r.A.forum.attribute("baseUrl")+"/register",method:"POST",body:s,errorHandler:this.onerror.bind(this)}).then((()=>window.location.reload()),this.loaded.bind(this))}submitData(){const t=this.attrs.token?{token:this.attrs.token}:{password:this.password()};return{username:this.username(),email:this.email(),...t}}}flarum.reg.add("core","forum/components/SignUpModal",h)}}]);
"use strict";(self.webpackChunkflarum_core=self.webpackChunkflarum_core||[]).push([[559],{9509:(s,t,e)=>{e.r(t),e.d(t,{default:()=>h});var a=e(8805),r=e(3554),o=e(2855),i=e(3092),n=e(1005),l=e(117),d=e(6064),u=e(4311);class h extends o.A{constructor(){super(...arguments),(0,a.A)(this,"username",void 0),(0,a.A)(this,"email",void 0),(0,a.A)(this,"password",void 0)}oninit(s){super.oninit(s),this.username=(0,u.A)(this.attrs.username||""),this.email=(0,u.A)(this.attrs.email||""),this.password=(0,u.A)(this.attrs.password||"")}className(){return"Modal--small SignUpModal"}title(){return r.A.translator.trans("core.forum.sign_up.title")}content(){return[m("div",{className:"Modal-body"},this.body()),m("div",{className:"Modal-footer"},this.footer())]}isProvided(s){return this.attrs.provided?.includes(s)??!1}body(){return[!this.attrs.token&&m(n.A,null),m("div",{className:"Form Form--centered"},this.fields().toArray())]}fields(){const s=new d.A,t=(0,l.A)(r.A.translator.trans("core.forum.sign_up.username_placeholder")),e=(0,l.A)(r.A.translator.trans("core.forum.sign_up.email_placeholder")),a=(0,l.A)(r.A.translator.trans("core.forum.sign_up.password_placeholder"));return s.add("username",m("div",{className:"Form-group"},m("input",{className:"FormControl",name:"username",type:"text",placeholder:t,"aria-label":t,bidi:this.username,disabled:this.loading||this.isProvided("username")})),30),s.add("email",m("div",{className:"Form-group"},m("input",{className:"FormControl",name:"email",type:"email",placeholder:e,"aria-label":e,bidi:this.email,disabled:this.loading||this.isProvided("email")})),20),this.attrs.token||s.add("password",m("div",{className:"Form-group"},m("input",{className:"FormControl",name:"password",type:"password",autocomplete:"new-password",placeholder:a,"aria-label":a,bidi:this.password,disabled:this.loading})),10),s.add("submit",m("div",{className:"Form-group"},m(i.A,{className:"Button Button--primary Button--block",type:"submit",loading:this.loading},r.A.translator.trans("core.forum.sign_up.submit_button"))),-10),s}footer(){return[m("p",{className:"SignUpModal-logIn"},r.A.translator.trans("core.forum.sign_up.log_in_text",{a:m(i.A,{className:"Button Button--text Button--link",onclick:this.logIn.bind(this)})}))]}logIn(){const s={identification:this.email()||this.username()};r.A.modal.show((()=>e.e(226).then(e.bind(e,1793))),s)}onready(){this.attrs.username&&!this.attrs.email?this.$("[name=email]").select():this.$("[name=username]").select()}onsubmit(s){s.preventDefault(),this.loading=!0;const t=this.submitData();r.A.request({url:r.A.forum.attribute("baseUrl")+"/register",method:"POST",body:t,errorHandler:this.onerror.bind(this)}).then((()=>window.location.reload()),this.loaded.bind(this))}submitData(){const s=this.attrs.token?{token:this.attrs.token}:{password:this.password()};return{username:this.username(),email:this.email(),...s}}}flarum.reg.add("core","forum/components/SignUpModal",h),flarum.reg.addChunkModule("226","1793","core","forum/components/LogInModal"),flarum.reg.addChunkModule("226","1793","core","forum/components/ForgotPasswordModal")}}]);
//# sourceMappingURL=SignUpModal.js.map

File diff suppressed because one or more lines are too long

View File

@ -83,7 +83,7 @@ export default class AdminApplication extends Application {
*/
registry = new AdminRegistry();
extensionCategories = {
extensionCategories: Record<string, number> = {
feature: 30,
theme: 20,
language: 10,

View File

@ -1,7 +1,19 @@
import app from '../../admin/app';
import SettingsModal from './SettingsModal';
import SettingsModal, { type ISettingsModalAttrs } from './SettingsModal';
import Mithril from 'mithril';
export default class EditCustomCssModal extends SettingsModal {
oninit(vnode: Mithril.Vnode<ISettingsModalAttrs, this>) {
super.oninit(vnode);
if (this.setting('custom_less_error')()) {
this.alertAttrs = {
type: 'error',
content: this.setting('custom_less_error')(),
};
}
}
className() {
return 'EditCustomCssModal TextareaCodeModal Modal--large';
}

View File

@ -211,7 +211,16 @@ export default class ExportRegistry implements IExportRegistry, IChunkRegistry {
// @ts-ignore
const wr = this._webpack_runtimes[namespace] ?? __webpack_require__;
return await wr.e(module.chunkId).then(wr.bind(wr, module.moduleId));
return await wr
.e(module.chunkId)
.then(wr.bind(wr, module.moduleId))
.then(() => {
const m = this.get(namespace, id);
m.default ??= m;
return m;
});
}
public clear(): void {

View File

@ -48,8 +48,8 @@ export default class Input<CustomAttrs extends IInputAttrs = IInputAttrs> extend
>
{this.attrs.prefixIcon && <Icon name={classList(this.attrs.prefixIcon, 'Input-prefix-icon')} />}
{this.input({ inputClassName, value, inputAttrs })}
{this.attrs.loading && <LoadingIndicator size="small" display="inline" containerClassName="Button Button--icon Button--link" />}
{this.attrs.clearable && value && !this.attrs.loading && (
{this.attrs.loading ? <LoadingIndicator size="small" display="inline" containerClassName="Button Button--icon Button--link" /> : null}
{this.attrs.clearable && value && !this.attrs.loading ? (
<Button
className="Input-clear Button Button--icon Button--link"
onclick={this.clear.bind(this)}
@ -57,7 +57,7 @@ export default class Input<CustomAttrs extends IInputAttrs = IInputAttrs> extend
type="button"
icon="fas fa-times-circle"
/>
)}
) : null}
</div>
);
}

View File

@ -21,6 +21,7 @@ import LoadingIndicator from './LoadingIndicator';
* - `placeholder`
* - `disabled`
* - `preview`
* - `onTextEditorBuilt`
*/
export default class TextEditor extends Component {
oninit(vnode) {
@ -78,6 +79,7 @@ export default class TextEditor extends Component {
onbuild() {
this.attrs.composer.editor = this.buildEditor(this.$('.TextEditor-editorContainer')[0]);
this.attrs.onTextEditorBuilt?.();
}
onupdate(vnode) {

View File

@ -24,7 +24,7 @@ export default function humanTime(time: dayjs.ConfigType): string {
if (d.isSame(now, 'year')) {
ago = app.translator.formatDateTime(d, 'core.lib.datetime_formats.humanTimeShort');
} else {
ago = app.translator.formatDateTime(d, 'core.lib.datetime_formats.humanTimeFull');
ago = app.translator.formatDateTime(d, 'core.lib.datetime_formats.humanTimeLong');
}
} else {
ago = d.fromNow();

View File

@ -31,6 +31,8 @@ export default class Composer extends Component {
// Store the initial position so that we can trigger animations correctly.
this.prevPosition = this.state.position;
this.textEditorBuilt = false;
}
view() {
@ -53,7 +55,9 @@ export default class Composer extends Component {
<div className="Composer-handle" oncreate={this.configHandle.bind(this)} />
<ul className="Composer-controls">{listItems(this.controlItems().toArray())}</ul>
<div className="Composer-content" onclick={showIfMinimized}>
{ComposerBody && <ComposerBody {...body.attrs} composer={this.state} disabled={classes.minimized} />}
{ComposerBody && (
<ComposerBody {...body.attrs} composer={this.state} disabled={classes.minimized} onTextEditorBuilt={this.onTextEditorBuilt.bind(this)} />
)}
</div>
</div>
);
@ -62,6 +66,17 @@ export default class Composer extends Component {
onupdate(vnode) {
super.onupdate(vnode);
if (this.textEditorBuilt) {
this.updateContainer();
}
}
onTextEditorBuilt() {
this.updateContainer();
this.textEditorBuilt = true;
}
updateContainer() {
if (this.state.position === this.prevPosition) {
// Set the height of the Composer element and its contents on each redraw,
// so that they do not lose it if their DOM elements are recreated.

View File

@ -17,6 +17,7 @@ export interface IComposerBodyAttrs extends ComponentAttrs {
user: any;
confirmExit: string;
disabled: boolean;
onTextEditorBuilt?: Function | null;
}
/**
@ -63,6 +64,7 @@ export default abstract class ComposerBody<CustomAttrs extends IComposerBodyAttr
onchange={this.composer.fields!.content}
onsubmit={this.onsubmit.bind(this)}
value={this.composer.fields!.content()}
onTextEditorBuilt={this.attrs.onTextEditorBuilt}
/>
</div>
</div>

View File

@ -15,6 +15,8 @@ import Stream from '../../common/utils/Stream';
* - `titlePlaceholder`
*/
export default class DiscussionComposer extends ComposerBody {
static focusOnSelector = () => '.DiscussionComposer-title';
static initAttrs(attrs) {
super.initAttrs(attrs);
@ -47,7 +49,7 @@ export default class DiscussionComposer extends ComposerBody {
'discussionTitle',
<h3>
<input
className="FormControl"
className="FormControl DiscussionComposer-title"
bidi={this.title}
placeholder={this.attrs.titlePlaceholder}
disabled={!!this.attrs.disabled}

View File

@ -84,6 +84,10 @@ export default class DiscussionPage<CustomAttrs extends IDiscussionPageAttrs = I
}
view() {
if (this.loading || !this.discussion) {
return <LoadingIndicator />;
}
return (
<PageStructure
className="DiscussionPage"
@ -165,40 +169,13 @@ export default class DiscussionPage<CustomAttrs extends IDiscussionPageAttrs = I
app.setTitle(discussion.title());
app.setTitleCount(0);
// When the API responds with a discussion, it will also include a number of
// posts. Some of these posts are included because they are on the first
// page of posts we want to display (determined by the `near` parameter) –
// others may be included because due to other relationships introduced by
// extensions. We need to distinguish the two so we don't end up displaying
// the wrong posts. We do so by filtering out the posts that don't have
// the 'discussion' relationship linked, then sorting and splicing.
let includedPosts: Post[] = [];
if (discussion.payload && discussion.payload.included) {
const discussionId = discussion.id();
includedPosts = discussion.payload.included
.filter(
(record) =>
record.type === 'posts' &&
record.relationships &&
record.relationships.discussion &&
!Array.isArray(record.relationships.discussion.data) &&
record.relationships.discussion.data.id === discussionId
)
// We can make this assertion because posts should be in the store,
// since they were in the discussion's payload.
.map((record) => app.store.getById<Post>('posts', record.id) as Post)
.sort((a: Post, b: Post) => a.number() - b.number())
.slice(0, 20);
}
// Set up the post stream for this discussion, along with the first page of
// posts we want to display. Tell the stream to scroll down and highlight
// the specific post that was routed to.
this.stream = new PostStreamState(discussion, includedPosts);
this.stream = new PostStreamState(discussion);
const rawNearParam = m.route.param('near');
const nearParam = rawNearParam === 'reply' ? 'reply' : parseInt(rawNearParam);
this.stream.goToNumber(nearParam || (includedPosts[0]?.number() ?? 0), true).then(() => {
this.stream.goToNumber(nearParam || 0, true).then(() => {
this.discussion = discussion;
app.current.set('discussion', discussion);

View File

@ -70,5 +70,6 @@
}
.Badge--success {
--badge-bg: var(--success-color);
--badge-color: var(--control-success-color);
--badge-bg: var(--control-success-bg);
}

View File

@ -82,6 +82,9 @@
.Alert {
border-radius: 0;
}
.Alert-container {
flex-direction: column;
}
.Alert-controls {
margin: 0;
display: block;

View File

@ -11,7 +11,7 @@
cursor: pointer;
line-height: 1;
.FormSection &, &.FormControl {
.FormSection & {
width: 100%;
}
}

View File

@ -64,6 +64,7 @@
> ul {
&.affix {
top: var(--header-height);
margin-top: 30px;
}
> li {
margin-bottom: 10px;

View File

@ -5,6 +5,12 @@
margin-right: 12px;
}
@media @tablet-up {
[data-colored-header=true] &, [data-colored-header=true] & a {
color: var(--text-color);
}
}
&-header, &-footer {
@media @tablet-up {
padding: 12px 15px;

View File

@ -123,8 +123,9 @@ class PostResource extends AbstractDatabaseResource
Endpoint\Index::make()
->extractOffset(function (Context $context, array $defaultExtracts): int {
$queryParams = $context->request->getQueryParams();
$near = intval(Arr::get($queryParams, 'page.near'));
if (($near = Arr::get($queryParams, 'page.near')) > 1) {
if ($near > 1) {
$sort = $defaultExtracts['sort'];
$filter = $defaultExtracts['filter'];

View File

@ -121,6 +121,10 @@ class Discussion extends AbstractModel
{
$discussion = $model ?? new static;
if ($title) {
$discussion->title = $title;
}
$discussion->created_at = Carbon::now();
$discussion->user_id = $user->id;

View File

@ -133,7 +133,7 @@ class ForumServiceProvider extends AbstractServiceProvider
$sources->addFile(__DIR__.'/../../less/forum.less');
$sources->addString(function () use ($container) {
return $container->make(SettingsRepositoryInterface::class)->get('custom_less', '');
});
}, 'custom_less');
});
$container->make(AddTranslations::class)->forFrontend('forum')->to($assets);
@ -195,7 +195,8 @@ class ForumServiceProvider extends AbstractServiceProvider
$container->make('flarum.assets.forum'),
$container->make('flarum.locales'),
$container,
$container->make('flarum.less.config')
$container->make(SettingsRepositoryInterface::class),
$container->make('flarum.less.config'),
);
$validator->whenSettingsSaved($event);
}
@ -208,7 +209,8 @@ class ForumServiceProvider extends AbstractServiceProvider
$container->make('flarum.assets.forum'),
$container->make('flarum.locales'),
$container,
$container->make('flarum.less.config')
$container->make(SettingsRepositoryInterface::class),
$container->make('flarum.less.config'),
);
$validator->whenSettingsSaving($event);
}

View File

@ -32,7 +32,8 @@ class ValidateCustomLess
protected Assets $assets,
protected LocaleManager $locales,
protected Container $container,
protected array $customLessSettings = []
protected SettingsRepositoryInterface $settings,
protected array $customLessSettings = [],
) {
}
@ -72,6 +73,8 @@ class ValidateCustomLess
$adapter = new InMemoryFilesystemAdapter();
$this->assets->setAssetsDir(new FilesystemAdapter(new Filesystem($adapter), $adapter));
$this->settings->delete('custom_less_error');
try {
$this->assets->makeCss()->commit();
@ -82,6 +85,10 @@ class ValidateCustomLess
throw new ValidationException(['custom_less' => $e->getMessage()]);
}
if (! empty($this->settings->get('custom_less_error'))) {
throw new ValidationException(['custom_less' => $this->settings->get('custom_less_error')]);
}
$this->assets->setAssetsDir($assetsDir);
$this->container->instance(SettingsRepositoryInterface::class, $settings);
}

View File

@ -25,7 +25,7 @@ class Application extends IlluminateContainer implements LaravelApplication
*
* @var string
*/
const VERSION = '2.0.0-beta.1';
const VERSION = '2.0.0-beta.2';
protected bool $booted = false;

View File

@ -12,6 +12,7 @@ namespace Flarum\Frontend\Compiler;
use Flarum\Frontend\Compiler\Source\FileSource;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Less_Exception_Compiler;
use Less_FileManager;
use Less_Parser;
use Less_Tree_Import;
@ -71,6 +72,10 @@ class LessCompiler extends RevisionCompiler
return '';
}
if (! empty($this->settings->get('custom_less_error'))) {
unset($sources['custom_less']);
}
ini_set('xdebug.max_nesting_level', '200');
$parser = new Less_Parser([
@ -96,7 +101,27 @@ class LessCompiler extends RevisionCompiler
$parser->registerFunction($name, $callback);
}
return $this->finalize($parser->getCss());
try {
$compiled = $this->finalize($parser->getCss());
if (isset($sources['custom_less'])) {
$this->settings->delete('custom_less_error');
}
return $compiled;
} catch (Less_Exception_Compiler $e) {
if (isset($sources['custom_less'])) {
unset($sources['custom_less']);
$compiled = $this->compile($sources);
$this->settings->set('custom_less_error', $e->getMessage());
return $compiled;
}
throw $e;
}
}
protected function finalize(string $parsedCss): string

View File

@ -13,6 +13,7 @@ use Flarum\Frontend\Compiler\Concerns\HasSources;
use Flarum\Frontend\Compiler\Source\FileSource;
use Flarum\Frontend\Compiler\Source\SourceInterface;
use Flarum\Frontend\Compiler\Source\StringSource;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Filesystem\Cloud;
/**
@ -29,6 +30,7 @@ class RevisionCompiler implements CompilerInterface
public function __construct(
protected Cloud $assetsDir,
protected string $filename,
protected SettingsRepositoryInterface $settings
) {
$this->versioner = new FileVersioner($assetsDir);
}

View File

@ -35,12 +35,18 @@ class SourceCollector
return $this;
}
public function addString(Closure $callback): static
public function addString(Closure $callback, ?string $key = null): static
{
$this->sources[] = $this->validateSourceType(
$source = $this->validateSourceType(
new StringSource($callback)
);
if (! empty($key)) {
$this->sources[$key] = $source;
} else {
$this->sources[] = $source;
}
return $this;
}

View File

@ -1,7 +1,7 @@
{
"name": "flarum-webpack-config",
"type": "module",
"version": "3.0.0",
"version": "3.0.1",
"description": "Webpack config for Flarum JS and TS transpilation.",
"main": "src/index.cjs",
"author": "Flarum Team",

View File

@ -140,12 +140,12 @@ class RegisterAsyncChunksPlugin {
if (
!chunkModuleMemory[sourceChunkId].includes(urlPath) &&
!RegisterAsyncChunksPlugin.registry[`${chunkId}:${moduleId}:${namespace}`]?.includes(urlPath)
!RegisterAsyncChunksPlugin.registry[`${sourceChunkId}:${chunkId}:${moduleId}:${namespace}`]?.includes(urlPath)
) {
reg.push(`flarum.reg.addChunkModule('${chunkId}', '${moduleId}', '${namespace}', '${urlPath}');`);
chunkModuleMemory[sourceChunkId].push(urlPath);
RegisterAsyncChunksPlugin.registry[`${chunkId}:${moduleId}:${namespace}`] ||= [];
RegisterAsyncChunksPlugin.registry[`${chunkId}:${moduleId}:${namespace}`].push(urlPath);
RegisterAsyncChunksPlugin.registry[`${sourceChunkId}:${chunkId}:${moduleId}:${namespace}`] ||= [];
RegisterAsyncChunksPlugin.registry[`${sourceChunkId}:${chunkId}:${moduleId}:${namespace}`].push(urlPath);
}
});

View File

@ -1 +1 @@
module.exports = (name) => (name === 'flarum/core' ? 'core' : name.replace('/flarum-ext-', '-').replace('/flarum-', '').replace('/', '-'));
module.exports = (name) => (name === 'flarum/core' ? 'core' : name.replace('/flarum-ext-', '-').replace('/flarum-', '-').replace('/', '-'));

View File

@ -3879,9 +3879,9 @@ ms@^2.1.3:
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
nanoid@^3.1.30:
version "3.3.7"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
version "3.3.8"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
integrity "sha1-sb4wML7jaq/xi6yzdeXM5SFoS68= sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="
natural-compare@^1.4.0:
version "1.4.0"