diff --git a/js/forum/src/components/DiscussionListItem.js b/js/forum/src/components/DiscussionListItem.js index 935aa0af7..a3cce4719 100644 --- a/js/forum/src/components/DiscussionListItem.js +++ b/js/forum/src/components/DiscussionListItem.js @@ -174,8 +174,12 @@ export default class DiscussionListItem extends Component { const discussion = this.props.discussion; if (discussion.isUnread()) { - discussion.save({readNumber: discussion.lastPostNumber()}); - m.redraw(); + const confirmation = confirm(app.translator.trans('core.forum.discussion_list.mark_all_as_read_confirmation')); + + if (confirmation) { + discussion.save({readNumber: discussion.lastPostNumber()}); + m.redraw(); + } } } diff --git a/js/forum/src/components/IndexPage.js b/js/forum/src/components/IndexPage.js index 5848520f0..d85867b94 100644 --- a/js/forum/src/components/IndexPage.js +++ b/js/forum/src/components/IndexPage.js @@ -358,6 +358,10 @@ export default class IndexPage extends Page { * @return void */ markAllAsRead() { - app.session.user.save({readTime: new Date()}); + const confirmation = confirm(app.translator.trans('core.forum.index.mark_all_as_read_confirmation')); + + if (confirmation) { + app.session.user.save({readTime: new Date()}); + } } } diff --git a/js/forum/src/components/PostStream.js b/js/forum/src/components/PostStream.js index d18cec577..5fc1cff41 100644 --- a/js/forum/src/components/PostStream.js +++ b/js/forum/src/components/PostStream.js @@ -55,7 +55,9 @@ class PostStream extends Component { return this.goToLast().then(() => { $('html,body').stop(true).animate({ scrollTop: $(document).height() - $(window).height() - }, 'fast'); + }, 'fast', () => { + this.flashItem(this.$('.PostStream-item:last-child')); + }); }); } diff --git a/js/lib/models/User.js b/js/lib/models/User.js index a1b231654..cd7ead7be 100644 --- a/js/lib/models/User.js +++ b/js/lib/models/User.js @@ -17,7 +17,7 @@ Object.assign(User.prototype, { avatarUrl: Model.attribute('avatarUrl'), bio: Model.attribute('bio'), - bioHtml: computed('bio', bio => bio ? '

' + $('

').text(bio).html().replace(/\n/g, '
').autoLink() + '

' : ''), + bioHtml: computed('bio', bio => bio ? '

' + $('

').text(bio).html().replace(/\n/g, '
').autoLink({rel: 'nofollow'}) + '

' : ''), preferences: Model.attribute('preferences'), groups: Model.hasMany('groups'), diff --git a/less/lib/lib.less b/less/lib/lib.less index b942aa28d..45396ecd3 100755 --- a/less/lib/lib.less +++ b/less/lib/lib.less @@ -1,5 +1,3 @@ -@import url(//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700,600); - @import "font-awesome.less"; @fa-font-path: "../../assets/fonts"; diff --git a/src/Api/ApiServiceProvider.php b/src/Api/ApiServiceProvider.php index 09012694b..acd114fdf 100644 --- a/src/Api/ApiServiceProvider.php +++ b/src/Api/ApiServiceProvider.php @@ -110,13 +110,6 @@ class ApiServiceProvider extends AbstractServiceProvider $toController('Flarum\Api\Controller\ShowForumController') ); - // Save forum information - $routes->patch( - '/forum', - 'forum.update', - $toController('Flarum\Api\Controller\UpdateForumController') - ); - // Retrieve authentication token $routes->post( '/token', diff --git a/src/Event/ConfigureLocales.php b/src/Event/ConfigureLocales.php index 8ecf98518..c37e84c49 100644 --- a/src/Event/ConfigureLocales.php +++ b/src/Event/ConfigureLocales.php @@ -10,7 +10,9 @@ namespace Flarum\Event; +use DirectoryIterator; use Flarum\Locale\LocaleManager; +use RuntimeException; class ConfigureLocales { @@ -26,4 +28,45 @@ class ConfigureLocales { $this->locales = $locales; } + + /** + * Load language pack resources from the given directory. + * + * @param $directory + */ + public function loadLanguagePackFrom($directory) + { + $name = $title = basename($directory); + + if (file_exists($manifest = $directory.'/composer.json')) { + $json = json_decode(file_get_contents($manifest), true); + + if (empty($json)) { + throw new RuntimeException("Error parsing composer.json in $name: ".json_last_error_msg()); + } + + $locale = array_get($json, 'extra.flarum-locale.code'); + $title = array_get($json, 'extra.flarum-locale.title', $title); + } + + if (! isset($locale)) { + throw new RuntimeException("Language pack $name must define \"extra.flarum-locale.code\" in composer.json."); + } + + $this->locales->addLocale($locale, $title); + + if (! is_dir($localeDir = $directory.'/locale')) { + throw new RuntimeException("Language pack $name must have a \"locale\" subdirectory."); + } + + if (file_exists($file = $localeDir.'/config.js')) { + $this->locales->addJsFile($locale, $file); + } + + foreach (new DirectoryIterator($localeDir) as $file) { + if ($file->isFile() && in_array($file->getExtension(), ['yml', 'yaml'])) { + $this->locales->addTranslations($locale, $file->getPathname()); + } + } + } } diff --git a/src/Foundation/AbstractServer.php b/src/Foundation/AbstractServer.php index 5dfda65c0..6cb669642 100644 --- a/src/Foundation/AbstractServer.php +++ b/src/Foundation/AbstractServer.php @@ -78,14 +78,6 @@ abstract class AbstractServer */ protected function getApp() { - // franzliedke/studio currently doesn't autoload files (see issue - // below), so we will need to load them manually if we're using studio. - // https://github.com/franzliedke/studio/issues/29 - if (file_exists($corePath = $this->path.'/core')) { - require $corePath.'/src/helpers.php'; - require $corePath.'/vendor/swiftmailer/swiftmailer/lib/swift_required.php'; - } - date_default_timezone_set('UTC'); $app = new Application($this->path); diff --git a/src/Http/Controller/ClientView.php b/src/Http/Controller/ClientView.php index b5f786b1c..97554de88 100644 --- a/src/Http/Controller/ClientView.php +++ b/src/Http/Controller/ClientView.php @@ -127,6 +127,8 @@ class ClientView implements Renderable $this->assets = $assets; $this->layout = $layout; $this->localeJs = $localeJs; + + $this->addHeadString('', 'font'); } /** @@ -164,9 +166,13 @@ class ClientView implements Renderable * * @param string $string */ - public function addHeadString($string) + public function addHeadString($string, $name = null) { - $this->headStrings[] = $string; + if ($name) { + $this->headStrings[$name] = $string; + } else { + $this->headStrings[] = $string; + } } /**