mirror of
https://github.com/flarum/framework.git
synced 2025-01-19 05:32:44 +08:00
Update for beta 8
This commit is contained in:
parent
8d5d5a2dad
commit
d748d8739d
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Flarum\Embed\EmbeddedDiscussionController;
|
||||
use Flarum\Embed\EmbedFrontend;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Extension\Event\Disabled;
|
||||
use Flarum\Extension\Event\Enabled;
|
||||
use Flarum\Settings\Event\Saved;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
|
||||
return [
|
||||
(new Extend\Routes('forum'))
|
||||
->get('/embed/{id:\d+(?:-[^/]*)?}[/{near:[^/]*}]', 'embed.discussion', EmbeddedDiscussionController::class),
|
||||
|
||||
// TODO: Convert to extenders
|
||||
function (Dispatcher $events, Factory $view, EmbedFrontend $frontend) {
|
||||
$events->listen(Saved::class, function (Saved $event) use ($frontend) {
|
||||
if (preg_match('/^theme_|^custom_less$/i', $event->key)) {
|
||||
$frontend->getAssets()->flushCss();
|
||||
}
|
||||
});
|
||||
$events->listen(Enabled::class, function () use ($frontend) {
|
||||
$frontend->getAssets()->flush();
|
||||
});
|
||||
$events->listen(Disabled::class, function () use ($frontend) {
|
||||
$frontend->getAssets()->flush();
|
||||
});
|
||||
|
||||
$view->addNamespace('flarum-embed', __DIR__.'/views');
|
||||
}
|
||||
];
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "flarum/flarum-ext-embed",
|
||||
"name": "flarum/embed",
|
||||
"description": "Embed Flarum discussions as comments for your blog.",
|
||||
"type": "flarum-extension",
|
||||
"keywords": ["discussion"],
|
||||
|
@ -12,7 +12,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/flarum/core/issues",
|
||||
"source": "https://github.com/flarum/flarum-ext-embed"
|
||||
"source": "https://github.com/flarum/embed"
|
||||
},
|
||||
"require": {
|
||||
"flarum/core": "^0.1.0-beta.8"
|
||||
|
|
41
extensions/embed/extend.php
Normal file
41
extensions/embed/extend.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Flarum\Extend;
|
||||
use Flarum\Frontend\Document;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
return [
|
||||
(new Extend\Frontend('forum'))
|
||||
->route(
|
||||
'/embed/{id:\d+(?:-[^/]*)?}[/{near:[^/]*}]',
|
||||
'embed.discussion',
|
||||
function (Document $document, Request $request) {
|
||||
// Add the discussion content to the document so that the
|
||||
// payload will be included on the page and the JS app will be
|
||||
// able to render the discussion immediately.
|
||||
app(Flarum\Forum\Content\Discussion::class)($document, $request);
|
||||
|
||||
app(Flarum\Frontend\Content\Assets::class)->forFrontend('embed')($document, $request);
|
||||
}
|
||||
),
|
||||
|
||||
(new Extend\Frontend('embed'))
|
||||
->js(__DIR__.'/js/dist/forum.js')
|
||||
->css(__DIR__.'/less/forum.less')
|
||||
->css(base_path().'/vendor/flarum/core/less/common/variables.less')
|
||||
->css(base_path().'/vendor/flarum/core/less/common/mixins.less'),
|
||||
|
||||
function (Factory $view) {
|
||||
$view->addNamespace('flarum-embed', __DIR__.'/views');
|
||||
}
|
||||
];
|
10
extensions/embed/js/forum.js
Normal file
10
extensions/embed/js/forum.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
export * from './src/forum';
|
|
@ -1,10 +0,0 @@
|
|||
var gulp = require('flarum-gulp');
|
||||
|
||||
gulp({
|
||||
files: [
|
||||
'bower_components/iframe-resizer/js/iframeResizer.contentWindow.min.js'
|
||||
],
|
||||
modules: {
|
||||
'flarum/embed': 'src/**/*.js'
|
||||
}
|
||||
});
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"name": "flarum-embed",
|
||||
"devDependencies": {
|
||||
"iframe-resizer": "^3.2.0"
|
||||
}
|
||||
}
|
230
extensions/embed/js/forum/dist/extension.js
vendored
230
extensions/embed/js/forum/dist/extension.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"flarum-gulp": "^0.2.0"
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
import BaseDiscussionPage from 'flarum/components/DiscussionPage';
|
||||
import LoadingIndicator from 'flarum/components/LoadingIndicator';
|
||||
import listItems from 'flarum/helpers/listItems';
|
||||
|
||||
export default class DiscussionPage extends BaseDiscussionPage {
|
||||
init() {
|
||||
super.init();
|
||||
|
||||
this.bodyClass = null;
|
||||
}
|
||||
|
||||
view() {
|
||||
return (
|
||||
<div className="DiscussionPage">
|
||||
<div class="container">
|
||||
<div className="DiscussionPage-discussion">
|
||||
{this.discussion ? [
|
||||
<nav className="DiscussionPage-nav--embed">
|
||||
<ul>{listItems(this.sidebarItems().toArray())}</ul>
|
||||
</nav>,
|
||||
<div className="DiscussionPage-stream">
|
||||
{this.stream.render()}
|
||||
</div>
|
||||
] : (
|
||||
<LoadingIndicator className="LoadingIndicator--block"/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
sidebarItems() {
|
||||
const items = super.sidebarItems();
|
||||
|
||||
items.remove('scrubber');
|
||||
|
||||
const count = this.discussion.repliesCount();
|
||||
|
||||
items.add('replies', <h3>
|
||||
<a href={app.route.discussion(this.discussion).replace('/embed', '/d')} config={m.route}>
|
||||
{count} comment{count == 1 ? '' : 's'}
|
||||
</a>
|
||||
</h3>, 100);
|
||||
|
||||
const props = items.get('controls').props;
|
||||
props.className = props.className.replace('App-primaryControl', '');
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
import { override, extend } from 'flarum/extend';
|
||||
import app from 'flarum/app';
|
||||
import Composer from 'flarum/components/Composer';
|
||||
import PostStream from 'flarum/components/PostStream';
|
||||
import ModalManager from 'flarum/components/ModalManager';
|
||||
import AlertManager from 'flarum/components/AlertManager';
|
||||
import PostMeta from 'flarum/components/PostMeta';
|
||||
import mapRoutes from 'flarum/utils/mapRoutes';
|
||||
import Pane from 'flarum/utils/Pane';
|
||||
import Drawer from 'flarum/utils/Drawer';
|
||||
import ScrollListener from 'flarum/utils/ScrollListener';
|
||||
|
||||
import DiscussionPage from 'flarum/embed/components/DiscussionPage';
|
||||
|
||||
app.initializers.replace('boot', () => {
|
||||
m.route.mode = 'pathname';
|
||||
|
||||
override(m, 'route', function(original, root, arg1, arg2, vdom) {
|
||||
if (arguments.length === 1) {
|
||||
|
||||
} else if (arguments.length === 4 && typeof arg1 === 'string') {
|
||||
|
||||
} else if (root.addEventListener || root.attachEvent) {
|
||||
root.href = vdom.attrs.href.replace('/embed', '/d');
|
||||
root.target = '_blank';
|
||||
|
||||
// TODO: If href leads to a post within this discussion that we have
|
||||
// already loaded, then scroll to it?
|
||||
return;
|
||||
}
|
||||
|
||||
return original.apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
});
|
||||
|
||||
// Trim the /embed prefix off of post permalinks
|
||||
override(PostMeta.prototype, 'getPermalink', (original, post) => {
|
||||
return original(post).replace('/embed', '/d');
|
||||
});
|
||||
|
||||
app.pageInfo = m.prop({});
|
||||
|
||||
const reposition = function() {
|
||||
const info = app.pageInfo();
|
||||
this.$().css('top', Math.max(0, info.scrollTop - info.offsetTop));
|
||||
};
|
||||
|
||||
extend(ModalManager.prototype, 'show', reposition);
|
||||
extend(Composer.prototype, 'show', reposition);
|
||||
|
||||
window.iFrameResizer = {
|
||||
readyCallback: function() {
|
||||
window.parentIFrame.getPageInfo(app.pageInfo);
|
||||
}
|
||||
};
|
||||
|
||||
extend(PostStream.prototype, 'goToNumber', function(promise, number) {
|
||||
if (number === 'reply' && 'parentIFrame' in window && app.composer.isFullScreen()) {
|
||||
const itemTop = this.$('.PostStream-item:last').offset().top;
|
||||
window.parentIFrame.scrollToOffset(0, itemTop);
|
||||
}
|
||||
});
|
||||
|
||||
app.pane = new Pane(document.getElementById('app'));
|
||||
app.drawer = new Drawer();
|
||||
app.composer = m.mount(document.getElementById('composer'), Composer.component());
|
||||
app.modal = m.mount(document.getElementById('modal'), ModalManager.component());
|
||||
app.alerts = m.mount(document.getElementById('alerts'), AlertManager.component());
|
||||
|
||||
app.viewingDiscussion = function(discussion) {
|
||||
return this.current instanceof DiscussionPage && this.current.discussion === discussion;
|
||||
};
|
||||
|
||||
delete app.routes['index.filter'];
|
||||
app.routes['discussion'] = {path: '/embed/:id', component: DiscussionPage.component()};
|
||||
app.routes['discussion.near'] = {path: '/embed/:id/:near', component: DiscussionPage.component()};
|
||||
|
||||
const basePath = app.forum.attribute('basePath');
|
||||
m.route.mode = 'pathname';
|
||||
m.route(
|
||||
document.getElementById('content'),
|
||||
basePath + '/',
|
||||
mapRoutes(app.routes, basePath)
|
||||
);
|
||||
|
||||
if (m.route.param('hideFirstPost')) {
|
||||
extend(PostStream.prototype, 'view', vdom => {
|
||||
if (vdom.children[0].attrs['data-number'] === 1) {
|
||||
vdom.children.splice(0, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add a class to the body which indicates that the page has been scrolled
|
||||
// down.
|
||||
new ScrollListener(top => {
|
||||
const $app = $('#app');
|
||||
const offset = $app.offset().top;
|
||||
|
||||
$app
|
||||
.toggleClass('affix', top >= offset)
|
||||
.toggleClass('scrolled', top > offset);
|
||||
}).start();
|
||||
|
||||
// Initialize FastClick, which makes links and buttons much more responsive on
|
||||
// touch devices.
|
||||
$(() => {
|
||||
FastClick.attach(document.body);
|
||||
|
||||
$('body').addClass('ontouchstart' in window ? 'touch' : 'no-touch');
|
||||
});
|
||||
|
||||
app.booted = true;
|
||||
});
|
4700
extensions/embed/js/package-lock.json
generated
Normal file
4700
extensions/embed/js/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
extensions/embed/js/package.json
Normal file
14
extensions/embed/js/package.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "@flarum/embed",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"flarum-webpack-config": "^0.1.0-beta.8",
|
||||
"iframe-resizer": "^3.6.0",
|
||||
"webpack": "^4.0.0",
|
||||
"webpack-cli": "^3.0.7"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --mode production --progress",
|
||||
"watch": "webpack --mode development --watch"
|
||||
}
|
||||
}
|
93
extensions/embed/js/src/forum/index.js
Normal file
93
extensions/embed/js/src/forum/index.js
Normal file
|
@ -0,0 +1,93 @@
|
|||
import 'iframe-resizer/js/iframeResizer.contentWindow.js';
|
||||
|
||||
import { override, extend } from 'flarum/extend';
|
||||
import app from 'flarum/app';
|
||||
import ForumApplication from 'flarum/ForumApplication';
|
||||
import Composer from 'flarum/components/Composer';
|
||||
import PostStream from 'flarum/components/PostStream';
|
||||
import ModalManager from 'flarum/components/ModalManager';
|
||||
import AlertManager from 'flarum/components/AlertManager';
|
||||
import PostMeta from 'flarum/components/PostMeta';
|
||||
import mapRoutes from 'flarum/utils/mapRoutes';
|
||||
import Pane from 'flarum/utils/Pane';
|
||||
import Drawer from 'flarum/utils/Drawer';
|
||||
import ScrollListener from 'flarum/utils/ScrollListener';
|
||||
|
||||
import DiscussionPage from 'flarum/components/DiscussionPage';
|
||||
|
||||
extend(ForumApplication.prototype, 'mount', function() {
|
||||
if (m.route.param('hideFirstPost')) {
|
||||
extend(PostStream.prototype, 'view', vdom => {
|
||||
if (vdom.children[0].attrs['data-number'] === 1) {
|
||||
vdom.children.splice(0, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
m.route.mode = 'pathname';
|
||||
|
||||
override(m, 'route', function(original, root, arg1, arg2, vdom) {
|
||||
if (arguments.length === 1) {
|
||||
|
||||
} else if (arguments.length === 4 && typeof arg1 === 'string') {
|
||||
|
||||
} else if (root.addEventListener || root.attachEvent) {
|
||||
root.href = vdom.attrs.href.replace('/embed', '/d');
|
||||
root.target = '_blank';
|
||||
|
||||
// TODO: If href leads to a post within this discussion that we have
|
||||
// already loaded, then scroll to it?
|
||||
return;
|
||||
}
|
||||
|
||||
return original.apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
});
|
||||
|
||||
// Trim the /embed prefix off of post permalinks
|
||||
override(PostMeta.prototype, 'getPermalink', (original, post) => {
|
||||
return original(post).replace('/embed', '/d');
|
||||
});
|
||||
|
||||
app.pageInfo = m.prop({});
|
||||
|
||||
const reposition = function() {
|
||||
const info = app.pageInfo();
|
||||
this.$().css('top', Math.max(0, info.scrollTop - info.offsetTop));
|
||||
};
|
||||
|
||||
extend(ModalManager.prototype, 'show', reposition);
|
||||
extend(Composer.prototype, 'show', reposition);
|
||||
|
||||
window.iFrameResizer = {
|
||||
readyCallback: function() {
|
||||
window.parentIFrame.getPageInfo(app.pageInfo);
|
||||
}
|
||||
};
|
||||
|
||||
extend(PostStream.prototype, 'goToNumber', function(promise, number) {
|
||||
if (number === 'reply' && 'parentIFrame' in window && app.composer.isFullScreen()) {
|
||||
const itemTop = this.$('.PostStream-item:last').offset().top;
|
||||
window.parentIFrame.scrollToOffset(0, itemTop);
|
||||
}
|
||||
});
|
||||
|
||||
extend(DiscussionPage.prototype, 'sidebarItems', function(items) {
|
||||
items.remove('scrubber');
|
||||
|
||||
const count = this.discussion.replyCount();
|
||||
|
||||
items.add('replies', <h3>
|
||||
<a href={app.route.discussion(this.discussion).replace('/embed', '/d')} config={m.route}>
|
||||
{count} comment{count == 1 ? '' : 's'}
|
||||
</a>
|
||||
</h3>, 100);
|
||||
|
||||
const props = items.get('controls').props;
|
||||
props.className = props.className.replace('App-primaryControl', '');
|
||||
});
|
||||
|
||||
delete app.routes['index.filter'];
|
||||
app.routes['discussion'] = {path: '/embed/:id', component: DiscussionPage.component()};
|
||||
app.routes['discussion.near'] = {path: '/embed/:id/:near', component: DiscussionPage.component()};
|
||||
|
3
extensions/embed/js/webpack.config.js
Normal file
3
extensions/embed/js/webpack.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
const config = require('flarum-webpack-config');
|
||||
|
||||
module.exports = config();
|
|
@ -19,7 +19,17 @@
|
|||
border-top: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
.DiscussionPage-nav--embed {
|
||||
.Composer {
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.DiscussionHero {
|
||||
display: none;
|
||||
}
|
||||
.DiscussionPage-nav {
|
||||
width: auto;
|
||||
float: none;
|
||||
|
||||
@media @tablet-up {
|
||||
height: 70px;
|
||||
}
|
||||
|
@ -31,6 +41,7 @@
|
|||
list-style: none;
|
||||
padding: 15px 0;
|
||||
margin: 0;
|
||||
width: auto;
|
||||
|
||||
@media @phone {
|
||||
position: static;
|
||||
|
@ -63,6 +74,14 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.ButtonGroup {
|
||||
&, .Button {
|
||||
width: auto !important;
|
||||
}
|
||||
.Dropdown-toggle {
|
||||
width: 36px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.DiscussionPage-stream {
|
||||
margin-right: 0;
|
|
@ -1,27 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# This script compiles the extension so that it can be used in a Flarum
|
||||
# installation. It should be run from the root directory of the extension.
|
||||
|
||||
base=$PWD
|
||||
|
||||
cd "${base}/js"
|
||||
|
||||
if [ -f bower.json ]; then
|
||||
bower install
|
||||
fi
|
||||
|
||||
for app in forum admin; do
|
||||
cd "${base}/js"
|
||||
|
||||
if [ -d $app ]; then
|
||||
cd $app
|
||||
|
||||
if [ -f bower.json ]; then
|
||||
bower install
|
||||
fi
|
||||
|
||||
npm install
|
||||
gulp --production
|
||||
fi
|
||||
done
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Embed;
|
||||
|
||||
use Flarum\Forum\Frontend;
|
||||
|
||||
class EmbedFrontend extends Frontend
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getView()
|
||||
{
|
||||
$view = parent::getView();
|
||||
|
||||
$view->getJs()->addFile(__DIR__.'/../js/forum/dist/extension.js');
|
||||
$view->getCss()->addFile(__DIR__.'/../less/forum/extension.less');
|
||||
|
||||
$view->loadModule('flarum/embed/main');
|
||||
$view->layout = 'flarum-embed::embed';
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAssets()
|
||||
{
|
||||
return $this->assets->make('embed');
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Embed;
|
||||
|
||||
use Flarum\Api\Client;
|
||||
use Flarum\Forum\Controller\DiscussionController;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class EmbeddedDiscussionController extends DiscussionController
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(EmbedFrontend $frontend, Dispatcher $events, Client $api, UrlGenerator $url)
|
||||
{
|
||||
parent::__construct($frontend, $events, $api, $url);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Forum Client Template
|
||||
*
|
||||
* NOTE: You shouldn't edit this file directly. Your changes will be overwritten
|
||||
* when you update Flarum. See flarum.org/docs/templates to learn how to
|
||||
* customize your forum's layout.
|
||||
*
|
||||
* Flarum's JavaScript client mounts various components into key elements in
|
||||
* this template. They are distinguished by their ID attributes:
|
||||
*
|
||||
* - #app
|
||||
* - #app-navigation
|
||||
* - #drawer
|
||||
* - #header
|
||||
* - #header-navigation
|
||||
* - #home-link
|
||||
* - #header-primary
|
||||
* - #header-secondary
|
||||
* - #content
|
||||
* - #composer
|
||||
*/
|
||||
?>
|
||||
<div id="app" class="App EmbedApp">
|
||||
|
||||
<main class="App-content">
|
||||
<div id="content"></div>
|
||||
|
||||
{!! $content !!}
|
||||
|
||||
<div class="App-composer">
|
||||
<div class="container">
|
||||
<div id="composer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user