mirror of
https://github.com/flarum/core.git
synced 2025-07-25 10:41:24 +02:00
Mithril 2 Update (#52)
Update for Mithril 2 - Please note that PostQuoteButton and AutocompleteDropdown are not Fragments, not Components. Accordingly, they have been moved to the components folder. Co-authored-by: Matthew Kilgore <tankerkiller125@gmail.com> Co-authored-by: Franz Liedke <franz@develophp.org>
This commit is contained in:
committed by
GitHub
parent
a48a84fcd0
commit
ea56f39a53
@@ -11,14 +11,12 @@ import highlight from 'flarum/helpers/highlight';
|
|||||||
import KeyboardNavigatable from 'flarum/utils/KeyboardNavigatable';
|
import KeyboardNavigatable from 'flarum/utils/KeyboardNavigatable';
|
||||||
import { truncate } from 'flarum/utils/string';
|
import { truncate } from 'flarum/utils/string';
|
||||||
|
|
||||||
import AutocompleteDropdown from './components/AutocompleteDropdown';
|
import AutocompleteDropdown from './fragments/AutocompleteDropdown';
|
||||||
|
|
||||||
export default function addComposerAutocomplete() {
|
export default function addComposerAutocomplete() {
|
||||||
extend(TextEditor.prototype, 'config', function(original, isInitialized) {
|
extend(TextEditor.prototype, 'oncreate', function () {
|
||||||
if (isInitialized) return;
|
|
||||||
|
|
||||||
const $container = $('<div class="ComposerBody-mentionsDropdownContainer"></div>');
|
const $container = $('<div class="ComposerBody-mentionsDropdownContainer"></div>');
|
||||||
const dropdown = new AutocompleteDropdown({items: []});
|
const dropdown = new AutocompleteDropdown();
|
||||||
const $textarea = this.$('textarea').wrap('<div class="ComposerBody-mentionsWrapper"></div>');
|
const $textarea = this.$('textarea').wrap('<div class="ComposerBody-mentionsWrapper"></div>');
|
||||||
const searched = [];
|
const searched = [];
|
||||||
let mentionStart;
|
let mentionStart;
|
||||||
@@ -77,7 +75,8 @@ export default function addComposerAutocomplete() {
|
|||||||
const makeSuggestion = function(user, replacement, content, className = '') {
|
const makeSuggestion = function(user, replacement, content, className = '') {
|
||||||
const username = usernameHelper(user);
|
const username = usernameHelper(user);
|
||||||
if (typed) {
|
if (typed) {
|
||||||
username.children[0] = highlight(username.children[0], typed);
|
username.children = [highlight(username.text, typed)];
|
||||||
|
delete username.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -150,7 +149,7 @@ export default function addComposerAutocomplete() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (suggestions.length) {
|
if (suggestions.length) {
|
||||||
dropdown.props.items = suggestions;
|
dropdown.items = suggestions;
|
||||||
m.render($container[0], dropdown.render());
|
m.render($container[0], dropdown.render());
|
||||||
|
|
||||||
dropdown.show();
|
dropdown.show();
|
||||||
|
@@ -11,7 +11,7 @@ export default function addMentionedByList() {
|
|||||||
Post.prototype.mentionedBy = Model.hasMany('mentionedBy');
|
Post.prototype.mentionedBy = Model.hasMany('mentionedBy');
|
||||||
|
|
||||||
extend(CommentPost.prototype, 'footerItems', function(items) {
|
extend(CommentPost.prototype, 'footerItems', function(items) {
|
||||||
const post = this.props.post;
|
const post = this.attrs.post;
|
||||||
const replies = post.mentionedBy();
|
const replies = post.mentionedBy();
|
||||||
|
|
||||||
if (replies && replies.length) {
|
if (replies && replies.length) {
|
||||||
@@ -21,10 +21,8 @@ export default function addMentionedByList() {
|
|||||||
.one('transitionend', function() { $(this).hide(); });
|
.one('transitionend', function() { $(this).hide(); });
|
||||||
};
|
};
|
||||||
|
|
||||||
const config = function(element, isInitialized) {
|
const oncreate = function(vnode) {
|
||||||
if (isInitialized) return;
|
const $this = $(vnode.dom);
|
||||||
|
|
||||||
const $this = $(element);
|
|
||||||
let timeout;
|
let timeout;
|
||||||
|
|
||||||
const $preview = $('<ul class="Dropdown-menu Post-mentionedBy-preview fade"/>');
|
const $preview = $('<ul class="Dropdown-menu Post-mentionedBy-preview fade"/>');
|
||||||
@@ -86,8 +84,7 @@ export default function addMentionedByList() {
|
|||||||
const user = reply.user();
|
const user = reply.user();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a href={app.route.post(reply)}
|
<a route={app.route.post(reply)}
|
||||||
config={m.route}
|
|
||||||
onclick={hidePreview}
|
onclick={hidePreview}
|
||||||
data-number={reply.number()}>
|
data-number={reply.number()}>
|
||||||
{app.session.user === user ? app.translator.trans('flarum-mentions.forum.post.you_text') : username(user)}
|
{app.session.user === user ? app.translator.trans('flarum-mentions.forum.post.you_text') : username(user)}
|
||||||
@@ -107,7 +104,7 @@ export default function addMentionedByList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
items.add('replies',
|
items.add('replies',
|
||||||
<div className="Post-mentionedBy" config={config}>
|
<div className="Post-mentionedBy" oncreate={oncreate}>
|
||||||
<span className="Post-mentionedBy-summary">
|
<span className="Post-mentionedBy-summary">
|
||||||
{icon('fas fa-reply')}
|
{icon('fas fa-reply')}
|
||||||
{app.translator.transChoice('flarum-mentions.forum.post.mentioned_by' + (repliers[0].user() === app.session.user ? '_self' : '') + '_text', names.length, {
|
{app.translator.transChoice('flarum-mentions.forum.post.mentioned_by' + (repliers[0].user() === app.session.user ? '_self' : '') + '_text', names.length, {
|
||||||
|
@@ -4,18 +4,19 @@ import PostPreview from 'flarum/components/PostPreview';
|
|||||||
import LoadingIndicator from 'flarum/components/LoadingIndicator';
|
import LoadingIndicator from 'flarum/components/LoadingIndicator';
|
||||||
|
|
||||||
export default function addPostMentionPreviews() {
|
export default function addPostMentionPreviews() {
|
||||||
extend(CommentPost.prototype, 'config', function() {
|
function addPreviews() {
|
||||||
const contentHtml = this.props.post.contentHtml();
|
const contentHtml = this.attrs.post.contentHtml();
|
||||||
|
|
||||||
if (contentHtml === this.oldPostContentHtml || this.isEditing()) return;
|
if (contentHtml === this.oldPostContentHtml || this.isEditing()) return;
|
||||||
|
|
||||||
this.oldPostContentHtml = contentHtml;
|
this.oldPostContentHtml = contentHtml;
|
||||||
|
|
||||||
const parentPost = this.props.post;
|
const parentPost = this.attrs.post;
|
||||||
const $parentPost = this.$();
|
const $parentPost = this.$();
|
||||||
|
|
||||||
this.$('.UserMention, .PostMention').each(function() {
|
this.$().on('click', '.UserMention, .PostMention', function (e) {
|
||||||
m.route.call(this, this, false, {}, {attrs: {href: this.getAttribute('href')}});
|
m.route.set(this.getAttribute('href'));
|
||||||
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$('.PostMention').each(function() {
|
this.$('.PostMention').each(function() {
|
||||||
@@ -122,5 +123,8 @@ export default function addPostMentionPreviews() {
|
|||||||
|
|
||||||
$(document).on('touchend', hidePreview);
|
$(document).on('touchend', hidePreview);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
extend(CommentPost.prototype, 'oncreate', addPreviews);
|
||||||
|
extend(CommentPost.prototype, 'onupdate', addPreviews);
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
import { extend } from 'flarum/extend';
|
import { extend } from 'flarum/extend';
|
||||||
import CommentPost from 'flarum/components/CommentPost';
|
import CommentPost from 'flarum/components/CommentPost';
|
||||||
|
|
||||||
import PostQuoteButton from './components/PostQuoteButton';
|
import PostQuoteButton from './fragments/PostQuoteButton';
|
||||||
import selectedText from './utils/selectedText';
|
import selectedText from './utils/selectedText';
|
||||||
|
|
||||||
export default function addPostQuoteButton() {
|
export default function addPostQuoteButton() {
|
||||||
extend(CommentPost.prototype, 'config', function(original, isInitialized) {
|
extend(CommentPost.prototype, 'oncreate', function() {
|
||||||
const post = this.props.post;
|
const post = this.attrs.post;
|
||||||
|
|
||||||
if (isInitialized || post.isHidden() || (app.session.user && !post.discussion().canReply())) return;
|
if (post.isHidden() || (app.session.user && !post.discussion().canReply())) return;
|
||||||
|
|
||||||
const $postBody = this.$('.Post-body');
|
const $postBody = this.$('.Post-body');
|
||||||
|
|
||||||
@@ -16,11 +16,13 @@ export default function addPostQuoteButton() {
|
|||||||
// button into it.
|
// button into it.
|
||||||
const $container = $('<div class="Post-quoteButtonContainer"></div>');
|
const $container = $('<div class="Post-quoteButtonContainer"></div>');
|
||||||
|
|
||||||
|
const button = new PostQuoteButton(post);
|
||||||
|
|
||||||
const handler = function(e) {
|
const handler = function(e) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const content = selectedText($postBody);
|
const content = selectedText($postBody);
|
||||||
if (content) {
|
if (content) {
|
||||||
const button = new PostQuoteButton({post, content});
|
button.content = content;
|
||||||
m.render($container[0], button.render());
|
m.render($container[0], button.render());
|
||||||
|
|
||||||
const rects = window.getSelection().getRangeAt(0).getClientRects();
|
const rects = window.getSelection().getRangeAt(0).getClientRects();
|
||||||
|
@@ -7,16 +7,14 @@ import reply from './utils/reply';
|
|||||||
export default function () {
|
export default function () {
|
||||||
extend(CommentPost.prototype, 'actionItems', function (items) {
|
extend(CommentPost.prototype, 'actionItems', function (items) {
|
||||||
|
|
||||||
const post = this.props.post;
|
const post = this.attrs.post;
|
||||||
|
|
||||||
if (post.isHidden() || (app.session.user && !post.discussion().canReply())) return;
|
if (post.isHidden() || (app.session.user && !post.discussion().canReply())) return;
|
||||||
|
|
||||||
items.add('reply',
|
items.add('reply',
|
||||||
Button.component({
|
<Button className='Button Button--link' onclick={() => reply(post)}>
|
||||||
className: 'Button Button--link',
|
{app.translator.trans('flarum-mentions.forum.post.reply_link')}
|
||||||
children: app.translator.trans('flarum-mentions.forum.post.reply_link'),
|
</Button>
|
||||||
onclick: () => reply(post)
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@ export default class PostMentionedNotification extends Notification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
href() {
|
href() {
|
||||||
const notification = this.props.notification;
|
const notification = this.attrs.notification;
|
||||||
const post = notification.subject();
|
const post = notification.subject();
|
||||||
const content = notification.content();
|
const content = notification.content();
|
||||||
|
|
||||||
@@ -15,13 +15,13 @@ export default class PostMentionedNotification extends Notification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
content() {
|
content() {
|
||||||
const notification = this.props.notification;
|
const notification = this.attrs.notification;
|
||||||
const user = notification.fromUser();
|
const user = notification.fromUser();
|
||||||
|
|
||||||
return app.translator.transChoice('flarum-mentions.forum.notifications.post_mentioned_text', 1, {user});
|
return app.translator.transChoice('flarum-mentions.forum.notifications.post_mentioned_text', 1, {user});
|
||||||
}
|
}
|
||||||
|
|
||||||
excerpt() {
|
excerpt() {
|
||||||
return truncate(this.props.notification.subject().contentPlain(), 200);
|
return truncate(this.attrs.notification.subject().contentPlain(), 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,53 +0,0 @@
|
|||||||
import Button from 'flarum/components/Button';
|
|
||||||
import extract from 'flarum/utils/extract';
|
|
||||||
|
|
||||||
import reply from '../utils/reply';
|
|
||||||
|
|
||||||
export default class PostQuoteButton extends Button {
|
|
||||||
view() {
|
|
||||||
const post = extract(this.props, 'post');
|
|
||||||
const content = extract(this.props, 'content');
|
|
||||||
|
|
||||||
this.props.className = 'Button PostQuoteButton';
|
|
||||||
this.props.icon = 'fas fa-quote-left';
|
|
||||||
this.props.children = app.translator.trans('flarum-mentions.forum.post.quote_button');
|
|
||||||
this.props.onclick = () => {
|
|
||||||
this.hide();
|
|
||||||
reply(post, content);
|
|
||||||
};
|
|
||||||
this.props.onmousedown = (e) => e.stopPropagation();
|
|
||||||
|
|
||||||
return super.view();
|
|
||||||
}
|
|
||||||
|
|
||||||
config(isInitialized) {
|
|
||||||
if (isInitialized) return;
|
|
||||||
|
|
||||||
$(document).on('mousedown', this.hide.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
show(left, top) {
|
|
||||||
const $this = this.$().show();
|
|
||||||
const parentOffset = $this.offsetParent().offset();
|
|
||||||
|
|
||||||
$this
|
|
||||||
.css('left', left - parentOffset.left)
|
|
||||||
.css('top', top - parentOffset.top);
|
|
||||||
}
|
|
||||||
|
|
||||||
showStart(left, top) {
|
|
||||||
const $this = this.$();
|
|
||||||
|
|
||||||
this.show(left, $(window).scrollTop() + top - $this.outerHeight() - 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
showEnd(right, bottom) {
|
|
||||||
const $this = this.$();
|
|
||||||
|
|
||||||
this.show(right - $this.outerWidth(), $(window).scrollTop() + bottom + 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
hide() {
|
|
||||||
this.$().hide();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -7,18 +7,18 @@ export default class UserMentionedNotification extends Notification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
href() {
|
href() {
|
||||||
const post = this.props.notification.subject();
|
const post = this.attrs.notification.subject();
|
||||||
|
|
||||||
return app.route.discussion(post.discussion(), post.number());
|
return app.route.discussion(post.discussion(), post.number());
|
||||||
}
|
}
|
||||||
|
|
||||||
content() {
|
content() {
|
||||||
const user = this.props.notification.fromUser();
|
const user = this.attrs.notification.fromUser();
|
||||||
|
|
||||||
return app.translator.trans('flarum-mentions.forum.notifications.user_mentioned_text', {user});
|
return app.translator.trans('flarum-mentions.forum.notifications.user_mentioned_text', {user});
|
||||||
}
|
}
|
||||||
|
|
||||||
excerpt() {
|
excerpt() {
|
||||||
return truncate(this.props.notification.subject().contentPlain(), 200);
|
return truncate(this.attrs.notification.subject().contentPlain(), 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,16 +1,15 @@
|
|||||||
import Component from 'flarum/Component';
|
import Fragment from 'flarum/Fragment';
|
||||||
|
|
||||||
export default class AutocompleteDropdown extends Component {
|
export default class AutocompleteDropdown extends Fragment {
|
||||||
init() {
|
items = [];
|
||||||
this.active = false;
|
active = false;
|
||||||
this.index = 0;
|
index = 0;
|
||||||
this.keyWasJustPressed = false;
|
keyWasJustPressed = false;
|
||||||
}
|
|
||||||
|
|
||||||
view() {
|
view() {
|
||||||
return (
|
return (
|
||||||
<ul className="Dropdown-menu MentionsDropdown">
|
<ul className="Dropdown-menu MentionsDropdown">
|
||||||
{this.props.items.map(item => <li>{item}</li>)}
|
{this.items.map(item => <li>{item}</li>)}
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -71,7 +70,7 @@ export default class AutocompleteDropdown extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof scrollTop !== 'undefined') {
|
if (typeof scrollTop !== 'undefined') {
|
||||||
$dropdown.stop(true).animate({scrollTop}, 100);
|
$dropdown.stop(true).animate({ scrollTop }, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,53 @@
|
|||||||
|
import Fragment from 'flarum/Fragment';
|
||||||
|
import icon from 'flarum/helpers/icon';
|
||||||
|
|
||||||
|
import reply from '../utils/reply';
|
||||||
|
|
||||||
|
export default class PostQuoteButton extends Fragment {
|
||||||
|
constructor(post) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.post = post;
|
||||||
|
}
|
||||||
|
|
||||||
|
view() {
|
||||||
|
return (
|
||||||
|
<button class="Button PostQuoteButton" onclick={() => {
|
||||||
|
reply(this.post, this.content);
|
||||||
|
}}>
|
||||||
|
{icon('fas fa-quote-left', { className: 'Button-icon' })}
|
||||||
|
{app.translator.trans('flarum-mentions.forum.post.quote_button')}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
show(left, top) {
|
||||||
|
const $this = this.$().show();
|
||||||
|
const parentOffset = $this.offsetParent().offset();
|
||||||
|
|
||||||
|
$this
|
||||||
|
.css('left', left - parentOffset.left)
|
||||||
|
.css('top', top - parentOffset.top);
|
||||||
|
|
||||||
|
|
||||||
|
this.hideHandler = this.hide.bind(this);
|
||||||
|
$(document).on('mouseup', this.hideHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
showStart(left, top) {
|
||||||
|
const $this = this.$();
|
||||||
|
|
||||||
|
this.show(left, $(window).scrollTop() + top - $this.outerHeight() - 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
showEnd(right, bottom) {
|
||||||
|
const $this = this.$();
|
||||||
|
|
||||||
|
this.show(right - $this.outerWidth(), $(window).scrollTop() + bottom + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
this.$().hide();
|
||||||
|
$(document).off('mouseup', this.hideHandler);
|
||||||
|
}
|
||||||
|
}
|
@@ -53,16 +53,15 @@ app.initializers.add('flarum-mentions', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Add mentions tab in user profile
|
// Add mentions tab in user profile
|
||||||
app.routes['user.mentions'] = {path: '/u/:username/mentions', component: MentionsUserPage.component()};
|
app.routes['user.mentions'] = {path: '/u/:username/mentions', component: MentionsUserPage};
|
||||||
extend(UserPage.prototype, 'navItems', function(items) {
|
extend(UserPage.prototype, 'navItems', function(items) {
|
||||||
const user = this.user;
|
const user = this.user;
|
||||||
items.add('mentions',
|
items.add('mentions',
|
||||||
LinkButton.component({
|
LinkButton.component({
|
||||||
href: app.route('user.mentions', {username: user.username()}),
|
href: app.route('user.mentions', {username: user.username()}),
|
||||||
name: 'mentions',
|
name: 'mentions',
|
||||||
children: [app.translator.trans('flarum-mentions.forum.user.mentions_link')],
|
|
||||||
icon: 'fas fa-at'
|
icon: 'fas fa-at'
|
||||||
}),
|
}, app.translator.trans('flarum-mentions.forum.user.mentions_link')),
|
||||||
80
|
80
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user