1
0
mirror of https://github.com/flarum/core.git synced 2025-08-15 12:54:47 +02:00

Compare commits

...

24 Commits

Author SHA1 Message Date
Sami Mazouz
13f997d784 feat: ItemList component 2023-11-10 14:15:53 +01:00
flarum-bot
d01c0e5210 Bundled output for commit bee50bec73
Includes transpiled JS/TS, and Typescript declaration files (typings).

[skip ci]
2023-11-03 13:15:30 +00:00
Sami Mazouz
bee50bec73 fix: color input changes while typing (#3919) 2023-11-03 14:08:40 +01:00
flarum-bot
679d32729e Bundled output for commit e978e29e00
Includes transpiled JS/TS, and Typescript declaration files (typings).

[skip ci]
2023-11-03 08:10:35 +00:00
IanM
e978e29e00 fix: add history push (#3916) 2023-11-03 09:07:25 +01:00
Sami Mazouz
5cdfa0f640 fix: load event mentioned tags on show discussion endpoint (#3915) 2023-11-01 13:43:00 +00:00
flarum-bot
a3192d2934 Bundled output for commit 96ba2f5f2d
Includes transpiled JS/TS, and Typescript declaration files (typings).

[skip ci]
2023-10-29 13:51:57 +00:00
dependabot[bot]
96ba2f5f2d chore(deps): bump @babel/traverse from 7.20.1 to 7.23.2 (#3901)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.20.1 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-29 14:46:38 +01:00
Sami Mazouz
87a83d33b3 chore: avoid using .fa() mixins and @fa-var vars (#3912) 2023-10-29 14:45:50 +01:00
Ngô Quốc Đạt
015529ff1e Use ::class syntax to fetch class name instead of get_class() function (#3910) 2023-10-29 14:43:58 +01:00
flarum-bot
2950290ad1 Bundled output for commit d154388468
Includes transpiled JS/TS, and Typescript declaration files (typings).

[skip ci]
2023-10-29 12:32:28 +00:00
Sami Mazouz
d154388468 chore: function names 2023-10-29 13:27:34 +01:00
Gary Green
7c885c72fd feat: frontend content flexible order priorities (#3765)
* Fix frontend factory so it includes controller content
* chore: more readable parameter passing
* feat: add priorities to frontend content
2023-10-29 12:59:48 +01:00
Sami Mazouz
577fc3e6a8 fix(webpack-config): split chunks can fail in dev mode (#3911) 2023-10-27 15:27:11 +01:00
IanM
e4e0fbff73 chore: remove ExtenderInterface[] as a conditional option, only support callable or ::class invoke (#3904)
* chore: remove ExtenderInterface[] as a conditional option, only support callable or ::class invoke

* Apply fixes from StyleCI

* stan

* review

---------

Co-authored-by: StyleCI Bot <bot@styleci.io>
2023-10-21 17:37:07 +01:00
IanM
94de8b42b4 fix: console extender does not accept ::class attribute for schedule (#3903) 2023-10-21 17:34:48 +01:00
flarum-bot
db0d9cb006 Bundled output for commit 5ab5257ff5
Includes transpiled JS/TS, and Typescript declaration files (typings).

[skip ci]
2023-10-10 20:41:11 +00:00
Sami Mazouz
5ab5257ff5 feat: theming and extensibility improvements (#3876)
* feat: make page structure customizable across different pages (#3867)

* feat: create `PageStructure` component
* feat: apply to `DiscussionPage`
* feat: apply to `UserPage`
* feat: apply to `TagsPage`
* fix: adapt subscriptions ext
* chore: cleanup

* chore: use grid & flexbox for the discussion list item (#3868)

* chore: rename `DiscussionPage-list` to `DiscussionListPane`
* chore: itemlistify `DiscussionListItem`
* chore: use flex and grid for `DiscussionListItem`

* chore: use flexbox for `App-header` (#3869)

* chore: use flex and grid for `App-header`
* chore: drop search floats
* fix: adapt admin styles

* chore: use flexbox in dropdowns and SplitDropdown for subscriptions (#3874)

* chore: flexbox dropdown menu items
* chore: normalize subscriptions menu (use slit dropdown)
* chore: cleanup

* chore: misc flexbox/grid changes (#3875)

* chore: `TagsPage` to tsx
* chore: `TagsPage` flexbox/grid
* chore: `IndexPage-toolbar` flexbox
* chore: `UserCard` flexbox & itemlists
* fix: `Post` improve spacing logic
* chore: `Post` grid and proper spacing
* fix: avatar editor hover layer layout
* chore: `Button` flex

* chore: normalize form semantics (#3877)

* chore: normalize fieldsets
* fix: `LinkButton` spacing
* chore: consistent form semantics

* fix: styling regressions (#3878)

* fix: post spacing goes off in other pages
* fix: regression

* feat: extract reusable components from `NotificationsDropdown` (#3879)

* feat: extensible global notices (#3880)

* fix: js error on null item list
* feat: extensible global notices

* chore: housekeeping (#3881)

* chore: use CSS variables where still not using
* chore: cleanup suspension modal
* chore: cleanup post flag
* fix: badge vertical align
* chore: use CSS variables for custom coloring
* chore: `icon` helper to `Icon` component
* chore: `avatar` helper to `Avatar` component
* fix: chunk loading fails on admin frontend
* chore: format

* feat: reusable `UploadImageButton` component (#3882)

* chore: convert `UploadImageButton` to tsx
* feat: reusable `UploadImageButton` component
* feat: add `image-upload` setting type

* feat: extensible default footer component (#3883)

* chore: yarn format
2023-10-10 21:36:08 +01:00
flarum-bot
24d13e33bb Bundled output for commit 412cfafb3a
Includes transpiled JS/TS, and Typescript declaration files (typings).

[skip ci]
2023-09-29 15:39:58 +00:00
IanM
412cfafb3a feat: notification unsubscribe & email overhaul with HTML multipart (#3872) 2023-09-29 16:34:54 +01:00
Sami Mazouz
ec5cb98c77 chore: merge the app with the container & implement the ApplicationContract (#3862)
* chore: merge the app with the container & implement the ApplicationContract

Illuminate components always expect the app to be the container, but also expect the app to be implementing the laravel app contract. This means that very often between minor illuminate updates we get a call to a method on the app that doesn't exist in the Flarum app. This fixes the issue once and for all.

* chore: improve concern implementation readability
* chore: service provider no longer has to change app type
* chore: unimplement `terminat(e/ing)`
* Apply fixes from StyleCI
* chore: recover `container` prop
* chore: return types
* fix: phpstan errors
2023-09-15 09:30:24 +01:00
flarum-bot
23fdddf185 Bundled output for commit be9eb16d7d
Includes transpiled JS/TS, and Typescript declaration files (typings).

[skip ci]
2023-09-14 20:09:52 +00:00
Ngô Quốc Đạt
be9eb16d7d chore: use str_contains (#3841) 2023-09-14 21:05:15 +01:00
IanM
ee34217b15 test: add MySQL 8.1 to the suite (#3870)
* Test using MySQL 8.1 also
* fix: db not added to matrix
* chore: add MySQL 8.1 to prefix tests
2023-09-14 21:04:25 +01:00
395 changed files with 5005 additions and 2786 deletions

View File

@@ -43,7 +43,7 @@ on:
description: Versions of databases to test with. Should be array of strings encoded as JSON array
type: string
required: false
default: '["mysql:5.7", "mysql:8.0.30", "mariadb"]'
default: '["mysql:5.7", "mysql:8.0.30", "mysql:8.1.0", "mariadb"]'
php_ini_values:
description: PHP ini values
@@ -76,6 +76,8 @@ jobs:
db: MySQL 8.0
- service: mariadb
db: MariaDB
- service: 'mysql:8.1.0'
db: MySQL 8.1
# Include Database prefix tests with only one PHP version.
- php: ${{ fromJSON(inputs.php_versions)[0] }}
@@ -93,6 +95,11 @@ jobs:
db: MariaDB
prefix: flarum_
prefixStr: (prefix)
- php: ${{ fromJSON(inputs.php_versions)[0] }}
service: 'mysql:8.1.0'
db: MySQL 8.1
prefix: flarum_
prefixStr: (prefix)
# To reduce number of actions, we exclude some PHP versions from running with some DB versions.
exclude:

View File

@@ -50,7 +50,7 @@
padding: 15px 15px;
.scrolled & {
.box-shadow(0 2px 6px @shadow-color);
.box-shadow(0 2px 6px var(--shadow-color));
}
}
@@ -69,7 +69,7 @@
margin: 0;
&, a {
color: @muted-color;
color: var(--muted-color);
}
}
}

View File

@@ -12,7 +12,7 @@ img.emoji {
margin: 5px 0 !important;
> li > button {
color: @text-color;
color: var(--text-color);
font-weight: bold;
padding-top: 6px;
padding-bottom: 6px;
@@ -25,7 +25,7 @@ img.emoji {
}
.Dropdown-header {
color: @muted-more-color;
color: var(--muted-more-color);
text-transform: none;
font-weight: normal;
padding-bottom: 5px;

View File

@@ -1,7 +1,11 @@
export default class FlagList extends Component<import("flarum/common/Component").ComponentAttrs, undefined> {
constructor();
oninit(vnode: any): void;
state: any;
import Component from 'flarum/common/Component';
import type { ComponentAttrs } from 'flarum/common/Component';
import type Mithril from 'mithril';
import type FlagListState from '../states/FlagListState';
export interface IFlagListAttrs extends ComponentAttrs {
state: FlagListState;
}
export default class FlagList<CustomAttrs extends IFlagListAttrs = IFlagListAttrs> extends Component<CustomAttrs, FlagListState> {
oninit(vnode: Mithril.Vnode<CustomAttrs, this>): void;
view(): JSX.Element;
}
import Component from "flarum/common/Component";

View File

@@ -1,7 +1,12 @@
export default class FlagsDropdown extends NotificationsDropdown<import("flarum/common/components/Dropdown").IDropdownAttrs> {
static initAttrs(attrs: any): void;
constructor();
getUnreadCount(): any;
getNewCount(): unknown;
/// <reference types="mithril" />
import HeaderDropdown from 'flarum/forum/components/HeaderDropdown';
import type { IHeaderDropdownAttrs } from 'flarum/forum/components/HeaderDropdown';
export interface IFlagsDropdownAttrs extends IHeaderDropdownAttrs {
}
export default class FlagsDropdown<CustomAttrs extends IFlagsDropdownAttrs = IFlagsDropdownAttrs> extends HeaderDropdown<CustomAttrs> {
static initAttrs(attrs: IFlagsDropdownAttrs): void;
getContent(): JSX.Element;
goToRoute(): void;
getUnreadCount(): number;
getNewCount(): number;
}
import NotificationsDropdown from "flarum/forum/components/NotificationsDropdown";

View File

@@ -1,16 +1,15 @@
import type ForumApplication from 'flarum/forum/ForumApplication';
import type Flag from '../models/Flag';
import type Post from 'flarum/common/models/Post';
export default class FlagListState {
constructor(app: any);
app: any;
/**
* Whether or not the flags are loading.
*
* @type {Boolean}
*/
app: ForumApplication;
loading: boolean;
cache: Flag[] | null;
index: Post | false | null;
constructor(app: ForumApplication);
/**
* Load flags into the application's cache if they haven't already
* been loaded.
*/
load(): void;
cache: any;
}

2
extensions/flags/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

View File

@@ -1,4 +1,4 @@
import { extend } from 'flarum/common/extend';
import { extend, override } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import Post from 'flarum/forum/components/Post';
import Button from 'flarum/common/components/Button';
@@ -75,7 +75,7 @@ export default function () {
return items;
};
extend(Post.prototype, 'content', function (vdom) {
override(Post.prototype, 'header', function (vdom) {
const post = this.attrs.post;
const flags = post.flags();
@@ -83,7 +83,7 @@ export default function () {
if (post.isHidden()) this.revealContent = true;
vdom.unshift(
return (
<div className="Post-flagged">
<div className="Post-flagged-flags">
{flags.map((flag) => (

View File

@@ -1,65 +0,0 @@
import app from 'flarum/forum/app';
import Component from 'flarum/common/Component';
import Link from 'flarum/common/components/Link';
import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
import avatar from 'flarum/common/helpers/avatar';
import username from 'flarum/common/helpers/username';
import icon from 'flarum/common/helpers/icon';
import humanTime from 'flarum/common/helpers/humanTime';
export default class FlagList extends Component {
oninit(vnode) {
super.oninit(vnode);
this.state = this.attrs.state;
}
view() {
const flags = this.state.cache || [];
return (
<div className="NotificationList FlagList">
<div className="NotificationList-header">
<h4 className="App-titleControl App-titleControl--text">{app.translator.trans('flarum-flags.forum.flagged_posts.title')}</h4>
</div>
<div className="NotificationList-content">
<ul className="NotificationGroup-content">
{flags.length ? (
flags.map((flag) => {
const post = flag.post();
return (
<li>
<Link
href={app.route.post(post)}
className="Notification Flag"
onclick={(e) => {
app.flags.index = post;
e.redraw = false;
}}
>
{avatar(post.user())}
{icon('fas fa-flag', { className: 'Notification-icon' })}
<span className="Notification-content">
{app.translator.trans('flarum-flags.forum.flagged_posts.item_text', {
username: username(post.user()),
em: <em />,
discussion: post.discussion().title(),
})}
</span>
{humanTime(flag.createdAt())}
<div className="Notification-excerpt">{post.contentPlain()}</div>
</Link>
</li>
);
})
) : !this.state.loading ? (
<div className="NotificationList-empty">{app.translator.trans('flarum-flags.forum.flagged_posts.empty_text')}</div>
) : (
<LoadingIndicator className="LoadingIndicator--block" />
)}
</ul>
</div>
</div>
);
}
}

View File

@@ -0,0 +1,64 @@
import app from 'flarum/forum/app';
import Component from 'flarum/common/Component';
import type { ComponentAttrs } from 'flarum/common/Component';
import Avatar from 'flarum/common/components/Avatar';
import username from 'flarum/common/helpers/username';
import HeaderList from 'flarum/forum/components/HeaderList';
import HeaderListItem from 'flarum/forum/components/HeaderListItem';
import type Mithril from 'mithril';
import type Post from 'flarum/common/models/Post';
import type FlagListState from '../states/FlagListState';
export interface IFlagListAttrs extends ComponentAttrs {
state: FlagListState;
}
export default class FlagList<CustomAttrs extends IFlagListAttrs = IFlagListAttrs> extends Component<CustomAttrs, FlagListState> {
oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
super.oninit(vnode);
this.state = this.attrs.state;
}
view() {
const flags = this.state.cache || [];
return (
<HeaderList
className="FlagList"
title={app.translator.trans('flarum-flags.forum.flagged_posts.title')}
hasItems={flags.length}
loading={this.state.loading}
emptyText={app.translator.trans('flarum-flags.forum.flagged_posts.empty_text')}
>
<ul className="HeaderListGroup-content">
{!this.state.loading &&
flags.map((flag) => {
const post = flag.post() as Post;
return (
<li>
<HeaderListItem
className="Flag"
avatar={<Avatar user={post.user() || null} />}
icon="fas fa-flag"
content={app.translator.trans('flarum-flags.forum.flagged_posts.item_text', {
username: username(post.user()),
em: <em />,
discussion: post.discussion().title(),
})}
excerpt={post.contentPlain()}
datetime={flag.createdAt()}
href={app.route.post(post)}
onclick={(e: MouseEvent) => {
app.flags.index = post;
e.redraw = false;
}}
/>
</li>
);
})}
</ul>
</HeaderList>
);
}
}

View File

@@ -1,5 +1,6 @@
import app from 'flarum/forum/app';
import Modal from 'flarum/common/components/Modal';
import Form from 'flarum/common/components/Form';
import Button from 'flarum/common/components/Button';
import Stream from 'flarum/common/utils/Stream';
@@ -28,31 +29,31 @@ export default class FlagPostModal extends Modal {
if (this.success) {
return (
<div className="Modal-body">
<div className="Form Form--centered">
<Form className="Form--centered">
<p className="helpText">{app.translator.trans('flarum-flags.forum.flag_post.confirmation_message')}</p>
<div className="Form-group">
<div className="Form-group Form-controls">
<Button className="Button Button--primary Button--block" onclick={this.hide.bind(this)}>
{app.translator.trans('flarum-flags.forum.flag_post.dismiss_button')}
</Button>
</div>
</div>
</Form>
</div>
);
}
return (
<div className="Modal-body">
<div className="Form Form--centered">
<Form className="Form--centered">
<div className="Form-group">
<div>{this.flagReasons().toArray()}</div>
</div>
<div className="Form-group">
<div className="Form-group Form-controls">
<Button className="Button Button--primary Button--block" type="submit" loading={this.loading} disabled={!this.reason()}>
{app.translator.trans('flarum-flags.forum.flag_post.submit_button')}
</Button>
</div>
</div>
</Form>
</div>
);
}

View File

@@ -1,33 +0,0 @@
import app from 'flarum/forum/app';
import NotificationsDropdown from 'flarum/forum/components/NotificationsDropdown';
import FlagList from './FlagList';
export default class FlagsDropdown extends NotificationsDropdown {
static initAttrs(attrs) {
attrs.label = attrs.label || app.translator.trans('flarum-flags.forum.flagged_posts.tooltip');
attrs.icon = attrs.icon || 'fas fa-flag';
super.initAttrs(attrs);
}
getMenu() {
return (
<div className={'Dropdown-menu ' + this.attrs.menuClassName} onclick={this.menuClick.bind(this)}>
{this.showing && <FlagList state={this.attrs.state} />}
</div>
);
}
goToRoute() {
m.route.set(app.route('flags'));
}
getUnreadCount() {
return app.flags.cache ? app.flags.cache.length : app.forum.attribute('flagCount');
}
getNewCount() {
return app.session.user.attribute('newFlagCount');
}
}

View File

@@ -0,0 +1,34 @@
import app from 'flarum/forum/app';
import HeaderDropdown from 'flarum/forum/components/HeaderDropdown';
import type { IHeaderDropdownAttrs } from 'flarum/forum/components/HeaderDropdown';
import classList from 'flarum/common/utils/classList';
import FlagList from './FlagList';
export interface IFlagsDropdownAttrs extends IHeaderDropdownAttrs {}
export default class FlagsDropdown<CustomAttrs extends IFlagsDropdownAttrs = IFlagsDropdownAttrs> extends HeaderDropdown<CustomAttrs> {
static initAttrs(attrs: IFlagsDropdownAttrs) {
attrs.className = classList('FlagsDropdown', attrs.className);
attrs.label = attrs.label || app.translator.trans('flarum-flags.forum.flagged_posts.tooltip');
attrs.icon = attrs.icon || 'fas fa-flag';
super.initAttrs(attrs);
}
getContent() {
return <FlagList state={this.attrs.state} />;
}
goToRoute() {
m.route.set(app.route('flags'));
}
getUnreadCount() {
return app.flags.cache ? app.flags.cache.length : app.forum.attribute<number>('flagCount');
}
getNewCount() {
return app.session.user!.attribute<number>('newFlagCount');
}
}

View File

@@ -1,37 +0,0 @@
export default class FlagListState {
constructor(app) {
this.app = app;
/**
* Whether or not the flags are loading.
*
* @type {Boolean}
*/
this.loading = false;
}
/**
* Load flags into the application's cache if they haven't already
* been loaded.
*/
load() {
if (this.cache && !this.app.session.user.attribute('newFlagCount')) {
return;
}
this.loading = true;
m.redraw();
this.app.store
.find('flags')
.then((flags) => {
this.app.session.user.pushAttributes({ newFlagCount: 0 });
this.cache = flags.sort((a, b) => b.createdAt() - a.createdAt());
})
.catch(() => {})
.then(() => {
this.loading = false;
m.redraw();
});
}
}

View File

@@ -0,0 +1,39 @@
import type ForumApplication from 'flarum/forum/ForumApplication';
import type Flag from '../models/Flag';
import type Post from 'flarum/common/models/Post';
export default class FlagListState {
public app: ForumApplication;
public loading = false;
public cache: Flag[] | null = null;
public index: Post | false | null = null;
constructor(app: ForumApplication) {
this.app = app;
}
/**
* Load flags into the application's cache if they haven't already
* been loaded.
*/
load() {
if (this.cache && !this.app.session.user!.attribute<number>('newFlagCount')) {
return;
}
this.loading = true;
m.redraw();
this.app.store
.find<Flag[]>('flags')
.then((flags) => {
this.app.session.user!.pushAttributes({ newFlagCount: 0 });
this.cache = flags.sort((a, b) => b.createdAt()!.getTime() - a.createdAt()!.getTime());
})
.catch(() => {})
.then(() => {
this.loading = false;
m.redraw();
});
}
}

View File

@@ -1,6 +1,9 @@
.Post--flagged {
--border-width: 2px;
padding-top: 0 !important;
border: 2px solid @primary-color;
padding-left: var(--post-padding);
margin-left: calc(~"0px - var(--post-padding)");
border: var(--border-width) solid var(--primary-color);
}
.Post-header .item-flagged {
@@ -8,29 +11,22 @@
margin: 0;
}
.Post-flagged {
background: @primary-color;
margin-top: -2px;
margin-bottom: 20px;
margin-left: -22px;
margin-right: -22px;
background: var(--primary-color);
margin: calc(~"0px - var(--border-width)") calc(~"0px - var(--border-width) - var(--post-padding)") var(--post-padding);
padding: 10px;
border-radius: @border-radius @border-radius 0 0;
border-radius: var(--border-radius) var(--border-radius) 0 0;
overflow: hidden;
.light-contents(@color: @body-bg; @control-color: @body-bg);
@media @tablet-up {
margin-left: -22px - 85px;
}
display: flex;
align-items: center;
justify-content: space-between;
&, a {
color: @body-bg !important;
color: var(--body-bg) !important;
}
}
.Post-flagged-flags {
@media @tablet-up {
float: left;
}
font-size: 14px;
margin: 7px 10px;
text-align: left;
@@ -42,19 +38,10 @@
font-weight: normal;
}
.Post-flagged-actions {
@media @tablet-up {
float: right;
}
}
.Post-flagged-actions .Button {
margin-left: 5px;
}
.FlagsDropdown .Dropdown-toggle {
.Button-label,
.Button-caret {
display: none;
}
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 5px;
}
.FlagPostModal {
@@ -66,7 +53,16 @@
strong {
display: block;
color: @text-color;
color: var(--text-color);
}
}
}
.Flag .HeaderListItem-title {
justify-content: space-between;
flex-wrap: nowrap;
}
.Flag .HeaderListItem-time {
flex-shrink: 0;
}

View File

@@ -24,7 +24,7 @@ class FlagSerializer extends AbstractSerializer
{
if (! ($model instanceof Flag)) {
throw new InvalidArgumentException(
get_class($this).' can only serialize instances of '.Flag::class
$this::class.' can only serialize instances of '.Flag::class
);
}

2
extensions/likes/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

View File

@@ -4,7 +4,7 @@ import CommentPost from 'flarum/forum/components/CommentPost';
import Link from 'flarum/common/components/Link';
import punctuateSeries from 'flarum/common/helpers/punctuateSeries';
import username from 'flarum/common/helpers/username';
import icon from 'flarum/common/helpers/icon';
import Icon from 'flarum/common/components/Icon';
import Button from 'flarum/common/components/Button';
import PostLikesModal from './components/PostLikesModal';
@@ -58,7 +58,7 @@ export default function () {
items.add(
'liked',
<div className="Post-likedBy">
{icon('far fa-thumbs-up')}
<Icon name={'far fa-thumbs-up'} />
{app.translator.trans(`flarum-likes.forum.post.liked_by${likes[0] === app.session.user ? '_self' : ''}_text`, {
count: names.length,
users: punctuateSeries(names),

View File

@@ -1,7 +1,7 @@
import app from 'flarum/forum/app';
import Modal from 'flarum/common/components/Modal';
import Link from 'flarum/common/components/Link';
import avatar from 'flarum/common/helpers/avatar';
import Avatar from 'flarum/common/components/Avatar';
import username from 'flarum/common/helpers/username';
import type { IInternalModalAttrs } from 'flarum/common/components/Modal';
import type Post from 'flarum/common/models/Post';
@@ -9,6 +9,7 @@ import type Mithril from 'mithril';
import PostLikesModalState from '../states/PostLikesModalState';
import Button from 'flarum/common/components/Button';
import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
import Form from 'flarum/common/components/Form';
export interface IPostLikesModalAttrs extends IInternalModalAttrs {
post: Post;
@@ -47,7 +48,7 @@ export default class PostLikesModal<CustomAttrs extends IPostLikesModalAttrs = I
page.items.map((user) => (
<li>
<Link href={app.route.user(user)}>
{avatar(user)} {username(user)}
<Avatar user={user} /> {username(user)}
</Link>
</li>
))
@@ -57,13 +58,13 @@ export default class PostLikesModal<CustomAttrs extends IPostLikesModalAttrs = I
</div>
{this.state.hasNext() ? (
<div className="Modal-footer">
<div className="Form Form--centered">
<Form className="Form--centered">
<div className="Form-group">
<Button className="Button Button--block" onclick={() => this.state.loadNext()} loading={this.state.isLoadingNext()}>
{app.translator.trans('flarum-likes.forum.post_likes.load_more_button')}
</Button>
</div>
</div>
</Form>
</div>
) : null}
</>

View File

@@ -4,7 +4,7 @@
margin: 0;
a {
color: @text-color;
color: var(--text-color);
font-size: 15px;
font-weight: bold;
display: block;

2
extensions/lock/js/dist/forum.js generated vendored
View File

@@ -1,2 +1,2 @@
(()=>{var o={n:t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return o.d(e,{a:e}),e},d:(t,e)=>{for(var n in e)o.o(e,n)&&!o.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o:(o,t)=>Object.prototype.hasOwnProperty.call(o,t),r:o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})}},t={};(()=>{"use strict";o.r(t),o.d(t,{extend:()=>P});const e=flarum.reg.get("core","common/extend"),n=flarum.reg.get("core","forum/app");var r=o.n(n);const s=flarum.reg.get("core","forum/components/Notification");var c=o.n(s);class a extends(c()){icon(){return"fas fa-lock"}href(){const o=this.attrs.notification;return r().route.discussion(o.subject(),o.content().postNumber)}content(){return r().translator.trans("flarum-lock.forum.notifications.discussion_locked_text",{user:this.attrs.notification.fromUser()})}}flarum.reg.add("flarum-lock","forum/components/DiscussionLockedNotification",a);const i=flarum.reg.get("core","common/models/Discussion");var u=o.n(i);const l=flarum.reg.get("core","common/components/Badge");var d=o.n(l);const f=flarum.reg.get("core","forum/utils/DiscussionControls");var k=o.n(f);const g=flarum.reg.get("core","forum/components/DiscussionPage");var p=o.n(g);const b=flarum.reg.get("core","common/components/Button");var _=o.n(b);const v=flarum.reg.get("core","common/extenders");var y=o.n(v);const L=flarum.reg.get("core","forum/components/EventPost");var h=o.n(L);class x extends(h()){icon(){return this.attrs.post.content().locked?"fas fa-lock":"fas fa-unlock"}descriptionKey(){return this.attrs.post.content().locked?"flarum-lock.forum.post_stream.discussion_locked_text":"flarum-lock.forum.post_stream.discussion_unlocked_text"}}flarum.reg.add("flarum-lock","forum/components/DiscussionLockedPost",x);const P=[(new(y().PostTypes)).add("discussionLocked",x),new(y().Model)(u()).attribute("isLocked").attribute("canLock")];r().initializers.add("flarum-lock",(()=>{r().notificationComponents.discussionLocked=a,(0,e.extend)(u().prototype,"badges",(function(o){this.isLocked()&&o.add("locked",m(d(),{type:"locked",label:r().translator.trans("flarum-lock.forum.badge.locked_tooltip"),icon:"fas fa-lock"}))})),(0,e.extend)(k(),"moderationControls",(function(o,t){t.canLock()&&o.add("lock",m(_(),{icon:"fas fa-lock",onclick:this.lockAction.bind(t)},r().translator.trans("flarum-lock.forum.discussion_controls.".concat(t.isLocked()?"unlock":"lock","_button"))))})),k().lockAction=function(){this.save({isLocked:!this.isLocked()}).then((()=>{r().current.matches(p())&&r().current.get("stream").update(),m.redraw()}))},(0,e.extend)("flarum/forum/components/NotificationGrid","notificationTypes",(function(o){o.add("discussionLocked",{name:"discussionLocked",icon:"fas fa-lock",label:r().translator.trans("flarum-lock.forum.settings.notify_discussion_locked_label")})}))}))})(),module.exports=t})();
(()=>{var o={n:t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return o.d(e,{a:e}),e},d:(t,e)=>{for(var n in e)o.o(e,n)&&!o.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o:(o,t)=>Object.prototype.hasOwnProperty.call(o,t),r:o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})}},t={};(()=>{"use strict";o.r(t),o.d(t,{extend:()=>P});const e=flarum.reg.get("core","common/extend"),n=flarum.reg.get("core","forum/app");var r=o.n(n);const s=flarum.reg.get("core","forum/components/Notification");var c=o.n(s);class a extends(c()){icon(){return"fas fa-lock"}href(){const o=this.attrs.notification;return r().route.discussion(o.subject(),o.content().postNumber)}content(){return r().translator.trans("flarum-lock.forum.notifications.discussion_locked_text",{user:this.attrs.notification.fromUser()})}excerpt(){return null}}flarum.reg.add("flarum-lock","forum/components/DiscussionLockedNotification",a);const i=flarum.reg.get("core","common/models/Discussion");var u=o.n(i);const l=flarum.reg.get("core","common/components/Badge");var d=o.n(l);const f=flarum.reg.get("core","forum/utils/DiscussionControls");var k=o.n(f);const g=flarum.reg.get("core","forum/components/DiscussionPage");var p=o.n(g);const b=flarum.reg.get("core","common/components/Button");var _=o.n(b);const v=flarum.reg.get("core","common/extenders");var y=o.n(v);const x=flarum.reg.get("core","forum/components/EventPost");var L=o.n(x);class h extends(L()){icon(){return this.attrs.post.content().locked?"fas fa-lock":"fas fa-unlock"}descriptionKey(){return this.attrs.post.content().locked?"flarum-lock.forum.post_stream.discussion_locked_text":"flarum-lock.forum.post_stream.discussion_unlocked_text"}}flarum.reg.add("flarum-lock","forum/components/DiscussionLockedPost",h);const P=[(new(y().PostTypes)).add("discussionLocked",h),new(y().Model)(u()).attribute("isLocked").attribute("canLock")];r().initializers.add("flarum-lock",(()=>{r().notificationComponents.discussionLocked=a,(0,e.extend)(u().prototype,"badges",(function(o){this.isLocked()&&o.add("locked",m(d(),{type:"locked",label:r().translator.trans("flarum-lock.forum.badge.locked_tooltip"),icon:"fas fa-lock"}))})),(0,e.extend)(k(),"moderationControls",(function(o,t){t.canLock()&&o.add("lock",m(_(),{icon:"fas fa-lock",onclick:this.lockAction.bind(t)},r().translator.trans("flarum-lock.forum.discussion_controls.".concat(t.isLocked()?"unlock":"lock","_button"))))})),k().lockAction=function(){this.save({isLocked:!this.isLocked()}).then((()=>{r().current.matches(p())&&r().current.get("stream").update(),m.redraw()}))},(0,e.extend)("flarum/forum/components/NotificationGrid","notificationTypes",(function(o){o.add("discussionLocked",{name:"discussionLocked",icon:"fas fa-lock",label:r().translator.trans("flarum-lock.forum.settings.notify_discussion_locked_label")})}))}))})(),module.exports=t})();
//# sourceMappingURL=forum.js.map

File diff suppressed because one or more lines are too long

View File

@@ -15,4 +15,8 @@ export default class DiscussionLockedNotification extends Notification {
content() {
return app.translator.trans('flarum-lock.forum.notifications.discussion_locked_text', { user: this.attrs.notification.fromUser() });
}
excerpt() {
return null;
}
}

View File

@@ -1,3 +1,3 @@
/*! For license information please see admin.js.LICENSE.txt */
(()=>{var t={n:e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return t.d(o,{a:o}),o},d:(e,o)=>{for(var r in o)t.o(o,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:o[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};(()=>{"use strict";t.r(e);const o=flarum.reg.get("core","admin/app");var r=t.n(o);const i=flarum.reg.get("core","common/app");var n=t.n(i);const a=flarum.reg.get("core","common/extend"),l=flarum.reg.get("core","common/utils/BasicEditorDriver");var c=t.n(l);const s=flarum.reg.get("core","common/utils/styleSelectedText");var d=t.n(s);const f=flarum.reg.get("core","common/Component");var u=t.n(f);class p extends(u()){view(t){return m("div",{className:"MarkdownToolbar"},t.children)}}flarum.reg.add("flarum-markdown","common/components/MarkdownToolbar",p);const k=flarum.reg.get("core","common/helpers/icon");var h=t.n(k);const g=flarum.reg.get("core","common/components/Tooltip");var x=t.n(g);class b extends(u()){oncreate(t){super.oncreate(t)}view(){const t=m("button",{className:"Button Button--icon Button--link",type:"button","data-hotkey":this.attrs.hotkey,onkeydown:this.keydown.bind(this),onclick:this.attrs.onclick},h()(this.attrs.icon));return this.attrs.title?m(x(),{text:this.attrs.title},t):t}keydown(t){" "!==t.key&&"Enter"!==t.key||(t.preventDefault(),this.element.click())}}flarum.reg.add("flarum-markdown","common/components/MarkdownButton",b);const y=flarum.reg.get("core","common/utils/ItemList");var v=t.n(y);const w=navigator.userAgent.match(/Macintosh/)?"⌘":"ctrl",_={header:{prefix:"### "},bold:{prefix:"**",suffix:"**",trimFirst:!0},italic:{prefix:"_",suffix:"_",trimFirst:!0},strikethrough:{prefix:"~~",suffix:"~~",trimFirst:!0},quote:{prefix:"> ",multiline:!0,surroundWithNewlines:!0},code:{prefix:"`",suffix:"`",blockPrefix:"```",blockSuffix:"```"},link:{prefix:"[",suffix:"](https://)",replaceNext:"https://",scanFor:"https?://"},image:{prefix:"![",suffix:"](https://)",replaceNext:"https://",scanFor:"https?://"},unordered_list:{prefix:"- ",multiline:!0,surroundWithNewlines:!0},ordered_list:{prefix:"1. ",multiline:!0,orderedList:!0},spoiler:{prefix:">!",suffix:"!<",blockPrefix:">! ",multiline:!0,trimFirst:!0}},T=(t,e)=>{d()(e.el,_[t])};function S(t,e,o){return function(r){r.key===e&&(r.metaKey&&"⌘"===w||r.ctrlKey&&"ctrl"===w)&&(r.preventDefault(),T(t,o))}}function M(t){const e="function"==typeof t?t():new(v());function o(t,e){return n().translator.trans("flarum-markdown.lib.composer.".concat(t,"_tooltip"))+(e?" <".concat(w,"-").concat(e,">"):"")}const r=t=>()=>T(t,this.attrs.composer.editor);return e.add("header",m(b,{title:o("header"),icon:"fas fa-heading",onclick:r("header")}),1e3),e.add("bold",m(b,{title:o("bold","b"),icon:"fas fa-bold",onclick:r("bold")}),900),e.add("italic",m(b,{title:o("italic","i"),icon:"fas fa-italic",onclick:r("italic")}),800),e.add("strikethrough",m(b,{title:o("strikethrough"),icon:"fas fa-strikethrough",onclick:r("strikethrough")}),700),e.add("quote",m(b,{title:o("quote"),icon:"fas fa-quote-left",onclick:r("quote")}),600),e.add("spoiler",m(b,{title:o("spoiler"),icon:"fas fa-exclamation-triangle",onclick:r("spoiler")}),500),e.add("code",m(b,{title:o("code"),icon:"fas fa-code",onclick:r("code")}),400),e.add("link",m(b,{title:o("link"),icon:"fas fa-link",onclick:r("link")}),300),e.add("image",m(b,{title:o("image"),icon:"fas fa-image",onclick:r("image")}),200),e.add("unordered_list",m(b,{title:o("unordered_list"),icon:"fas fa-list-ul",onclick:r("unordered_list")}),100),e.add("ordered_list",m(b,{title:o("ordered_list"),icon:"fas fa-list-ol",onclick:r("ordered_list")}),0),e}r().initializers.add("flarum-markdown",(function(t){(0,a.extend)(c().prototype,"keyHandlers",(function(t){t.add("bold",S("bold","b",this)),t.add("italic",S("italic","i",this))})),(0,a.override)("flarum/common/components/TextEditor","markdownToolbarItems",M),(0,a.extend)("flarum/common/components/TextEditor","toolbarItems",(function(t){t.add("markdown",m(p,{for:this.textareaId,setShortcutHandler:t=>shortcutHandler=t},this.markdownToolbarItems().toArray()),100)}))}))})(),module.exports=e})();
(()=>{var t={n:e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return t.d(o,{a:o}),o},d:(e,o)=>{for(var r in o)t.o(o,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:o[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};(()=>{"use strict";t.r(e);const o=flarum.reg.get("core","admin/app");var r=t.n(o);const i=flarum.reg.get("core","common/app");var n=t.n(i);const a=flarum.reg.get("core","common/extend"),l=flarum.reg.get("core","common/utils/BasicEditorDriver");var c=t.n(l);const s=flarum.reg.get("core","common/utils/styleSelectedText");var d=t.n(s);const f=flarum.reg.get("core","common/Component");var u=t.n(f);class p extends(u()){view(t){return m("div",{className:"MarkdownToolbar"},t.children)}}flarum.reg.add("flarum-markdown","common/components/MarkdownToolbar",p);const k=flarum.reg.get("core","common/components/Icon");var h=t.n(k);const g=flarum.reg.get("core","common/components/Tooltip");var x=t.n(g);class b extends(u()){oncreate(t){super.oncreate(t)}view(){const t=m("button",{className:"Button Button--icon Button--link",type:"button","data-hotkey":this.attrs.hotkey,onkeydown:this.keydown.bind(this),onclick:this.attrs.onclick},m(h(),{name:this.attrs.icon}));return this.attrs.title?m(x(),{text:this.attrs.title},t):t}keydown(t){" "!==t.key&&"Enter"!==t.key||(t.preventDefault(),this.element.click())}}flarum.reg.add("flarum-markdown","common/components/MarkdownButton",b);const y=flarum.reg.get("core","common/utils/ItemList");var v=t.n(y);const w=navigator.userAgent.match(/Macintosh/)?"⌘":"ctrl",_={header:{prefix:"### "},bold:{prefix:"**",suffix:"**",trimFirst:!0},italic:{prefix:"_",suffix:"_",trimFirst:!0},strikethrough:{prefix:"~~",suffix:"~~",trimFirst:!0},quote:{prefix:"> ",multiline:!0,surroundWithNewlines:!0},code:{prefix:"`",suffix:"`",blockPrefix:"```",blockSuffix:"```"},link:{prefix:"[",suffix:"](https://)",replaceNext:"https://",scanFor:"https?://"},image:{prefix:"![",suffix:"](https://)",replaceNext:"https://",scanFor:"https?://"},unordered_list:{prefix:"- ",multiline:!0,surroundWithNewlines:!0},ordered_list:{prefix:"1. ",multiline:!0,orderedList:!0},spoiler:{prefix:">!",suffix:"!<",blockPrefix:">! ",multiline:!0,trimFirst:!0}},T=(t,e)=>{d()(e.el,_[t])};function S(t,e,o){return function(r){r.key===e&&(r.metaKey&&"⌘"===w||r.ctrlKey&&"ctrl"===w)&&(r.preventDefault(),T(t,o))}}function M(t){const e="function"==typeof t?t():new(v());function o(t,e){return n().translator.trans("flarum-markdown.lib.composer.".concat(t,"_tooltip"))+(e?" <".concat(w,"-").concat(e,">"):"")}const r=t=>()=>T(t,this.attrs.composer.editor);return e.add("header",m(b,{title:o("header"),icon:"fas fa-heading",onclick:r("header")}),1e3),e.add("bold",m(b,{title:o("bold","b"),icon:"fas fa-bold",onclick:r("bold")}),900),e.add("italic",m(b,{title:o("italic","i"),icon:"fas fa-italic",onclick:r("italic")}),800),e.add("strikethrough",m(b,{title:o("strikethrough"),icon:"fas fa-strikethrough",onclick:r("strikethrough")}),700),e.add("quote",m(b,{title:o("quote"),icon:"fas fa-quote-left",onclick:r("quote")}),600),e.add("spoiler",m(b,{title:o("spoiler"),icon:"fas fa-exclamation-triangle",onclick:r("spoiler")}),500),e.add("code",m(b,{title:o("code"),icon:"fas fa-code",onclick:r("code")}),400),e.add("link",m(b,{title:o("link"),icon:"fas fa-link",onclick:r("link")}),300),e.add("image",m(b,{title:o("image"),icon:"fas fa-image",onclick:r("image")}),200),e.add("unordered_list",m(b,{title:o("unordered_list"),icon:"fas fa-list-ul",onclick:r("unordered_list")}),100),e.add("ordered_list",m(b,{title:o("ordered_list"),icon:"fas fa-list-ol",onclick:r("ordered_list")}),0),e}r().initializers.add("flarum-markdown",(function(t){(0,a.extend)(c().prototype,"keyHandlers",(function(t){t.add("bold",S("bold","b",this)),t.add("italic",S("italic","i",this))})),(0,a.override)("flarum/common/components/TextEditor","markdownToolbarItems",M),(0,a.extend)("flarum/common/components/TextEditor","toolbarItems",(function(t){t.add("markdown",m(p,{for:this.textareaId,setShortcutHandler:t=>shortcutHandler=t},this.markdownToolbarItems().toArray()),100)}))}))})(),module.exports=e})();
//# sourceMappingURL=admin.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,3 @@
/*! For license information please see forum.js.LICENSE.txt */
(()=>{var t={n:e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return t.d(o,{a:o}),o},d:(e,o)=>{for(var r in o)t.o(o,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:o[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};(()=>{"use strict";t.r(e);const o=flarum.reg.get("core","forum/app");var r=t.n(o);const i=flarum.reg.get("core","common/app");var n=t.n(i);const a=flarum.reg.get("core","common/extend"),l=flarum.reg.get("core","common/utils/BasicEditorDriver");var c=t.n(l);const s=flarum.reg.get("core","common/utils/styleSelectedText");var d=t.n(s);const f=flarum.reg.get("core","common/Component");var u=t.n(f);class p extends(u()){view(t){return m("div",{className:"MarkdownToolbar"},t.children)}}flarum.reg.add("flarum-markdown","common/components/MarkdownToolbar",p);const k=flarum.reg.get("core","common/helpers/icon");var h=t.n(k);const g=flarum.reg.get("core","common/components/Tooltip");var x=t.n(g);class b extends(u()){oncreate(t){super.oncreate(t)}view(){const t=m("button",{className:"Button Button--icon Button--link",type:"button","data-hotkey":this.attrs.hotkey,onkeydown:this.keydown.bind(this),onclick:this.attrs.onclick},h()(this.attrs.icon));return this.attrs.title?m(x(),{text:this.attrs.title},t):t}keydown(t){" "!==t.key&&"Enter"!==t.key||(t.preventDefault(),this.element.click())}}flarum.reg.add("flarum-markdown","common/components/MarkdownButton",b);const y=flarum.reg.get("core","common/utils/ItemList");var v=t.n(y);const w=navigator.userAgent.match(/Macintosh/)?"⌘":"ctrl",_={header:{prefix:"### "},bold:{prefix:"**",suffix:"**",trimFirst:!0},italic:{prefix:"_",suffix:"_",trimFirst:!0},strikethrough:{prefix:"~~",suffix:"~~",trimFirst:!0},quote:{prefix:"> ",multiline:!0,surroundWithNewlines:!0},code:{prefix:"`",suffix:"`",blockPrefix:"```",blockSuffix:"```"},link:{prefix:"[",suffix:"](https://)",replaceNext:"https://",scanFor:"https?://"},image:{prefix:"![",suffix:"](https://)",replaceNext:"https://",scanFor:"https?://"},unordered_list:{prefix:"- ",multiline:!0,surroundWithNewlines:!0},ordered_list:{prefix:"1. ",multiline:!0,orderedList:!0},spoiler:{prefix:">!",suffix:"!<",blockPrefix:">! ",multiline:!0,trimFirst:!0}},T=(t,e)=>{d()(e.el,_[t])};function S(t,e,o){return function(r){r.key===e&&(r.metaKey&&"⌘"===w||r.ctrlKey&&"ctrl"===w)&&(r.preventDefault(),T(t,o))}}function M(t){const e="function"==typeof t?t():new(v());function o(t,e){return n().translator.trans("flarum-markdown.lib.composer.".concat(t,"_tooltip"))+(e?" <".concat(w,"-").concat(e,">"):"")}const r=t=>()=>T(t,this.attrs.composer.editor);return e.add("header",m(b,{title:o("header"),icon:"fas fa-heading",onclick:r("header")}),1e3),e.add("bold",m(b,{title:o("bold","b"),icon:"fas fa-bold",onclick:r("bold")}),900),e.add("italic",m(b,{title:o("italic","i"),icon:"fas fa-italic",onclick:r("italic")}),800),e.add("strikethrough",m(b,{title:o("strikethrough"),icon:"fas fa-strikethrough",onclick:r("strikethrough")}),700),e.add("quote",m(b,{title:o("quote"),icon:"fas fa-quote-left",onclick:r("quote")}),600),e.add("spoiler",m(b,{title:o("spoiler"),icon:"fas fa-exclamation-triangle",onclick:r("spoiler")}),500),e.add("code",m(b,{title:o("code"),icon:"fas fa-code",onclick:r("code")}),400),e.add("link",m(b,{title:o("link"),icon:"fas fa-link",onclick:r("link")}),300),e.add("image",m(b,{title:o("image"),icon:"fas fa-image",onclick:r("image")}),200),e.add("unordered_list",m(b,{title:o("unordered_list"),icon:"fas fa-list-ul",onclick:r("unordered_list")}),100),e.add("ordered_list",m(b,{title:o("ordered_list"),icon:"fas fa-list-ol",onclick:r("ordered_list")}),0),e}r().initializers.add("flarum-markdown",(function(t){(0,a.extend)(c().prototype,"keyHandlers",(function(t){t.add("bold",S("bold","b",this)),t.add("italic",S("italic","i",this))})),(0,a.override)("flarum/common/components/TextEditor","markdownToolbarItems",M),(0,a.extend)("flarum/common/components/TextEditor","toolbarItems",(function(t){t.add("markdown",m(p,{for:this.textareaId,setShortcutHandler:t=>shortcutHandler=t},this.markdownToolbarItems().toArray()),100)}))}))})(),module.exports=e})();
(()=>{var t={n:e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return t.d(o,{a:o}),o},d:(e,o)=>{for(var r in o)t.o(o,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:o[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};(()=>{"use strict";t.r(e);const o=flarum.reg.get("core","forum/app");var r=t.n(o);const i=flarum.reg.get("core","common/app");var n=t.n(i);const a=flarum.reg.get("core","common/extend"),l=flarum.reg.get("core","common/utils/BasicEditorDriver");var c=t.n(l);const s=flarum.reg.get("core","common/utils/styleSelectedText");var d=t.n(s);const f=flarum.reg.get("core","common/Component");var u=t.n(f);class p extends(u()){view(t){return m("div",{className:"MarkdownToolbar"},t.children)}}flarum.reg.add("flarum-markdown","common/components/MarkdownToolbar",p);const k=flarum.reg.get("core","common/components/Icon");var h=t.n(k);const g=flarum.reg.get("core","common/components/Tooltip");var x=t.n(g);class b extends(u()){oncreate(t){super.oncreate(t)}view(){const t=m("button",{className:"Button Button--icon Button--link",type:"button","data-hotkey":this.attrs.hotkey,onkeydown:this.keydown.bind(this),onclick:this.attrs.onclick},m(h(),{name:this.attrs.icon}));return this.attrs.title?m(x(),{text:this.attrs.title},t):t}keydown(t){" "!==t.key&&"Enter"!==t.key||(t.preventDefault(),this.element.click())}}flarum.reg.add("flarum-markdown","common/components/MarkdownButton",b);const y=flarum.reg.get("core","common/utils/ItemList");var v=t.n(y);const w=navigator.userAgent.match(/Macintosh/)?"⌘":"ctrl",_={header:{prefix:"### "},bold:{prefix:"**",suffix:"**",trimFirst:!0},italic:{prefix:"_",suffix:"_",trimFirst:!0},strikethrough:{prefix:"~~",suffix:"~~",trimFirst:!0},quote:{prefix:"> ",multiline:!0,surroundWithNewlines:!0},code:{prefix:"`",suffix:"`",blockPrefix:"```",blockSuffix:"```"},link:{prefix:"[",suffix:"](https://)",replaceNext:"https://",scanFor:"https?://"},image:{prefix:"![",suffix:"](https://)",replaceNext:"https://",scanFor:"https?://"},unordered_list:{prefix:"- ",multiline:!0,surroundWithNewlines:!0},ordered_list:{prefix:"1. ",multiline:!0,orderedList:!0},spoiler:{prefix:">!",suffix:"!<",blockPrefix:">! ",multiline:!0,trimFirst:!0}},T=(t,e)=>{d()(e.el,_[t])};function S(t,e,o){return function(r){r.key===e&&(r.metaKey&&"⌘"===w||r.ctrlKey&&"ctrl"===w)&&(r.preventDefault(),T(t,o))}}function M(t){const e="function"==typeof t?t():new(v());function o(t,e){return n().translator.trans("flarum-markdown.lib.composer.".concat(t,"_tooltip"))+(e?" <".concat(w,"-").concat(e,">"):"")}const r=t=>()=>T(t,this.attrs.composer.editor);return e.add("header",m(b,{title:o("header"),icon:"fas fa-heading",onclick:r("header")}),1e3),e.add("bold",m(b,{title:o("bold","b"),icon:"fas fa-bold",onclick:r("bold")}),900),e.add("italic",m(b,{title:o("italic","i"),icon:"fas fa-italic",onclick:r("italic")}),800),e.add("strikethrough",m(b,{title:o("strikethrough"),icon:"fas fa-strikethrough",onclick:r("strikethrough")}),700),e.add("quote",m(b,{title:o("quote"),icon:"fas fa-quote-left",onclick:r("quote")}),600),e.add("spoiler",m(b,{title:o("spoiler"),icon:"fas fa-exclamation-triangle",onclick:r("spoiler")}),500),e.add("code",m(b,{title:o("code"),icon:"fas fa-code",onclick:r("code")}),400),e.add("link",m(b,{title:o("link"),icon:"fas fa-link",onclick:r("link")}),300),e.add("image",m(b,{title:o("image"),icon:"fas fa-image",onclick:r("image")}),200),e.add("unordered_list",m(b,{title:o("unordered_list"),icon:"fas fa-list-ul",onclick:r("unordered_list")}),100),e.add("ordered_list",m(b,{title:o("ordered_list"),icon:"fas fa-list-ol",onclick:r("ordered_list")}),0),e}r().initializers.add("flarum-markdown",(function(t){(0,a.extend)(c().prototype,"keyHandlers",(function(t){t.add("bold",S("bold","b",this)),t.add("italic",S("italic","i",this))})),(0,a.override)("flarum/common/components/TextEditor","markdownToolbarItems",M),(0,a.extend)("flarum/common/components/TextEditor","toolbarItems",(function(t){t.add("markdown",m(p,{for:this.textareaId,setShortcutHandler:t=>shortcutHandler=t},this.markdownToolbarItems().toArray()),100)}))}))})(),module.exports=e})();
//# sourceMappingURL=forum.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
import Component from 'flarum/common/Component';
import icon from 'flarum/common/helpers/icon';
import Icon from 'flarum/common/components/Icon';
import Tooltip from 'flarum/common/components/Tooltip';
export default class MarkdownButton extends Component {
@@ -16,7 +16,7 @@ export default class MarkdownButton extends Component {
onkeydown={this.keydown.bind(this)}
onclick={this.attrs.onclick}
>
{icon(this.attrs.icon)}
<Icon name={this.attrs.icon} />
</button>
);

View File

@@ -27,7 +27,6 @@ use Flarum\Post\Event\Revised;
use Flarum\Post\Filter\PostFilterer;
use Flarum\Post\Post;
use Flarum\Tags\Api\Serializer\TagSerializer;
use Flarum\Tags\Tag;
use Flarum\User\User;
return [
@@ -126,7 +125,7 @@ return [
// Tag mentions
(new Extend\Conditional())
->whenExtensionEnabled('flarum-tags', [
->whenExtensionEnabled('flarum-tags', fn () => [
(new Extend\Formatter)
->render(Formatter\FormatTagMentions::class)
->unparse(Formatter\UnparseTagMentions::class),

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,7 @@ import Link from 'flarum/common/components/Link';
import PostPreview from 'flarum/forum/components/PostPreview';
import punctuateSeries from 'flarum/common/helpers/punctuateSeries';
import username from 'flarum/common/helpers/username';
import icon from 'flarum/common/helpers/icon';
import Icon from 'flarum/common/components/Icon';
import Button from 'flarum/common/components/Button';
import MentionedByModal from './components/MentionedByModal';
@@ -54,7 +54,9 @@ export default function addMentionedByList() {
}}
>
<span className="PostPreview-content">
<span className="PostPreview-badge Avatar">{icon('fas fa-reply-all')}</span>
<span className="PostPreview-badge Avatar">
<Icon name={'fas fa-reply-all'} />
</span>
<span>
{app.translator.trans('flarum-mentions.forum.post.mentioned_by_more_text', { count: post.mentionedByCount() - replies.length })}
</span>
@@ -145,7 +147,7 @@ export default function addMentionedByList() {
'replies',
<div className="Post-mentionedBy">
<span className="Post-mentionedBy-summary">
{icon('fas fa-reply')}
<Icon name={'fas fa-reply'} />
{app.translator.trans(`flarum-mentions.forum.post.mentioned_by${repliers[0].user() === app.session.user ? '_self' : ''}_text`, {
count: names.length,
users: punctuateSeries(names),

View File

@@ -5,7 +5,7 @@ import CommentPost from 'flarum/forum/components/CommentPost';
import reply from './utils/reply';
export default function () {
export default function addPostReplyAction() {
extend(CommentPost.prototype, 'actionItems', function (items) {
const post = this.attrs.post;

View File

@@ -6,6 +6,7 @@ import type Post from 'flarum/common/models/Post';
import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
import Button from 'flarum/common/components/Button';
import MentionedByModalState from '../state/MentionedByModalState';
import Form from 'flarum/common/components/Form';
export interface IMentionedByModalAttrs extends IInternalModalAttrs {
post: Post;
@@ -58,13 +59,13 @@ export default class MentionedByModal<CustomAttrs extends IMentionedByModalAttrs
</div>
{this.state.hasNext() && (
<div className="Modal-footer">
<div className="Form Form--centered">
<Form className="Form--centered">
<div className="Form-group">
<Button className="Button Button--block" onclick={() => this.state.loadNext()} loading={this.state.isLoadingNext()}>
{app.translator.trans('flarum-mentions.forum.mentioned_by.load_more_button')}
</Button>
</div>
</div>
</Form>
</div>
)}
</>

View File

@@ -1,6 +1,6 @@
import app from 'flarum/forum/app';
import Fragment from 'flarum/common/Fragment';
import icon from 'flarum/common/helpers/icon';
import Icon from 'flarum/common/components/Icon';
import reply from '../utils/reply';
@@ -19,7 +19,7 @@ export default class PostQuoteButton extends Fragment {
reply(this.post, this.content);
}}
>
{icon('fas fa-quote-left', { className: 'Button-icon' })}
<Icon name="fas fa-quote-left" className="Button-icon" />
{app.translator.trans('flarum-mentions.forum.post.quote_button')}
</button>
);

View File

@@ -3,7 +3,7 @@ import MentionableModel from './MentionableModel';
import type Post from 'flarum/common/models/Post';
import type Mithril from 'mithril';
import usernameHelper from 'flarum/common/helpers/username';
import avatar from 'flarum/common/helpers/avatar';
import Avatar from 'flarum/common/components/Avatar';
import highlight from 'flarum/common/helpers/highlight';
import { truncate } from 'flarum/common/utils/string';
import getCleanDisplayName from '../utils/getCleanDisplayName';
@@ -63,7 +63,7 @@ export default class PostMention extends MentionableModel<Post, AtMentionFormat>
return (
<>
{avatar(user)}
<Avatar user={user} />
{username}
{[
app.translator.trans('flarum-mentions.forum.composer.reply_to_post_text', { number: model.number() }),

View File

@@ -2,7 +2,7 @@ import app from 'flarum/forum/app';
import type Mithril from 'mithril';
import type User from 'flarum/common/models/User';
import usernameHelper from 'flarum/common/helpers/username';
import avatar from 'flarum/common/helpers/avatar';
import Avatar from 'flarum/common/components/Avatar';
import highlight from 'flarum/common/helpers/highlight';
import MentionableModel from './MentionableModel';
import getCleanDisplayName, { shouldUseOldFormat } from '../utils/getCleanDisplayName';
@@ -46,7 +46,7 @@ export default class UserMention extends MentionableModel<User, AtMentionFormat>
return (
<>
{avatar(model)}
<Avatar user={model} />
{username}
</>
);

View File

@@ -1,7 +1,7 @@
.PostMention, .UserMention, .GroupMention {
background: var(--control-bg);
color: var(--control-color);
border-radius: @border-radius;
border-radius: var(--border-radius);
font-weight: 600;
blockquote & {
@@ -30,10 +30,7 @@
margin-left: 0;
}
// @TODO: 2.0 use an icon in the XSLT template.
&:before {
.fas();
content: @fa-var-reply;
.icon {
margin-right: 5px;
}
}
@@ -81,7 +78,7 @@
.MentionsDropdown, .PostMention-preview, .Post-mentionedBy-preview {
// @TODO: Rename to .MentionsDropdownItem, along with child classes. 2.0
.PostPreview {
color: @muted-color;
color: var(--muted-color);
.Avatar {
.Avatar--size(24px);
@@ -93,7 +90,7 @@
}
}
.username {
color: @text-color;
color: var(--text-color);
font-weight: bold;
}
}

View File

@@ -70,40 +70,43 @@ flarum-mentions:
# These translations are used in emails sent when a post is replied to
post_mentioned:
subject: "{replier_display_name} replied to your post in {title}"
body: |
Hey {recipient_display_name}!
plain:
body: |
{replier_display_name} replied to your post (#{post_number}) in {title}.
{replier_display_name} replied to your post (#{post_number}) in {title}.
{url}
{url}
---
---
{content}
{content}
html:
body: "{replier_display_name} replied to your post (#{post_number}) in [{title}]({url})."
# These translations are used in emails sent when a user is mentioned
user_mentioned:
subject: "{mentioner_display_name} mentioned you in {title}"
body: |
Hey {recipient_display_name}!
plain:
body: |
{mentioner_display_name} mentioned you in a post in {title}.
{mentioner_display_name} mentioned you in a post in {title}.
{url}
{url}
---
---
{content}
{content}
html:
body: "{mentioner_display_name} mentioned you in a post in [{title}]({url})."
# These translations are used in emails sent when a group is mentioned
group_mentioned:
subject: "{mentioner_display_name} mentioned a group you're a member of in {title}"
body: |
Hey {recipient_display_name}!
plain:
body: |
{mentioner_display_name} mentioned a group you're a member of in {title}.
{mentioner_display_name} mentioned a group you're a member of in {title}.
{url}
{url}
---
---
{content}
{content}
html:
body: "{mentioner_display_name} mentioned a group you're a member of in [{title}]({url})."

View File

@@ -122,10 +122,10 @@ class ConfigureMentions
$tag->template = '
<xsl:choose>
<xsl:when test="@deleted != 1">
<a href="{$DISCUSSION_URL}{@discussionid}/{@number}" class="PostMention" data-id="{@id}"><xsl:value-of select="@displayname"/></a>
<a href="{$DISCUSSION_URL}{@discussionid}/{@number}" class="PostMention" data-id="{@id}"><i class="icon fas fa-reply"></i><xsl:value-of select="@displayname"/></a>
</xsl:when>
<xsl:otherwise>
<span class="PostMention PostMention--deleted" data-id="{@id}"><xsl:value-of select="@displayname"/></span>
<span class="PostMention PostMention--deleted" data-id="{@id}"><i class="icon fas fa-reply"></i><xsl:value-of select="@displayname"/></span>
</xsl:otherwise>
</xsl:choose>';

View File

@@ -47,7 +47,7 @@ class UnparsePostMentions
$attributes['displayname'] = $this->translator->trans('core.lib.username.deleted_text');
}
if (strpos($attributes['displayname'], '"#') !== false) {
if (str_contains($attributes['displayname'], '"#')) {
$attributes['displayname'] = preg_replace('/"#[a-z]{0,3}[0-9]+/', '_', $attributes['displayname']);
}
@@ -62,7 +62,7 @@ class UnparsePostMentions
{
$tagName = 'POSTMENTION';
if (strpos($xml, $tagName) === false) {
if (! str_contains($xml, $tagName)) {
return $xml;
}

View File

@@ -49,7 +49,7 @@ class UnparseTagMentions
{
$tagName = 'TAGMENTION';
if (strpos($xml, $tagName) === false) {
if (! str_contains($xml, $tagName)) {
return $xml;
}

View File

@@ -40,7 +40,7 @@ class UnparseUserMentions
$attributes['displayname'] = $user?->display_name ?? $this->translator->trans('core.lib.username.deleted_text');
if (strpos($attributes['displayname'], '"#') !== false) {
if (str_contains($attributes['displayname'], '"#')) {
$attributes['displayname'] = preg_replace('/"#[a-z]{0,3}[0-9]+/', '_', $attributes['displayname']);
}
@@ -55,7 +55,7 @@ class UnparseUserMentions
{
$tagName = 'USERMENTION';
if (strpos($xml, $tagName) === false) {
if (! str_contains($xml, $tagName)) {
return $xml;
}

View File

@@ -38,9 +38,11 @@ class GroupMentionedBlueprint implements BlueprintInterface, MailableInterface
return null;
}
public function getEmailView(): string|array
public function getEmailViews(): array
{
return ['text' => 'flarum-mentions::emails.groupMentioned'];
return [
'text' => 'flarum-mentions::emails.plain.groupMentioned',
'html' => 'flarum-mentions::emails.html.groupMentioned', ];
}
public function getEmailSubject(TranslatorInterface $translator): string

View File

@@ -39,9 +39,12 @@ class PostMentionedBlueprint implements BlueprintInterface, MailableInterface
return ['replyNumber' => (int) $this->reply->number];
}
public function getEmailView(): string|array
public function getEmailViews(): array
{
return ['text' => 'flarum-mentions::emails.postMentioned'];
return [
'text' => 'flarum-mentions::emails.plain.postMentioned',
'html' => 'flarum-mentions::emails.html.postMentioned',
];
}
public function getEmailSubject(TranslatorInterface $translator): string

View File

@@ -38,9 +38,12 @@ class UserMentionedBlueprint implements BlueprintInterface, MailableInterface
return null;
}
public function getEmailView(): string|array
public function getEmailViews(): array
{
return ['text' => 'flarum-mentions::emails.userMentioned'];
return [
'text' => 'flarum-mentions::emails.plain.userMentioned',
'html' => 'flarum-mentions::emails.html.userMentioned'
];
}
public function getEmailSubject(TranslatorInterface $translator): string

View File

@@ -0,0 +1,13 @@
@extends('flarum.forum::email.html.notification.base')
@section('notificationContent')
{!! $formatter->convert($translator->trans('flarum-mentions.email.group_mentioned.html.body', [
'{mentioner_display_name}' => $blueprint->post->user->display_name,
'{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number])
])) !!}
@endsection
@section('contentPreview')
{!! $blueprint->post->formatContent() !!}
@endsection

View File

@@ -0,0 +1,14 @@
@extends('flarum.forum::email.html.notification.base')
@section('notificationContent')
{!! $formatter->convert($translator->trans('flarum-mentions.email.post_mentioned.html.body', [
'{replier_display_name}' => $blueprint->reply->user->display_name,
'{post_number}' => $blueprint->post->number,
'{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->reply->discussion_id, 'near' => $blueprint->reply->number])
])) !!}
@endsection
@section('contentPreview')
{!! $blueprint->reply->formatContent() !!}
@endsection

View File

@@ -0,0 +1,13 @@
@extends('flarum.forum::email.html.notification.base')
@section('notificationContent')
{!! $formatter->convert($translator->trans('flarum-mentions.email.user_mentioned.html.body', [
'{mentioner_display_name}' => $blueprint->post->user->display_name,
'{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number])
])) !!}
@endsection
@section('contentPreview')
{!! $blueprint->post->formatContent() !!}
@endsection

View File

@@ -1,7 +1,10 @@
{!! $translator->trans('flarum-mentions.email.group_mentioned.body', [
'{recipient_display_name}' => $user->display_name,
@extends('flarum.forum::email.plain.notification.base')
@section('content')
{!! $translator->trans('flarum-mentions.email.group_mentioned.plain.body', [
'{mentioner_display_name}' => $blueprint->post->user->display_name,
'{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]),
'{content}' => $blueprint->post->content
]) !!}
@endsection

View File

@@ -1,8 +1,11 @@
{!! $translator->trans('flarum-mentions.email.post_mentioned.body', [
'{recipient_display_name}' => $user->display_name,
@extends('flarum.forum::email.plain.notification.base')
@section('content')
{!! $translator->trans('flarum-mentions.email.post_mentioned.plain.body', [
'{replier_display_name}' => $blueprint->reply->user->display_name,
'{post_number}' => $blueprint->post->number,
'{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->reply->discussion_id, 'near' => $blueprint->reply->number]),
'{content}' => $blueprint->reply->content
]) !!}
@endsection

View File

@@ -1,7 +1,10 @@
{!! $translator->trans('flarum-mentions.email.user_mentioned.body', [
'{recipient_display_name}' => $user->display_name,
@extends('flarum.forum::email.plain.notification.base')
@section('content')
{!! $translator->trans('flarum-mentions.email.user_mentioned.plain.body', [
'{mentioner_display_name}' => $blueprint->post->user->display_name,
'{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]),
'{content}' => $blueprint->post->content
]) !!}
@endsection

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,6 +2,7 @@ import app from 'flarum/forum/app';
import Modal from 'flarum/common/components/Modal';
import Button from 'flarum/common/components/Button';
import Stream from 'flarum/common/utils/Stream';
import Form from '@flarum/core/src/common/components/Form';
export default class NicknameModal extends Modal {
oninit(vnode) {
@@ -20,16 +21,16 @@ export default class NicknameModal extends Modal {
content() {
return (
<div className="Modal-body">
<div className="Form Form--centered">
<Form className="Form--centered">
<div className="Form-group">
<input type="text" autocomplete="off" name="nickname" className="FormControl" bidi={this.nickname} disabled={this.loading} />
</div>
<div className="Form-group">
<div className="Form-group Form-controls">
<Button className="Button Button--primary Button--block" type="submit" loading={this.loading}>
{app.translator.trans('flarum-nicknames.forum.change_nickname.submit_button')}
</Button>
</div>
</div>
</Form>
</div>
);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@ import type Mithril from 'mithril';
import app from 'flarum/admin/app';
import Component, { ComponentAttrs } from 'flarum/common/Component';
import classList from 'flarum/common/utils/classList';
import icon from 'flarum/common/helpers/icon';
import Icon from 'flarum/common/components/Icon';
import Tooltip from 'flarum/common/components/Tooltip';
import Button from 'flarum/common/components/Button';
import { Extension } from 'flarum/admin/AdminApplication';
@@ -35,7 +35,7 @@ export default class ExtensionItem<Attrs extends ExtensionItemAttrs = ExtensionI
})}
>
<div className="PackageManager-extension-icon ExtensionIcon" style={extension.icon}>
{extension.icon ? icon(extension.icon.name) : ''}
{extension.icon ? <Icon name={extension.icon.name} /> : ''}
</div>
<div className="PackageManager-extension-info">
<div className="PackageManager-extension-name">{extension.extra['flarum-extension'].title}</div>

View File

@@ -5,7 +5,7 @@ import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
import Button from 'flarum/common/components/Button';
import Tooltip from 'flarum/common/components/Tooltip';
import { Extension } from 'flarum/admin/AdminApplication';
import icon from 'flarum/common/helpers/icon';
import Icon from 'flarum/common/components/Icon';
import ItemList from 'flarum/common/utils/ItemList';
import extractText from 'flarum/common/utils/extractText';
@@ -75,7 +75,7 @@ export default class QueueSection extends Component<{}> {
return extension ? (
<div className="PackageManager-queueTable-package">
<div className="PackageManager-queueTable-package-icon ExtensionIcon" style={extension.icon}>
{!!extension.icon && icon(extension.icon.name)}
{!!extension.icon && <Icon name={extension.icon.name} />}
</div>
<div className="PackageManager-queueTable-package-details">
<span className="PackageManager-queueTable-package-title">{extension.extra['flarum-extension'].title}</span>
@@ -199,17 +199,17 @@ export default class QueueSection extends Component<{}> {
}
operationIcon(operation: TaskOperations): Mithril.Children {
return icon(
{
update_check: 'fas fa-sync-alt',
update_major: 'fas fa-play',
update_minor: 'fas fa-play',
update_global: 'fas fa-play',
extension_install: 'fas fa-download',
extension_remove: 'fas fa-times',
extension_update: 'fas fa-arrow-alt-circle-up',
why_not: 'fas fa-exclamation-circle',
}[operation]
);
const iconName = {
update_check: 'fas fa-sync-alt',
update_major: 'fas fa-play',
update_minor: 'fas fa-play',
update_global: 'fas fa-play',
extension_install: 'fas fa-download',
extension_remove: 'fas fa-times',
extension_update: 'fas fa-arrow-alt-circle-up',
why_not: 'fas fa-exclamation-circle',
}[operation];
return <Icon name={iconName} />;
}
}

View File

@@ -24,7 +24,7 @@ class TaskSerializer extends AbstractSerializer
{
if (! ($model instanceof Task)) {
throw new InvalidArgumentException(
get_class($this).' can only serialize instances of '.Task::class
$this::class.' can only serialize instances of '.Task::class
);
}

View File

@@ -45,7 +45,7 @@ class RequireExtensionHandler
$packageName = $command->package;
// Auto append :* if not requiring a specific version.
if (strpos($packageName, ':') === false) {
if (! str_contains($packageName, ':')) {
$packageName .= ':*';
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -6,7 +6,7 @@ import abbreviateNumber from 'flarum/common/utils/abbreviateNumber';
import extractText from 'flarum/common/utils/extractText';
import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
import Placeholder from 'flarum/common/components/Placeholder';
import icon from 'flarum/common/helpers/icon';
import Icon from 'flarum/common/components/Icon';
import classList from 'flarum/common/utils/classList';
import DashboardWidget, { IDashboardWidgetAttrs } from 'flarum/admin/components/DashboardWidget';
@@ -291,7 +291,7 @@ export default class StatisticsWidget extends DashboardWidget {
<>
{' '}
<span className={'StatisticsWidget-change StatisticsWidget-change--' + (periodChange > 0 ? 'up' : 'down')}>
{icon('fas fa-arrow-' + (periodChange > 0 ? 'up' : 'down'))}
<Icon name={'fas fa-arrow-' + (periodChange > 0 ? 'up' : 'down')} />
{Math.abs(periodChange).toFixed(1)}%
</span>
</>

View File

@@ -11,7 +11,7 @@
&-title {
margin: 0 20px;
color: @muted-color;
color: var(--muted-color);
}
&-entities {
@@ -29,7 +29,7 @@
min-width: 130px;
font-size: 12px;
font-weight: bold;
color: @muted-color;
color: var(--muted-color);
}
&-label {
@@ -39,7 +39,7 @@
&-entity {
min-width: 130px;
padding: 15px 20px;
color: @text-color;
color: var(--text-color);
font-size: 20px;
.StatisticsWidget:not(.StatisticsWidget--mini) & {
@@ -47,12 +47,12 @@
&:hover,
&:focus-visible {
background: mix(@control-bg, @body-bg, 50%);
background: var(--control-body-bg-mix);
text-decoration: none;
}
&.active {
border-top: 4px solid @primary-color;
border-top: 4px solid var(--primary-color);
padding-top: 11px;
}
}
@@ -75,10 +75,10 @@
font-weight: bold;
text-transform: uppercase;
font-size: 12px;
color: @muted-color;
color: var(--muted-color);
.active & {
color: @primary-color;
color: var(--primary-color);
}
}

File diff suppressed because one or more lines are too long

View File

@@ -6,7 +6,7 @@ import DiscussionPage from 'flarum/forum/components/DiscussionPage';
import IndexPage from 'flarum/forum/components/IndexPage';
import { truncate } from 'flarum/common/utils/string';
export default function addStickyControl() {
export default function addStickyExcerpt() {
extend(DiscussionListState.prototype, 'requestParams', function (params) {
if (app.current.matches(IndexPage) || app.current.matches(DiscussionPage)) {
params.include.push('firstPost');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
import 'flarum/common/models/Discussion';
declare module 'flarum/common/models/Discussion' {
export default interface Discussion {
subscription(): string;
}
}

View File

@@ -2,11 +2,12 @@ import app from 'flarum/forum/app';
import { extend } from 'flarum/common/extend';
import LinkButton from 'flarum/common/components/LinkButton';
import IndexPage from 'flarum/forum/components/IndexPage';
import IndexSidebar from 'flarum/forum/components/IndexSidebar';
import DiscussionListState from 'flarum/forum/states/DiscussionListState';
import GlobalSearchState from 'flarum/forum/states/GlobalSearchState';
export default function addSubscriptionFilter() {
extend(IndexPage.prototype, 'navItems', function (items) {
extend(IndexSidebar.prototype, 'navItems', function (items) {
if (app.session.user) {
const params = app.search.stickyParams();

View File

@@ -17,4 +17,8 @@ export default class NewPostNotification extends Notification {
content() {
return app.translator.trans('flarum-subscriptions.forum.notifications.new_post_text', { user: this.attrs.notification.fromUser() });
}
excerpt() {
return null;
}
}

View File

@@ -1,115 +0,0 @@
import app from 'flarum/forum/app';
import Dropdown from 'flarum/common/components/Dropdown';
import Button from 'flarum/common/components/Button';
import Tooltip from 'flarum/common/components/Tooltip';
import icon from 'flarum/common/helpers/icon';
import extractText from 'flarum/common/utils/extractText';
import classList from 'flarum/common/utils/classList';
import SubscriptionMenuItem from './SubscriptionMenuItem';
export default class SubscriptionMenu extends Dropdown {
oninit(vnode) {
super.oninit(vnode);
this.options = [
{
subscription: null,
icon: 'far fa-star',
label: app.translator.trans('flarum-subscriptions.forum.sub_controls.not_following_button'),
description: app.translator.trans('flarum-subscriptions.forum.sub_controls.not_following_text'),
},
{
subscription: 'follow',
icon: 'fas fa-star',
label: app.translator.trans('flarum-subscriptions.forum.sub_controls.following_button'),
description: app.translator.trans('flarum-subscriptions.forum.sub_controls.following_text'),
},
{
subscription: 'ignore',
icon: 'far fa-eye-slash',
label: app.translator.trans('flarum-subscriptions.forum.sub_controls.ignoring_button'),
description: app.translator.trans('flarum-subscriptions.forum.sub_controls.ignoring_text'),
},
];
}
view() {
const discussion = this.attrs.discussion;
const subscription = discussion.subscription();
let buttonLabel = app.translator.trans('flarum-subscriptions.forum.sub_controls.follow_button');
let buttonIcon = 'far fa-star';
const buttonClass = 'SubscriptionMenu-button--' + subscription;
switch (subscription) {
case 'follow':
buttonLabel = app.translator.trans('flarum-subscriptions.forum.sub_controls.following_button');
buttonIcon = 'fas fa-star';
break;
case 'ignore':
buttonLabel = app.translator.trans('flarum-subscriptions.forum.sub_controls.ignoring_button');
buttonIcon = 'far fa-eye-slash';
break;
default:
// no default
}
const preferences = app.session.user.preferences();
const notifyEmail = preferences['notify_newPost_email'];
const notifyAlert = preferences['notify_newPost_alert'];
const tooltipText = extractText(
app.translator.trans(
notifyEmail ? 'flarum-subscriptions.forum.sub_controls.notify_email_tooltip' : 'flarum-subscriptions.forum.sub_controls.notify_alert_tooltip'
)
);
const shouldShowTooltip = (notifyEmail || notifyAlert) && subscription === null;
const button = (
<Button
className={classList('Button', 'SubscriptionMenu-button', buttonClass)}
icon={buttonIcon}
onclick={this.saveSubscription.bind(this, discussion, ['follow', 'ignore'].indexOf(subscription) !== -1 ? null : 'follow')}
>
{buttonLabel}
</Button>
);
return (
<div className="Dropdown ButtonGroup SubscriptionMenu">
{shouldShowTooltip ? (
<Tooltip text={tooltipText} position="bottom">
{button}
</Tooltip>
) : (
button
)}
<button className={classList('Dropdown-toggle Button Button--icon', buttonClass)} data-toggle="dropdown">
{icon('fas fa-caret-down', { className: 'Button-icon' })}
</button>
<ul className="Dropdown-menu dropdown-menu Dropdown-menu--right">
{this.options.map((attrs) => (
<li>
<SubscriptionMenuItem
{...attrs}
onclick={this.saveSubscription.bind(this, discussion, attrs.subscription)}
active={subscription === attrs.subscription}
/>
</li>
))}
</ul>
</div>
);
}
saveSubscription(discussion, subscription) {
discussion.save({ subscription });
this.$('.SubscriptionMenu-button').tooltip('hide');
}
}

View File

@@ -0,0 +1,99 @@
import app from 'flarum/forum/app';
import Dropdown, { IDropdownAttrs } from 'flarum/common/components/Dropdown';
import Button from 'flarum/common/components/Button';
import extractText from 'flarum/common/utils/extractText';
import DetailedDropdownItem from 'flarum/common/components/DetailedDropdownItem';
import SplitDropdown from 'flarum/common/components/SplitDropdown';
import type Discussion from 'flarum/common/models/Discussion';
export interface ISubscriptionMenuAttrs extends IDropdownAttrs {
discussion: Discussion;
}
export default class SubscriptionMenu<CustomAttrs extends ISubscriptionMenuAttrs = ISubscriptionMenuAttrs> extends Dropdown<CustomAttrs> {
private options: any[] = [
{
subscription: null,
icon: 'far fa-star',
label: app.translator.trans('flarum-subscriptions.forum.sub_controls.not_following_button'),
description: app.translator.trans('flarum-subscriptions.forum.sub_controls.not_following_text'),
},
{
subscription: 'follow',
icon: 'fas fa-star',
label: app.translator.trans('flarum-subscriptions.forum.sub_controls.following_button'),
description: app.translator.trans('flarum-subscriptions.forum.sub_controls.following_text'),
},
{
subscription: 'ignore',
icon: 'far fa-eye-slash',
label: app.translator.trans('flarum-subscriptions.forum.sub_controls.ignoring_button'),
description: app.translator.trans('flarum-subscriptions.forum.sub_controls.ignoring_text'),
},
];
private possibleButtonAttrs: any = {
null: {
icon: 'far fa-star',
label: app.translator.trans('flarum-subscriptions.forum.sub_controls.follow_button'),
},
follow: {
icon: 'fas fa-star',
label: app.translator.trans('flarum-subscriptions.forum.sub_controls.following_button'),
},
ignore: {
icon: 'far fa-eye-slash',
label: app.translator.trans('flarum-subscriptions.forum.sub_controls.ignoring_button'),
},
};
view() {
const discussion = this.attrs.discussion;
const subscription = discussion.subscription();
const buttonAttrs = this.possibleButtonAttrs[subscription];
const preferences = app.session.user!.preferences()!;
const notifyEmail = preferences['notify_newPost_email'];
const notifyAlert = preferences['notify_newPost_alert'];
const tooltipText = extractText(
app.translator.trans(
notifyEmail ? 'flarum-subscriptions.forum.sub_controls.notify_email_tooltip' : 'flarum-subscriptions.forum.sub_controls.notify_alert_tooltip'
)
);
const shouldShowTooltip = (notifyEmail || notifyAlert) && subscription === null;
return (
<SplitDropdown
className="SubscriptionMenu"
buttonClassName={`SubscriptionMenu-button--${subscription}`}
tooltip={shouldShowTooltip ? tooltipText : null}
mainAction={
<Button
className={'SubscriptionMenu-button'}
icon={buttonAttrs.icon}
onclick={this.saveSubscription.bind(this, discussion, ['follow', 'ignore'].indexOf(subscription) !== -1 ? null : 'follow')}
>
{buttonAttrs.label}
</Button>
}
>
{this.options.map((attrs) => (
<DetailedDropdownItem
{...attrs}
onclick={this.saveSubscription.bind(this, discussion, attrs.subscription)}
active={subscription === attrs.subscription}
/>
))}
</SplitDropdown>
);
}
saveSubscription(discussion: Discussion, subscription: string | null): void {
discussion.save({ subscription });
// @ts-ignore
this.$('.SubscriptionMenu-button').tooltip('hide');
}
}

View File

@@ -1,17 +0,0 @@
import Component from 'flarum/common/Component';
import icon from 'flarum/common/helpers/icon';
export default class SubscriptionMenuItem extends Component {
view() {
return (
<button className="SubscriptionMenuItem hasIcon" onclick={this.attrs.onclick}>
{this.attrs.active && icon('fas fa-check', { className: 'Button-icon' })}
<span className="SubscriptionMenuItem-label">
{icon(this.attrs.icon, { className: 'Button-icon' })}
<strong>{this.attrs.label}</strong>
<span className="SubscriptionMenuItem-description">{this.attrs.description}</span>
</span>
</button>
);
}
}

View File

@@ -22,18 +22,3 @@
.SubscriptionMenu .Dropdown-menu {
min-width: 260px;
}
.SubscriptionMenuItem-label {
padding-left: 25px;
display: block;
white-space: normal;
& strong {
display: block;
}
}
.SubscriptionMenuItem-description {
display: block;
color: @muted-color;
font-size: 12px;
margin-top: 3px;
}

View File

@@ -51,21 +51,25 @@ flarum-subscriptions:
# These translations are used in emails sent when a post is made in a subscribed discussion
new_post:
subject: "[New Post] {title}"
body: |
Hey {recipient_display_name}!
plain:
body: |
{poster_display_name} just posted in a discussion you're following: {title}.
{poster_display_name} made a post in a discussion you're following: {title}.
To view the new activity, check out the following link:
{url}
To view the new activity, check out the following link:
{url}
---
---
{content}
{content}
---
---
You won't receive any more notifications about this discussion until you're up-to-date.
html:
body: |
{poster_display_name} just posted in a discussion you're following: [{title}]({url}).
You won't receive any more notifications about this discussion until you're up-to-date.
You won't recieve any more notifications about this discussion until you're up-to-date.
##
# REUSED TRANSLATIONS - These keys should not be used directly in code!

View File

@@ -39,9 +39,11 @@ class NewPostBlueprint implements BlueprintInterface, MailableInterface
return ['postNumber' => (int) $this->post->number];
}
public function getEmailView(): string|array
public function getEmailViews(): array
{
return ['text' => 'flarum-subscriptions::emails.newPost'];
return [
'text' => 'flarum-subscriptions::emails.plain.newPost',
'html' => 'flarum-subscriptions::emails.html.newPost', ];
}
public function getEmailSubject(TranslatorInterface $translator): string

View File

@@ -0,0 +1,13 @@
@extends('flarum.forum::email.html.notification.base')
@section('notificationContent')
{!! $formatter->convert($translator->trans('flarum-subscriptions.email.new_post.html.body', [
'{poster_display_name}' => $blueprint->post->user->display_name,
'{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number])
])) !!}
@endsection
@section('contentPreview')
{!! $blueprint->post->formatContent() !!}
@endsection

View File

@@ -1,7 +1,10 @@
{!! $translator->trans('flarum-subscriptions.email.new_post.body', [
'{recipient_display_name}' => $user->display_name,
@extends('flarum.forum::email.plain.notification.base')
@section('content')
{!! $translator->trans('flarum-subscriptions.email.new_post.plain.body', [
'{poster_display_name}' => $blueprint->post->user->display_name,
'{title}' => $blueprint->post->discussion->title,
'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]),
'{content}' => $blueprint->post->content
]) !!}
@endsection

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -6,6 +6,8 @@ import withAttr from 'flarum/common/utils/withAttr';
import ItemList from 'flarum/common/utils/ItemList';
import { getPermanentSuspensionDate } from '../helpers/suspensionHelper';
import Form from '@flarum/core/src/common/components/Form';
import FieldSet from '@flarum/core/src/common/components/FieldSet';
export default class SuspendUserModal extends Modal {
oninit(vnode) {
@@ -40,18 +42,15 @@ export default class SuspendUserModal extends Modal {
content() {
return (
<div className="Modal-body">
<div className="Form">
<div className="Form-group">
<label>{app.translator.trans('flarum-suspend.forum.suspend_user.status_heading')}</label>
<div>{this.formItems().toArray()}</div>
</div>
<Form>
{this.formItems().toArray()}
<div className="Form-group">
<div className="Form-group Form-controls">
<Button className="Button Button--primary" loading={this.loading} type="submit">
{app.translator.trans('flarum-suspend.forum.suspend_user.submit_button')}
</Button>
</div>
</div>
</Form>
</div>
);
}
@@ -109,20 +108,22 @@ export default class SuspendUserModal extends Modal {
formItems() {
const items = new ItemList();
items.add('radioItems', <div className="Form-group">{this.radioItems().toArray()}</div>, 100);
items.add(
'radioItems',
<FieldSet label={app.translator.trans('flarum-suspend.forum.suspend_user.status_heading')}>{this.radioItems().toArray()}</FieldSet>,
100
);
items.add(
'reason',
<div className="Form-group">
<label>
{app.translator.trans('flarum-suspend.forum.suspend_user.reason')}
<textarea
className="FormControl"
bidi={this.reason}
placeholder={app.translator.trans('flarum-suspend.forum.suspend_user.placeholder_optional')}
rows="2"
/>
</label>
<label>{app.translator.trans('flarum-suspend.forum.suspend_user.reason')}</label>
<textarea
className="FormControl"
bidi={this.reason}
placeholder={app.translator.trans('flarum-suspend.forum.suspend_user.placeholder_optional')}
rows="4"
/>
</div>,
90
);
@@ -130,15 +131,13 @@ export default class SuspendUserModal extends Modal {
items.add(
'message',
<div className="Form-group">
<label>
{app.translator.trans('flarum-suspend.forum.suspend_user.display_message')}
<textarea
className="FormControl"
bidi={this.message}
placeholder={app.translator.trans('flarum-suspend.forum.suspend_user.placeholder_optional')}
rows="2"
/>
</label>
<label>{app.translator.trans('flarum-suspend.forum.suspend_user.display_message')}</label>
<textarea
className="FormControl"
bidi={this.message}
placeholder={app.translator.trans('flarum-suspend.forum.suspend_user.placeholder_optional')}
rows="4"
/>
</div>,
80
);

View File

@@ -3,6 +3,7 @@ import Modal from 'flarum/common/components/Modal';
import Button from 'flarum/common/components/Button';
import fullTime from 'flarum/common/helpers/fullTime';
import { isPermanentSuspensionDate, localStorageKey } from '../helpers/suspensionHelper';
import Form from '@flarum/core/src/common/components/Form';
export default class SuspensionInfoModal extends Modal {
oninit(vnode) {
@@ -27,16 +28,16 @@ export default class SuspensionInfoModal extends Modal {
return (
<div className="Modal-body">
<div className="Form Form--centered">
<Form className="Form--centered">
<p className="helpText">{this.message}</p>
<p className="helpText">{timespan}</p>
<div className="Form-group">
<div className="Form-group Form-controls">
<Button className="Button Button--primary Button--block" onclick={this.hide.bind(this)}>
{app.translator.trans('flarum-suspend.forum.suspension_info.dismiss_button')}
</Button>
</div>
</div>
</Form>
</div>
);
}

View File

@@ -23,4 +23,8 @@ export default class UserSuspendedNotification extends Notification {
timeReadable,
});
}
excerpt() {
return null;
}
}

View File

@@ -15,4 +15,8 @@ export default class UserUnsuspendedNotification extends Notification {
return app.translator.trans('flarum-suspend.forum.notifications.user_unsuspended_text');
}
excerpt() {
return null;
}
}

View File

@@ -52,20 +52,22 @@ flarum-suspend:
no_reason_given: No reason was given for this suspension.
suspended:
subject: Your account has been suspended
body: |
Hey {recipient_display_name},
plain:
body: |
You have been suspended for the following reason:
You have been suspended for the following reason:
---
{suspension_message}
---
---
{suspension_message}
---
html:
body: "You have been suspended from {forumTitle} for the following reason:"
unsuspended:
subject: Your account has been unsuspended
body: |
Hey {recipient_display_name},
plain:
body: |
You have been unsuspended. You can head back to the forum by clicking on the following link:
You have been unsuspended. You can head back to the forum by clicking on the following link:
{forum_url}
{forum_url}
html:
body: "You have been unsuspended. You can head back to [{forumTitle}]({forum_url}) when you are ready."

View File

@@ -9,6 +9,7 @@
namespace Flarum\Suspend\Notification;
use Carbon\Carbon;
use Carbon\CarbonInterface;
use Flarum\Database\AbstractModel;
use Flarum\Locale\TranslatorInterface;
@@ -35,7 +36,7 @@ class UserSuspendedBlueprint implements BlueprintInterface, MailableInterface
public function getData(): CarbonInterface
{
return $this->user->suspended_until;
return Carbon::now();
}
public static function getType(): string
@@ -48,9 +49,11 @@ class UserSuspendedBlueprint implements BlueprintInterface, MailableInterface
return User::class;
}
public function getEmailView(): string|array
public function getEmailViews(): array
{
return ['text' => 'flarum-suspend::emails.suspended'];
return [
'text' => 'flarum-suspend::emails.plain.suspended',
'html' => 'flarum-suspend::emails.html.suspended', ];
}
public function getEmailSubject(TranslatorInterface $translator): string

View File

@@ -49,9 +49,11 @@ class UserUnsuspendedBlueprint implements BlueprintInterface, MailableInterface
return User::class;
}
public function getEmailView(): string|array
public function getEmailViews(): array
{
return ['text' => 'flarum-suspend::emails.unsuspended'];
return [
'text' => 'flarum-suspend::emails.plain.unsuspended',
'html' => 'flarum-suspend::emails.html.unsuspended', ];
}
public function getEmailSubject(TranslatorInterface $translator): string

View File

@@ -50,7 +50,7 @@ class SuspendUserTest extends TestCase
{
$response = $this->sendSuspensionRequest($authenticatedAs, $targetUserId);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(200, $response->getStatusCode(), $response->getBody()->getContents());
}
/**

View File

@@ -0,0 +1,11 @@
@extends('flarum.forum::email.html.information.base')
@section('informationContent')
{!! $formatter->convert($translator->trans('flarum-suspend.email.suspended.html.body', [
'{forumTitle}' => $settings->get('forum_title')
])) !!}
@endsection
@section('contentPreview')
{!! $formatter->convert($blueprint->user->suspend_message ?? $translator->trans('flarum-suspend.email.no_reason_given')) !!}
@endsection

View File

@@ -0,0 +1,8 @@
@extends('flarum.forum::email.html.information.base')
@section('content')
{!! $formatter->convert($translator->trans('flarum-suspend.email.unsuspended.html.body', [
'{forumTitle}' => $settings->get('forum_title'),
'{forum_url}' => $url->to('forum')->base(),
])) !!}
@endsection

View File

@@ -0,0 +1,7 @@
@extends('flarum.forum::email.plain.information.base')
@section('content')
{!! $translator->trans('flarum-suspend.email.suspended.plain.body', [
'{suspension_message}' => $blueprint->user->suspend_message ?? $translator->trans('flarum-suspend.email.no_reason_given'),
]) !!}
@endsection

View File

@@ -0,0 +1,7 @@
@extends('flarum.forum::email.plain.information.base')
@section('content')
{!! $translator->trans('flarum-suspend.email.unsuspended.plain.body', [
'{forum_url}' => $url->to('forum')->base(),
]) !!}
@endsection

View File

@@ -1,4 +0,0 @@
{!! $translator->trans('flarum-suspend.email.suspended.body', [
'{recipient_display_name}' => $user->display_name,
'{suspension_message}' => $blueprint->user->suspend_message ?? $translator->trans('flarum-suspend.email.no_reason_given'),
]) !!}

View File

@@ -1,4 +0,0 @@
{!! $translator->trans('flarum-suspend.email.unsuspended.body', [
'{recipient_display_name}' => $user->display_name,
'{forum_url}' => $url->to('forum')->base(),
]) !!}

View File

@@ -177,10 +177,14 @@ return [
(new Extend\ApiController(FlarumController\ListPostsController::class))
->addInclude('eventPostMentionsTags')
// Restricted tags should still appear as `deleted` to unauthorized users.
->loadWhere('eventPostMentionsTags', function (Relation|Builder $query, ?ServerRequestInterface $request) {
->loadWhere('eventPostMentionsTags', $restrictMentionedTags = function (Relation|Builder $query, ?ServerRequestInterface $request) {
if ($request) {
$actor = RequestUtil::getActor($request);
$query->whereVisibleTo($actor);
}
}),
(new Extend\ApiController(FlarumController\ShowDiscussionController::class))
->addInclude('posts.eventPostMentionsTags')
->loadWhere('posts.eventPostMentionsTags', $restrictMentionedTags),
];

Some files were not shown because too many files have changed in this diff Show More