mirror of
https://github.com/flarum/core.git
synced 2025-08-14 12:24:33 +02:00
Compare commits
22 Commits
as/cleanup
...
as/discuss
Author | SHA1 | Date | |
---|---|---|---|
|
641330ce52 | ||
|
656409794c | ||
|
245f3c6846 | ||
|
962b49567c | ||
|
12498b7620 | ||
|
84f7d29d8c | ||
|
561e8c6b6a | ||
|
ad9917f0d6 | ||
|
6977c24dd8 | ||
|
d1b72429ac | ||
|
63692f12c5 | ||
|
441ccec8e7 | ||
|
414b0ff6d3 | ||
|
2ff0e1efcb | ||
|
8c46b37a6f | ||
|
9be629cfcc | ||
|
df9be1b063 | ||
|
97c36f2f7d | ||
|
13efd02085 | ||
|
0b44c48433 | ||
|
b562072471 | ||
|
718445cb0c |
4
js/dist/admin.js
vendored
4
js/dist/admin.js
vendored
File diff suppressed because one or more lines are too long
2
js/dist/admin.js.map
vendored
2
js/dist/admin.js.map
vendored
File diff suppressed because one or more lines are too long
4
js/dist/forum.js
vendored
4
js/dist/forum.js
vendored
File diff suppressed because one or more lines are too long
2
js/dist/forum.js.map
vendored
2
js/dist/forum.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -272,7 +272,7 @@ export default class Application {
|
||||
/**
|
||||
* Make an AJAX request, handling any low-level errors that may occur.
|
||||
*
|
||||
* @see https://lhorie.github.io/mithril/mithril.request.html
|
||||
* @see https://mithril.js.org/request.html
|
||||
* @param {Object} options
|
||||
* @return {Promise}
|
||||
* @public
|
||||
|
@@ -12,9 +12,6 @@ export default class Page extends Component {
|
||||
|
||||
this.onNewRoute();
|
||||
|
||||
app.drawer.hide();
|
||||
app.modal.close();
|
||||
|
||||
/**
|
||||
* A class name to apply to the body while the route is active.
|
||||
*
|
||||
@@ -32,6 +29,9 @@ export default class Page extends Component {
|
||||
onNewRoute() {
|
||||
app.previous = app.current;
|
||||
app.current = new PageState(this.constructor, { routeName: this.attrs.routeName });
|
||||
|
||||
app.drawer.hide();
|
||||
app.modal.close();
|
||||
}
|
||||
|
||||
oncreate(vnode) {
|
||||
|
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* The `icon` helper displays an icon.
|
||||
*
|
||||
* @param {String} fontClass The full icon class, prefix and the icon’s name.
|
||||
* @param {Object} attrs Any other attributes to apply.
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function icon(fontClass, attrs = {}) {
|
||||
attrs.className = 'icon ' + fontClass + ' ' + (attrs.className || '');
|
||||
|
||||
return <i {...attrs} />;
|
||||
}
|
13
js/src/common/helpers/icon.tsx
Normal file
13
js/src/common/helpers/icon.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import * as Mithril from 'mithril';
|
||||
|
||||
/**
|
||||
* The `icon` helper displays an icon.
|
||||
*
|
||||
* @param fontClass The full icon class, prefix and the icon’s name.
|
||||
* @param attrs Any other attributes to apply.
|
||||
*/
|
||||
export default function icon(fontClass: string, attrs: Mithril.Attributes = {}): Mithril.Vnode {
|
||||
attrs.className = 'icon ' + fontClass + ' ' + (attrs.className || '');
|
||||
|
||||
return <i {...attrs} />;
|
||||
}
|
@@ -28,6 +28,9 @@ export default class SubtreeRetainer {
|
||||
constructor(...callbacks) {
|
||||
this.callbacks = callbacks;
|
||||
this.data = {};
|
||||
// Build the initial data, so it is available when calling
|
||||
// needsRebuild from the onbeforeupdate hook.
|
||||
this.needsRebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +63,8 @@ export default class SubtreeRetainer {
|
||||
*/
|
||||
check(...callbacks) {
|
||||
this.callbacks = this.callbacks.concat(callbacks);
|
||||
// Update the data cache when new checks are added.
|
||||
this.needsRebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -52,6 +52,7 @@ export default class DiscussionPage extends Page {
|
||||
}
|
||||
|
||||
onremove() {
|
||||
super.onremove();
|
||||
// If we are indeed navigating away from this discussion, then disable the
|
||||
// discussion list pane. Also, if we're composing a reply to this
|
||||
// discussion, minimize the composer – unless it's empty, in which case
|
||||
@@ -98,28 +99,12 @@ export default class DiscussionPage extends Page {
|
||||
onbeforeupdate(vnode) {
|
||||
super.onbeforeupdate(vnode);
|
||||
|
||||
if (m.route.get() !== this.prevRoute) {
|
||||
this.onNewRoute();
|
||||
const idParam = m.route.param('id');
|
||||
if (m.route.get() !== this.prevRoute && this.discussion && (!idParam || idParam.split('-')[0] !== this.discussion.id())) {
|
||||
this.prevRoute = m.route.get();
|
||||
|
||||
// If we have routed to the same discussion as we were viewing previously,
|
||||
// cancel the unloading of this controller and instead prompt the post
|
||||
// stream to jump to the new 'near' param.
|
||||
if (this.discussion) {
|
||||
const idParam = m.route.param('id');
|
||||
|
||||
if (idParam && idParam.split('-')[0] === this.discussion.id()) {
|
||||
const near = m.route.param('near') || '1';
|
||||
|
||||
if (near !== String(this.near)) {
|
||||
this.stream.goToNumber(near);
|
||||
}
|
||||
|
||||
this.near = near;
|
||||
} else {
|
||||
this.oninit(vnode);
|
||||
}
|
||||
}
|
||||
this.onNewRoute();
|
||||
this.oninit(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,15 +174,19 @@ export default class DiscussionPage extends Page {
|
||||
.slice(0, 20);
|
||||
}
|
||||
|
||||
const startNumber = m.route.param('near') || (includedPosts[0] && includedPosts[0].number());
|
||||
|
||||
// Set up the post stream for this discussion, along with the first page of
|
||||
// posts we want to display. Tell the stream to scroll down and highlight
|
||||
// the specific post that was routed to.
|
||||
this.stream = new PostStreamState(discussion, includedPosts);
|
||||
this.stream.goToNumber(m.route.param('near') || (includedPosts[0] && includedPosts[0].number()), true).then(() => {
|
||||
this.stream.goToNumber(startNumber, true).then(() => {
|
||||
this.discussion = discussion;
|
||||
|
||||
app.current.set('discussion', discussion);
|
||||
app.current.set('stream', this.stream);
|
||||
|
||||
this.positionChanged(startNumber);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -359,9 +359,6 @@ export default class PostStream extends Component {
|
||||
|
||||
return Promise.all([$container.promise(), this.stream.loadPromise]).then(() => {
|
||||
m.redraw.sync();
|
||||
// We want to adjust this again after posts have been loaded in so that
|
||||
// the height of the scrubber is accurate.
|
||||
updateScrubberHeight();
|
||||
|
||||
// After post data has been loaded in, we will attempt to scroll back
|
||||
// to the top of the requested post (or to the top of the page if the
|
||||
@@ -377,6 +374,10 @@ export default class PostStream extends Component {
|
||||
$(window).scrollTop($(`.PostStream-item[data-index=${index}]`).offset().top - this.getMarginTop());
|
||||
}
|
||||
|
||||
// We want to adjust this again after posts have been loaded in
|
||||
// and position adjusted so that the scrubber's height is accurate.
|
||||
updateScrubberHeight();
|
||||
|
||||
this.calculatePosition();
|
||||
this.stream.paused = false;
|
||||
});
|
||||
|
@@ -33,7 +33,7 @@ export default class ReplyPlaceholder extends Component {
|
||||
}
|
||||
|
||||
const reply = () => {
|
||||
DiscussionControls.replyAction.call(this.attrs.discussion, true);
|
||||
DiscussionControls.replyAction.call(this.attrs.discussion, true).catch(() => {});
|
||||
};
|
||||
|
||||
return (
|
||||
|
@@ -82,7 +82,7 @@ abstract class AbstractModel extends Eloquent
|
||||
}
|
||||
|
||||
$this->attributes = array_map(function ($item) {
|
||||
return is_callable($item) ? $item() : $item;
|
||||
return is_callable($item) ? $item($this) : $item;
|
||||
}, $this->attributes);
|
||||
|
||||
parent::__construct($attributes);
|
||||
|
@@ -12,7 +12,7 @@ namespace Flarum\User\Event;
|
||||
use Flarum\User\User;
|
||||
|
||||
/**
|
||||
* @deprecated beta 14, removed beta 15.
|
||||
* @deprecated beta 14, remove in beta 15.
|
||||
*/
|
||||
class GetDisplayName
|
||||
{
|
||||
|
@@ -722,7 +722,7 @@ class User extends AbstractModel
|
||||
$groupIds = array_merge($groupIds, [Group::MEMBER_ID], $this->groups->pluck('id')->all());
|
||||
}
|
||||
|
||||
// Deprecated, remove in beta 14.
|
||||
/** @deprecated in beta 14, remove in beta 15 */
|
||||
event(new PrepareUserGroups($this, $groupIds));
|
||||
|
||||
foreach (static::$groupProcessors as $processor) {
|
||||
|
@@ -51,7 +51,7 @@ class UserValidator extends AbstractValidator
|
||||
],
|
||||
'email' => [
|
||||
'required',
|
||||
'email',
|
||||
'email:filter',
|
||||
'unique:users,email'.$idSuffix
|
||||
],
|
||||
'password' => [
|
||||
|
@@ -16,7 +16,7 @@ use Flarum\Tests\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Tests\integration\TestCase;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Bus\Dispatcher;
|
||||
use Illuminate\Contracts\Translation\Translator;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
|
||||
class EventTest extends TestCase
|
||||
{
|
||||
@@ -87,7 +87,7 @@ class CustomListener
|
||||
{
|
||||
protected $translator;
|
||||
|
||||
public function __construct(Translator $translator)
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
@@ -277,7 +277,7 @@ class ModelTest extends TestCase
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Model(Group::class))
|
||||
->default('counter', function () {
|
||||
->default('counter', function (Group $group) {
|
||||
static $counter = 0;
|
||||
|
||||
return ++$counter;
|
||||
|
Reference in New Issue
Block a user