mirror of
https://github.com/flarum/framework.git
synced 2025-01-19 18:12:59 +08:00
Initial commit
This commit is contained in:
commit
5ea3579f76
4
extensions/subscriptions/.gitignore
vendored
Normal file
4
extensions/subscriptions/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/vendor
|
||||
composer.phar
|
||||
.DS_Store
|
||||
Thumbs.db
|
21
extensions/subscriptions/LICENSE.txt
Normal file
21
extensions/subscriptions/LICENSE.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015 Toby Zerner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
9
extensions/subscriptions/bootstrap.php
Normal file
9
extensions/subscriptions/bootstrap.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
// Require the extension's composer autoload file. This will enable all of our
|
||||
// classes in the src directory to be autoloaded.
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
// Register our service provider with the Flarum application. In here we can
|
||||
// register bindings and execute code when the application boots.
|
||||
return $this->app->register('Flarum\Subscriptions\SubscriptionsServiceProvider');
|
7
extensions/subscriptions/composer.json
Normal file
7
extensions/subscriptions/composer.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Flarum\\Subscriptions\\": "src/"
|
||||
}
|
||||
}
|
||||
}
|
16
extensions/subscriptions/flarum.json
Normal file
16
extensions/subscriptions/flarum.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "flarum-subscriptions",
|
||||
"title": "Subscriptions",
|
||||
"description": "Allow users to follow discussions and receive notifications for new posts.",
|
||||
"tags": [],
|
||||
"version": "0.1.0",
|
||||
"author": {
|
||||
"name": "Toby Zerner",
|
||||
"email": "toby@flarum.org"
|
||||
},
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": ">=5.4.0",
|
||||
"flarum": ">0.1.0"
|
||||
}
|
||||
}
|
3
extensions/subscriptions/js/.gitignore
vendored
Normal file
3
extensions/subscriptions/js/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
bower_components
|
||||
node_modules
|
||||
dist
|
5
extensions/subscriptions/js/Gulpfile.js
Normal file
5
extensions/subscriptions/js/Gulpfile.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
var gulp = require('flarum-gulp');
|
||||
|
||||
gulp({
|
||||
modulePrefix: 'flarum-subscriptions'
|
||||
});
|
93
extensions/subscriptions/js/bootstrap.js
vendored
Normal file
93
extensions/subscriptions/js/bootstrap.js
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
import { extend, override } from 'flarum/extension-utils';
|
||||
import app from 'flarum/app';
|
||||
import Model from 'flarum/model';
|
||||
import Component from 'flarum/component';
|
||||
import Discussion from 'flarum/models/discussion';
|
||||
import Badge from 'flarum/components/badge';
|
||||
import ActionButton from 'flarum/components/action-button';
|
||||
import SettingsPage from 'flarum/components/settings-page';
|
||||
import DiscussionPage from 'flarum/components/discussion-page';
|
||||
import IndexPage from 'flarum/components/index-page';
|
||||
import IndexNavItem from 'flarum/components/index-nav-item';
|
||||
import DiscussionList from 'flarum/components/discussion-list';
|
||||
import icon from 'flarum/helpers/icon';
|
||||
|
||||
import SubscriptionMenu from 'flarum-subscriptions/components/subscription-menu';
|
||||
import NewPostNotification from 'flarum-subscriptions/components/new-post-notification';
|
||||
|
||||
app.initializers.add('flarum-subscriptions', function() {
|
||||
|
||||
app.notificationComponentRegistry['newPost'] = NewPostNotification;
|
||||
|
||||
Discussion.prototype.subscription = Model.prop('subscription');
|
||||
|
||||
// Add subscription badges to discussions.
|
||||
extend(Discussion.prototype, 'badges', function(badges) {
|
||||
var badge;
|
||||
|
||||
switch (this.subscription()) {
|
||||
case 'follow':
|
||||
badge = Badge.component({ label: 'Following', icon: 'star', className: 'badge-follow' });
|
||||
break;
|
||||
|
||||
case 'ignore':
|
||||
badge = Badge.component({ label: 'Ignoring', icon: 'eye-slash', className: 'badge-ignore' });
|
||||
}
|
||||
|
||||
if (badge) {
|
||||
badges.add('subscription', badge);
|
||||
}
|
||||
});
|
||||
|
||||
extend(Discussion.prototype, 'userControls', function(items, context) {
|
||||
if (app.session.user() && !(context instanceof DiscussionPage)) {
|
||||
var states = {
|
||||
none: {label: 'Follow', icon: 'star', save: 'follow'},
|
||||
follow: {label: 'Unfollow', icon: 'star-o', save: false},
|
||||
ignore: {label: 'Unignore', icon: 'eye', save: false}
|
||||
};
|
||||
var subscription = this.subscription() || 'none';
|
||||
|
||||
items.add('subscription', ActionButton.component({
|
||||
label: states[subscription].label,
|
||||
icon: states[subscription].icon,
|
||||
onclick: this.save.bind(this, {subscription: states[subscription].save})
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
extend(DiscussionPage.prototype, 'sidebarItems', function(items) {
|
||||
if (app.session.user()) {
|
||||
var discussion = this.discussion();
|
||||
items.add('subscription', SubscriptionMenu.component({discussion}), {after: 'controls'});
|
||||
}
|
||||
});
|
||||
|
||||
extend(IndexPage.prototype, 'navItems', function(items) {
|
||||
if (app.session.user()) {
|
||||
var params = this.stickyParams();
|
||||
params.filter = 'following';
|
||||
|
||||
items.add('following', IndexNavItem.component({
|
||||
href: app.route('index.filter', params),
|
||||
label: 'Following',
|
||||
icon: 'star'
|
||||
}), {after: 'allDiscussions'});
|
||||
}
|
||||
});
|
||||
|
||||
extend(DiscussionList.prototype, 'params', function(params) {
|
||||
if (params.filter === 'following') {
|
||||
params.q = (params.q || '')+' is:following';
|
||||
}
|
||||
});
|
||||
|
||||
// Add a notification preference.
|
||||
extend(SettingsPage.prototype, 'notificationTypes', function(items) {
|
||||
items.add('newPost', {
|
||||
name: 'newPost',
|
||||
label: [icon('star'), " Someone posts in a discussion I'm following"]
|
||||
});
|
||||
});
|
||||
|
||||
});
|
7
extensions/subscriptions/js/package.json
Normal file
7
extensions/subscriptions/js/package.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"gulp": "^3.8.11",
|
||||
"flarum-gulp": "git+https://github.com/flarum/gulp.git"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import Notification from 'flarum/components/notification';
|
||||
import username from 'flarum/helpers/username';
|
||||
|
||||
export default class NewPostNotification extends Notification {
|
||||
view() {
|
||||
var notification = this.props.notification;
|
||||
var discussion = notification.subject();
|
||||
var content = notification.content() || {};
|
||||
|
||||
return super.view({
|
||||
href: app.route.discussion(discussion, content.postNumber),
|
||||
icon: 'star',
|
||||
content: [username(notification.sender()), ' posted']
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import Component from 'flarum/component';
|
||||
import icon from 'flarum/helpers/icon';
|
||||
|
||||
export default class SubscriptionMenuItem extends Component {
|
||||
view() {
|
||||
return m('a.subscription-menu-item.has-icon[href=javascript:;]', {
|
||||
onclick: this.props.onclick
|
||||
}, [
|
||||
this.props.active ? icon('check icon') : '',
|
||||
m('span.label',
|
||||
icon(this.props.icon+' icon'),
|
||||
m('strong', this.props.label),
|
||||
m('span.description', this.props.description)
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import Component from 'flarum/component';
|
||||
import ActionButton from 'flarum/components/action-button';
|
||||
import icon from 'flarum/helpers/icon';
|
||||
|
||||
import SubscriptionMenuItem from 'flarum-subscriptions/components/subscription-menu-item';
|
||||
|
||||
export default class SubscriptionMenu extends Component {
|
||||
view() {
|
||||
var discussion = this.props.discussion;
|
||||
var subscription = discussion.subscription();
|
||||
|
||||
var buttonLabel = 'Follow';
|
||||
var buttonIcon = 'star-o';
|
||||
var buttonClass = 'btn-subscription-'+subscription;
|
||||
|
||||
switch (subscription) {
|
||||
case 'follow':
|
||||
buttonLabel = 'Following';
|
||||
buttonIcon = 'star';
|
||||
break;
|
||||
|
||||
case 'ignore':
|
||||
buttonLabel = 'Ignoring';
|
||||
buttonIcon = 'eye-slash';
|
||||
}
|
||||
|
||||
var options = [
|
||||
{subscription: false, icon: 'star-o', label: 'Not Following', description: 'Be notified when @mentioned.'},
|
||||
{subscription: 'follow', icon: 'star', label: 'Following', description: 'Be notified of all replies.'},
|
||||
{subscription: 'ignore', icon: 'eye-slash', label: 'Ignoring', description: 'Never be notified. Hide from the discussion list.'}
|
||||
];
|
||||
|
||||
return m('div.dropdown.btn-group.subscription-menu', [
|
||||
ActionButton.component({
|
||||
className: 'btn btn-default '+buttonClass,
|
||||
icon: buttonIcon,
|
||||
label: buttonLabel,
|
||||
onclick: this.saveSubscription.bind(this, discussion, ['follow', 'ignore'].indexOf(subscription) !== -1 ? false : 'follow')
|
||||
}),
|
||||
|
||||
m('a.dropdown-toggle.btn.btn-default.btn-icon[href=javascript:;][data-toggle=dropdown]', {className: buttonClass}, icon('caret-down icon-caret')),
|
||||
|
||||
m('ul.dropdown-menu.pull-right', options.map(props => {
|
||||
props.onclick = this.saveSubscription.bind(this, discussion, props.subscription);
|
||||
props.active = subscription === props.subscription;
|
||||
return m('li', SubscriptionMenuItem.component(props));
|
||||
}))
|
||||
]);
|
||||
}
|
||||
|
||||
saveSubscription(discussion, subscription) {
|
||||
discussion.save({subscription});
|
||||
}
|
||||
}
|
29
extensions/subscriptions/less/extension.less
Normal file
29
extensions/subscriptions/less/extension.less
Normal file
|
@ -0,0 +1,29 @@
|
|||
.badge-follow {
|
||||
background: #fc0;
|
||||
}
|
||||
.badge-ignore {
|
||||
background: #aaa;
|
||||
}
|
||||
.btn-subscription-follow {
|
||||
.button-variant(#de8e00, #fff2ae, #fff2ae);
|
||||
}
|
||||
.subscription-menu .dropdown-menu {
|
||||
min-width: 260px;
|
||||
}
|
||||
.subscription-menu-item {
|
||||
& .label {
|
||||
padding-left: 25px;
|
||||
display: block;
|
||||
white-space: normal;
|
||||
|
||||
& strong {
|
||||
display: block;
|
||||
}
|
||||
& .description {
|
||||
display: block;
|
||||
color: @fl-body-muted-color;
|
||||
font-size: 12px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
}
|
2
extensions/subscriptions/locale/en.yml
Normal file
2
extensions/subscriptions/locale/en.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
flarum-subscriptions:
|
||||
# hello_world: Hello, world!
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddSubscriptionToUsersDiscussionsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
app('db')->getSchemaBuilder()->table('users_discussions', function (Blueprint $table) {
|
||||
$table->enum('subscription', ['follow', 'ignore'])->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
app('db')->getSchemaBuilder()->table('users_discussions', function (Blueprint $table) {
|
||||
$table->dropColumn('subscription');
|
||||
});
|
||||
}
|
||||
}
|
72
extensions/subscriptions/src/Handlers/NewPostNotifier.php
Executable file
72
extensions/subscriptions/src/Handlers/NewPostNotifier.php
Executable file
|
@ -0,0 +1,72 @@
|
|||
<?php namespace Flarum\Subscriptions\Handlers;
|
||||
|
||||
use Flarum\Subscriptions\NewPostNotification;
|
||||
use Flarum\Core\Events\PostWasPosted;
|
||||
use Flarum\Core\Events\PostWasHidden;
|
||||
use Flarum\Core\Events\PostWasRestored;
|
||||
use Flarum\Core\Events\PostWasDeleted;
|
||||
use Flarum\Core\Notifications\NotificationSyncer;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class NewPostNotifier
|
||||
{
|
||||
protected $notifications;
|
||||
|
||||
public function __construct(NotificationSyncer $notifications)
|
||||
{
|
||||
$this->notifications = $notifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the listeners for the subscriber.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||
*/
|
||||
public function subscribe(Dispatcher $events)
|
||||
{
|
||||
// Register with '1' as priority so this runs before discussion metadata
|
||||
// is updated, as we need to compare the user's last read number to that
|
||||
// of the previous post.
|
||||
$events->listen('Flarum\Core\Events\PostWasPosted', __CLASS__.'@whenPostWasPosted', 1);
|
||||
$events->listen('Flarum\Core\Events\PostWasHidden', __CLASS__.'@whenPostWasHidden');
|
||||
$events->listen('Flarum\Core\Events\PostWasRestored', __CLASS__.'@whenPostWasRestored');
|
||||
$events->listen('Flarum\Core\Events\PostWasDeleted', __CLASS__.'@whenPostWasDeleted');
|
||||
}
|
||||
|
||||
public function whenPostWasPosted(PostWasPosted $event)
|
||||
{
|
||||
$post = $event->post;
|
||||
$discussion = $post->discussion;
|
||||
|
||||
$notify = $discussion->readers()
|
||||
->where('users.id', '!=', $post->user_id)
|
||||
->where('users_discussions.subscription', 'follow')
|
||||
->where('users_discussions.read_number', $discussion->last_post_number)
|
||||
->get();
|
||||
|
||||
$this->notifications->sync(
|
||||
$this->getNotification($event->post),
|
||||
$notify->all()
|
||||
);
|
||||
}
|
||||
|
||||
public function whenPostWasHidden(PostWasHidden $event)
|
||||
{
|
||||
$this->notifications->delete($this->getNotification($event->post));
|
||||
}
|
||||
|
||||
public function whenPostWasRestored(PostWasRestored $event)
|
||||
{
|
||||
$this->notifications->restore($this->getNotification($event->post));
|
||||
}
|
||||
|
||||
public function whenPostWasDeleted(PostWasDeleted $event)
|
||||
{
|
||||
$this->notifications->delete($this->getNotification($event->post));
|
||||
}
|
||||
|
||||
protected function getNotification($post)
|
||||
{
|
||||
return new NewPostNotification($post);
|
||||
}
|
||||
}
|
31
extensions/subscriptions/src/Handlers/SubscriptionSaver.php
Executable file
31
extensions/subscriptions/src/Handlers/SubscriptionSaver.php
Executable file
|
@ -0,0 +1,31 @@
|
|||
<?php namespace Flarum\Subscriptions\Handlers;
|
||||
|
||||
use Flarum\Core\Events\DiscussionWillBeSaved;
|
||||
|
||||
class SubscriptionSaver
|
||||
{
|
||||
public function subscribe($events)
|
||||
{
|
||||
$events->listen('Flarum\Core\Events\DiscussionWillBeSaved', __CLASS__.'@whenDiscussionWillBeSaved');
|
||||
}
|
||||
|
||||
public function whenDiscussionWillBeSaved(DiscussionWillBeSaved $event)
|
||||
{
|
||||
$discussion = $event->discussion;
|
||||
$data = $event->command->data;
|
||||
|
||||
if (isset($data['subscription'])) {
|
||||
$user = $event->command->user;
|
||||
$subscription = $data['subscription'];
|
||||
|
||||
$state = $discussion->stateFor($user);
|
||||
|
||||
if (! in_array($subscription, ['follow', 'ignore'])) {
|
||||
$subscription = null;
|
||||
}
|
||||
|
||||
$state->subscription = $subscription;
|
||||
$state->save();
|
||||
}
|
||||
}
|
||||
}
|
26
extensions/subscriptions/src/Handlers/SubscriptionSearchModifier.php
Executable file
26
extensions/subscriptions/src/Handlers/SubscriptionSearchModifier.php
Executable file
|
@ -0,0 +1,26 @@
|
|||
<?php namespace Flarum\Subscriptions\Handlers;
|
||||
|
||||
use Flarum\Core\Events\DiscussionSearchWillBePerformed;
|
||||
|
||||
class SubscriptionSearchModifier
|
||||
{
|
||||
public function subscribe($events)
|
||||
{
|
||||
$events->listen('Flarum\Core\Events\DiscussionSearchWillBePerformed', __CLASS__.'@filterIgnored');
|
||||
}
|
||||
|
||||
public function filterIgnored(DiscussionSearchWillBePerformed $event)
|
||||
{
|
||||
if (! $event->criteria->query) {
|
||||
// might be better as `id IN (subquery)`?
|
||||
$user = $event->criteria->user;
|
||||
$event->searcher->getQuery()->whereNotExists(function ($query) use ($user) {
|
||||
$query->select(app('db')->raw(1))
|
||||
->from('users_discussions')
|
||||
->whereRaw('discussion_id = discussions.id')
|
||||
->where('user_id', $user->id)
|
||||
->where('subscription', 'ignore');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
55
extensions/subscriptions/src/NewPostNotification.php
Normal file
55
extensions/subscriptions/src/NewPostNotification.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php namespace Flarum\Subscriptions;
|
||||
|
||||
use Flarum\Core\Models\Post;
|
||||
use Flarum\Core\Models\User;
|
||||
use Flarum\Core\Notifications\NotificationAbstract;
|
||||
|
||||
class NewPostNotification extends NotificationAbstract
|
||||
{
|
||||
public $post;
|
||||
|
||||
public function __construct(Post $post)
|
||||
{
|
||||
$this->post = $post;
|
||||
}
|
||||
|
||||
public function getSubject()
|
||||
{
|
||||
return $this->post->discussion;
|
||||
}
|
||||
|
||||
public function getSender()
|
||||
{
|
||||
return $this->post->user;
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
return ['postNumber' => (int) $this->post->number];
|
||||
}
|
||||
|
||||
public function getEmailView()
|
||||
{
|
||||
return ['text' => 'flarum-subscriptions::emails.newPost'];
|
||||
}
|
||||
|
||||
public function getEmailSubject()
|
||||
{
|
||||
return '[New Post] '.$this->post->discussion->title;
|
||||
}
|
||||
|
||||
public static function getType()
|
||||
{
|
||||
return 'newPost';
|
||||
}
|
||||
|
||||
public static function getSubjectModel()
|
||||
{
|
||||
return 'Flarum\Core\Models\Discussion';
|
||||
}
|
||||
|
||||
public static function isEmailable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
37
extensions/subscriptions/src/SubscriptionGambit.php
Normal file
37
extensions/subscriptions/src/SubscriptionGambit.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php namespace Flarum\Subscriptions;
|
||||
|
||||
use Flarum\Core\Search\SearcherInterface;
|
||||
use Flarum\Core\Search\GambitAbstract;
|
||||
|
||||
class SubscriptionGambit extends GambitAbstract
|
||||
{
|
||||
/**
|
||||
* The gambit's regex pattern.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $pattern = 'is:(follow|ignor)(?:ing|ed)';
|
||||
|
||||
/**
|
||||
* Apply conditions to the searcher, given matches from the gambit's
|
||||
* regex.
|
||||
*
|
||||
* @param array $matches The matches from the gambit's regex.
|
||||
* @param \Flarum\Core\Search\SearcherInterface $searcher
|
||||
* @return void
|
||||
*/
|
||||
protected function conditions(SearcherInterface $searcher, array $matches, $negate)
|
||||
{
|
||||
$user = $searcher->getUser();
|
||||
|
||||
// might be better as `id IN (subquery)`?
|
||||
$method = $negate ? 'whereNotExists' : 'whereExists';
|
||||
$searcher->getQuery()->$method(function ($query) use ($user, $matches) {
|
||||
$query->select(app('db')->raw(1))
|
||||
->from('users_discussions')
|
||||
->whereRaw('discussion_id = discussions.id')
|
||||
->where('user_id', $user->id)
|
||||
->where('subscription', $matches[1] === 'follow' ? 'follow' : 'ignore');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php namespace Flarum\Subscriptions;
|
||||
|
||||
use Flarum\Support\ServiceProvider;
|
||||
use Flarum\Extend;
|
||||
|
||||
class SubscriptionsServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->loadViewsFrom(__DIR__.'/../views', 'flarum-subscriptions');
|
||||
|
||||
$this->extend([
|
||||
(new Extend\Locale('en'))->translations(__DIR__.'/../locale/en.yml'),
|
||||
|
||||
(new Extend\ForumClient())
|
||||
->assets([
|
||||
__DIR__.'/../js/dist/extension.js',
|
||||
__DIR__.'/../less/extension.less'
|
||||
])
|
||||
->translations([
|
||||
// Add the keys of translations you would like to be available
|
||||
// for use by the JS client application.
|
||||
])
|
||||
->route('get', '/following', 'flarum.forum.following'),
|
||||
|
||||
(new Extend\ApiSerializer('Flarum\Api\Serializers\DiscussionSerializer'))
|
||||
->attributes(function (&$attributes, $discussion, $user) {
|
||||
if ($state = $discussion->stateFor($user)) {
|
||||
$attributes['subscription'] = $state->subscription ?: false;
|
||||
}
|
||||
}),
|
||||
|
||||
new Extend\EventSubscriber('Flarum\Subscriptions\Handlers\SubscriptionSaver'),
|
||||
new Extend\EventSubscriber('Flarum\Subscriptions\Handlers\SubscriptionSearchModifier'),
|
||||
new Extend\EventSubscriber('Flarum\Subscriptions\Handlers\NewPostNotifier'),
|
||||
|
||||
new Extend\DiscussionGambit('Flarum\Subscriptions\SubscriptionGambit'),
|
||||
|
||||
(new Extend\NotificationType('Flarum\Subscriptions\NewPostNotification', 'Flarum\Api\Serializers\DiscussionBasicSerializer'))
|
||||
->enableByDefault('alert')
|
||||
->enableByDefault('email')
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
14
extensions/subscriptions/views/emails/newPost.blade.php
Normal file
14
extensions/subscriptions/views/emails/newPost.blade.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
Hey {{ $user->username }}!
|
||||
|
||||
{{ $notification->post->user->username }} made a post in a discussion you're following: {{ $notification->post->discussion->title }}
|
||||
|
||||
To view the new activity, check out the following link:
|
||||
{{ \Flarum\Core::config('base_url') }}/d/{{ $notification->post->discussion_id }}/-/{{ $notification->post->number }}
|
||||
|
||||
---
|
||||
|
||||
{{ strip_tags($notification->post->contentHtml) }}
|
||||
|
||||
---
|
||||
|
||||
You won't receive any more notifications about this discussion until you're up-to-date.
|
Loading…
Reference in New Issue
Block a user