1
0
mirror of https://github.com/flarum/core.git synced 2025-08-26 01:34:16 +02:00

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
This commit is contained in:
Sami Mazouz
2023-10-10 21:36:08 +01:00
committed by GitHub
parent 24d13e33bb
commit 5ab5257ff5
174 changed files with 2671 additions and 2056 deletions

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>
);
}
}