1
0
mirror of https://github.com/flarum/core.git synced 2025-09-04 05:25:37 +02:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Franz Liedke
a5cfe6be37 Apply fixes from StyleCI
[ci skip] [skip ci]
2018-11-14 07:20:48 +00:00
Franz Liedke
dfbbd66a37 WIP: frontend extender 2018-11-14 08:19:54 +01:00
647 changed files with 10992 additions and 9975 deletions

BIN
.deploy.enc Normal file

Binary file not shown.

3
.github/CONTRIBUTING.md vendored Normal file
View File

@@ -0,0 +1,3 @@
# Contributing to Flarum
Howdy! We're really excited that you are interested in contributing to Flarum. Before submitting your contribution, please take a moment and read through the [Contributing Guidelines](https://github.com/flarum/flarum/blob/master/CONTRIBUTING.md).

View File

@@ -3,6 +3,9 @@ name: "🐛 Bug Report"
about: "If something isn't working as expected" about: "If something isn't working as expected"
--- ---
<!--
IMPORTANT: If you discover a security vulnerability within Flarum, please send an email to [security@flarum.org](mailto:security@flarum.org) instead. We will address these with the utmost urgency and it will prevent vulnerabilities, which may be abused, from popping up on our issue tracker.
-->
## Bug Report ## Bug Report
**Current Behavior** **Current Behavior**

View File

@@ -16,7 +16,7 @@ IMPORTANT: We applaud pull requests, they excite us every single time. As we hav
**Confirmed** **Confirmed**
- [ ] Frontend changes: tested on a local Flarum installation. - [ ] Frontend changes: tested on a local Flarum installation.
- [ ] Backend changes: tests are green (run `composer test`). - [ ] Backend changes: tests are green (run `php vendor/bin/phpunit`).
**Required changes:** **Required changes:**

13
.github/SECURITY.md vendored
View File

@@ -1,13 +0,0 @@
# Security Policy
## Supported Versions
During the beta phase, we will only patch security vulnerabilities in the latest beta release.
## Reporting a Vulnerability
If you discover a security vulnerability within Flarum, please send an email to security@flarum.org so we can address it promptly.
We will get back to you as time allows.
Discussions may commence internally, so you may not hear back immediately.
When reporting a vulnerability, please provide your GitHub username (if available), so that we can invite you to collaborate on a [security advisory on GitHub](https://help.github.com/en/articles/about-maintainer-security-advisories).

View File

@@ -1,16 +0,0 @@
name: JavaScript
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: flarum/action-build@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,65 +0,0 @@
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
php: [7.1, 7.2, 7.3]
service: ['mysql:5.7', mariadb]
prefix: ['', flarum_]
include:
- service: 'mysql:5.7'
db: MySQL
- service: mariadb
db: MariaDB
- prefix: flarum_
prefixStr: (prefix)
exclude:
- php: 7.1
service: 'mysql:5.7'
prefix: flarum_
- php: 7.1
service: mariadb
prefix: flarum_
- php: 7.2
service: 'mysql:5.7'
prefix: flarum_
- php: 7.2
service: mariadb
prefix: flarum_
services:
mysql:
image: ${{ matrix.service }}
ports:
- 13306:3306
name: 'PHP ${{ matrix.php }} / ${{ matrix.db }} ${{ matrix.prefixStr }}'
steps:
- uses: actions/checkout@master
- name: Select PHP version
run: sudo update-alternatives --set php $(which php${{ matrix.php }})
- name: Create MySQL Database
run: mysql -uroot -proot -e 'CREATE DATABASE flarum_test;' --port 13306
- name: Install Composer dependencies
run: composer install
- name: Setup Composer tests
run: composer test:setup
env:
DB_PORT: 13306
DB_PASSWORD: root
DB_PREFIX: ${{ matrix.prefix }}
- name: Run Composer tests
run: composer test

2
.gitignore vendored
View File

@@ -4,6 +4,6 @@ composer.phar
node_modules node_modules
.DS_Store .DS_Store
Thumbs.db Thumbs.db
/tests/integration/tmp /tests/tmp
.vagrant .vagrant
.idea/* .idea/*

48
.travis.yml Normal file
View File

@@ -0,0 +1,48 @@
language: php
sudo: false
cache:
directories:
- $HOME/.composer/cache
- $HOME/.npm
install:
- composer install
- mysql -e 'CREATE DATABASE flarum;'
script:
- vendor/bin/phpunit --coverage-clover=coverage.xml
after_success:
- bash <(curl -s https://codecov.io/bash)
jobs:
include:
- php: 7.1
env: DB=mysql
- php: 7.2
env: DB=mysql
- php: 7.2
env: DB=mysql PREFIX=forum_
- php: 7.1
addons:
mariadb: '10.2'
env: DB=mariadb
- php: 7.2
addons:
mariadb: '10.2'
env: DB=mariadb
- stage: build
language: generic
if: branch = master AND type = push
install: skip
script: bash .travis/build.sh
-k $encrypted_678139e2bc67_key
-i $encrypted_678139e2bc67_iv
after_success: skip

33
.travis/build.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/bash
main() {
while getopts ":k:i:" opt; do
case $opt in
k) encrypted_key="$OPTARG"
;;
i) encrypted_iv="$OPTARG"
;;
\?) echo "Invalid option -$OPTARG" >&2
;;
esac
done
git checkout -f $TRAVIS_BRANCH
git config user.name "flarum-bot"
git config user.email "bot@flarum.org"
cd js
npm i -g npm@6.1.0
npm ci
npm run build
git add dist/* -f
git commit -m "Bundled output for commit $TRAVIS_COMMIT [skip ci]"
eval `ssh-agent -s`
openssl aes-256-cbc -K $encrypted_key -iv $encrypted_iv -in ../.deploy.enc -d | ssh-add -
git push git@github.com:$TRAVIS_REPO_SLUG.git $TRAVIS_BRANCH
}
main "$@"

View File

@@ -1,113 +0,0 @@
# Changelog
## [0.1.0-beta.11](https://github.com/flarum/core/compare/v0.1.0-beta.10...v0.1.0-beta.11)
### Added
- Comments have an additional class `Post--by-actor` when posted by the user (#1927)
### Changed
- Improved support for URL identification during installation (#1861)
- KeyboardNavigatable now has a callback ability (#1922)
- Links are no longer opened with target `_blank` but in the same window (#859)
- Links now have `nofollow ugc` by default as their `rel` attribute (#859, #1884)
- Improved performance of the full text gambit when searching for users (#1877)
- The Queue implementation is now available under its Illuminate contract
### Fixed
- No error handling was possible in the console/cli (#1789)
- Enable scrollbars in log in modals so it fits for GitHub (#1716)
- Reduce log in modal for SSO so it fits for Facebook (#1727)
- Deleting discussions permanently did not delete its posts (#1909)
- Fixed the queue:restart command (#1932)
- Deleted posts were visible to all visitors (#1827)
- Old avatars weren't being deleted when replaced (#1918)
- The search performance regression was reverted (#1764)
- No profile background could be set for remote images (#445)
- Back button sends to home even though it could actually go back (#1942)
- Debug button no longer visible (#1687)
- Modals on smaller screens use the whole width of the page
## [0.1.0-beta.10](https://github.com/flarum/core/compare/v0.1.0-beta.9...v0.1.0-beta.10)
### Added
- Initial queue support: Infrastructure for offloading long-running tasks (e.g. email sending) to background workers (#1773)
- Notifications can now be marked as read without visiting a discussion (#151)
- SEO: The discussion list now has a `rel="canonical"` meta tag, preventing duplicate content (#1134, #1814)
- The "Edit User" permission can now be edited in the UI (#1845)
- New status message and redirect after user deletion (#1750, #1777)
- Errors in Flarum's boot process are now presented with more detailed information (#1607)
### Changed
- Better, more detailed and extensible error handling (#1641, #1843)
- Error pages in debug mode now return the same HTTP status codes as in production (#1648)
- Tweak HTTP status codes for authentication / authorization errors (#1854)
- Already-used links from account activation emails now show a better error message (#1337)
### Fixed
- Security vulnerabilities in dependencies
- Performance: High CPU usage when scrolling in a discussion (#1222)
- Special characters crashed the search (#1498)
- Missing declarations for language and text direction in HTML output (#1772)
- Private messages were counted in user post counts (#1695)
- Extensions could not change the forum's default page (#1819)
- API requests authenticated using access tokens needed to provide a CSRF token (#1828)
- Accessibility: Screenreaders did not read the "Back to discussion list" link (#1835)
## [0.1.0-beta.9](https://github.com/flarum/core/compare/v0.1.0-beta.8.2...v0.1.0-beta.9)
### Added
- New `hasPermission()` helper method for `Group` objects ([9684fbc](https://github.com/flarum/core/commit/9684fbc4da07d32aa322d9228302a23418412cb9))
- Expose supported mail drivers in IoC container ([208bad3](https://github.com/flarum/core/commit/208bad393f37bfdb76007afcddfa4b7451563e9d))
- More test for some API endpoints ([1670590](https://github.com/flarum/core/commit/167059027e5a066d618599c90164ef1b5a509148))
- The `Formatter\Rendering` event now receives the HTTP request instance as well ([0ab9fac](https://github.com/flarum/core/commit/0ab9facc4bd59a260575e6fc650793c663e5866a))
- More and better validation in installer UIs
- Check and enforce minimum MariaDB ([7ff9a90](https://github.com/flarum/core/commit/7ff9a90204923293adc520d3c02dc984845d4f9f))
- Revert publication of assets when installation fails ([ed9591c](https://github.com/flarum/core/commit/ed9591c16fb2ea7a4be3387b805d855a53e0a7d5))
- Benefit from Laravel's database reconnection logic in long-running tasks ([e0becd0](https://github.com/flarum/core/commit/e0becd0c7bda939048923c1f86648793feee78d5))
- The "vendor path" (where Composer dependencies can be found) can now be configured ([5e1680c](https://github.com/flarum/core/commit/5e1680c458cd3ba274faeb92de3ac2053789131e))
### Changed
- Performance: Actually cache translations on disk ([0d16fac](https://github.com/flarum/core/commit/0d16fac001bb735ee66e82871183516aeac269b7))
- Allow per-site extenders to override extension extenders ([ba594de](https://github.com/flarum/core/commit/ba594de13a033480834d53d73f747b05fe9796f8))
- Do not resolve objects from the IoC container (in service providers and extenders) until they are actually used
- Replace event subscribers (that resolve objects from the IoC container) with listeners (that resolve lazily)
- Use custom service provider for Mail component ([ac5e26a](https://github.com/flarum/core/commit/ac5e26a254d89e21bd4c115b6cbd40338e2e4b4b))
- Update to Laravel 5.7, revert custom logic for building database index names
- Refactored installer, extracted Installation class and pipeline for reuse in CLI and web installers ([790d5be](https://github.com/flarum/core/commit/790d5beee5e283178716bc8f9901c758d9e5b6a0))
- Use whitelist for enabling pre-installed extensions during installation ([4585f03](https://github.com/flarum/core/commit/4585f03ee356c92942fbc2ae8c683c651b473954))
- Update minimum MySQL version ([7ff9a90](https://github.com/flarum/core/commit/7ff9a90204923293adc520d3c02dc984845d4f9f))
### Fixed
- Signing up via OAuth providers was broken ([67f9375](https://github.com/flarum/core/commit/67f9375d4745add194ae3249d526197c32fd5461))
- Group badges were overlapping ([16eb1fa](https://github.com/flarum/core/commit/16eb1fa63b6d7b80ec30c24c0e406a2b7ab09934))
- API: Endpoint for uninstalling extensions returned an error ([c761802](https://github.com/flarum/core/commit/c76180290056ddbab67baf5ede814fcedf1dcf14))
- Documentation links in installer were outdated ([b58380e](https://github.com/flarum/core/commit/b58380e224ee54abdade3d0a4cc107ef5c91c9a9))
- Event posts where counted when aggregating user posts ([671fdec](https://github.com/flarum/core/commit/671fdec8d0a092ccceb5d4d5f657d0f4287fc4c7))
- Admins could not reset user passwords ([c67fb2d](https://github.com/flarum/core/commit/c67fb2d4b6a128c71d65dc6703310c0b62f91be2))
- Several down migrations were invalid
- Validation errors on reset password page resulted in HTTP 404 ([4611abe](https://github.com/flarum/core/commit/4611abe5db8b94ca3dc7bf9c447fca7c67358ee3))
- `is:unread` gambit generated an invalid query ([e17bb0b](https://github.com/flarum/core/commit/e17bb0b4331f2c92459292195c6b7db8cde1f9f3))
- Entire forum was breaking when the `custom_less` setting was missing from the database ([bf2c5a5](https://github.com/flarum/core/commit/bf2c5a5564dff3f5ef13efe7a8d69f2617570ce6))
- Dropdown icon was not showing in user card when on user page ([12fdfc9](https://github.com/flarum/core/commit/12fdfc9b544a27f6fe59c82ad6bddd3420cc0181))
- Requests were missing the `original*` attributes, which broke installations in subfolders ([56fde28](https://github.com/flarum/core/commit/56fde28e436f52fee0c03c538f0a6049bc584b53))
- Special characters such as `%` and `_` could return incorrect results ([ee3640e](https://github.com/flarum/core/commit/ee3640e1605ff67fef4b3d5cd0596f14a6ae73c9))
- FontAwesome component package changed paths in version 5.9.0 ([5eb69e1](https://github.com/flarum/core/commit/5eb69e1f59fa73fdfd5badbf41a05a6a040e7426))
- Some server environments had problems accessing the system-wide tmp path for storing JS file maps ([54660eb](https://github.com/flarum/core/commit/54660ebd6311f9ea142f1b573263d0d907400786))
- Content length of posts.content was not migrated to mediumText in 2017 ([590b311](https://github.com/flarum/core/commit/590b3115708bf94a9c7f169d98c6126380c7056e))
- An error occurred when going to the previous route if there was no previous route found ([985b87da](https://github.com/flarum/core/commit/985b87da6c9942c568a1a192e2fdcfde72e030ee))
### Removed
- `php flarum install --defaults` - this was meant to be used in our old development VM ([44c9109](https://github.com/flarum/core/commit/44c91099cd77138bb5fc29f14fb1e81a9781272d))
- Obsolete `id` attributes in JSON-API responses ([ecc3b5e](https://github.com/flarum/core/commit/ecc3b5e2271f8d9b38d52cd54476d86995dbe32e) and [7a44086](https://github.com/flarum/core/commit/7a44086bf3a0e3ba907dceb13d07ac695eca05ea))
## [0.1.0-beta.8.1](https://github.com/flarum/core/compare/v0.1.0-beta.8...v0.1.0-beta.8.1)
### Fixed
- Fix live output in `migrate:reset` command ([f591585](https://github.com/flarum/core/commit/f591585d02f8c4ff0211c5bf4413dd6baa724c05))
- Fix search with database prefix ([7705a2b](https://github.com/flarum/core/commit/7705a2b7d751943ef9d0c7379ec34f8530b99310))
- Fix invalid join time of admin user created by installer ([57f73c9](https://github.com/flarum/core/commit/57f73c9638eeb825f9e336ed3c443afccfd8995e))
- Ensure InnoDB engine is used for all tables ([fb6b51b](https://github.com/flarum/core/commit/fb6b51b1cfef0af399607fe038603c8240800b2b), [6370f7e](https://github.com/flarum/core/commit/6370f7ecffa9ea7d5fb64d9551400edbc63318db))
- Fix dropping foreign keys in `down` migrations ([57d5846](https://github.com/flarum/core/commit/57d5846b647881009d9e60f9ffca20b1bb77776e))
- Fix discussion list scroll position not being maintained when hero is not visible ([40dc6ac](https://github.com/flarum/core/commit/40dc6ac604c2a0973356b38217aa8d09352daae5))
- Fix empty meta description tag ([88e43cc](https://github.com/flarum/core/commit/88e43cc6940ee30d6529e9ce659471ec4fb1c474))
- Remove empty attributes on `<html>` tag ([796b577](https://github.com/flarum/core/commit/796b57753d34d4ea741dbebcbc550b17808f6c94))

View File

@@ -1,7 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2019 Stichting Flarum (Flarum Foundation) Copyright (c) 2014-2018 Toby Zerner
Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,35 +1,11 @@
<p align="center"><img src="https://flarum.org/img/logo.png"></p> # Flarum Core
<p align="center"> This repository contains Flarum's core code. If you want to set up a forum, visit the [main Flarum repository](https://github.com/flarum/flarum).
<a href="https://travis-ci.org/flarum/core"><img src="https://travis-ci.org/flarum/core.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/flarum/core"><img src="https://poser.pugx.org/flarum/core/d/total.svg" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/flarum/core"><img src="https://poser.pugx.org/flarum/core/v/stable.svg" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/flarum/core"><img src="https://poser.pugx.org/flarum/core/license.svg" alt="License"></a>
</p>
## About Flarum
**[Flarum](https://flarum.org/) is a delightfully simple discussion platform for your website.** It's fast and easy to use, with all the features you need to run a successful community. It is designed to be:
* **Fast and simple.** No clutter, no bloat, no complex dependencies. Flarum is built with PHP so its quick and easy to deploy. The interface is powered by Mithril, a performant JavaScript framework with a tiny footprint.
* **Beautiful and responsive.** This is forum software for humans. Flarum is carefully designed to be consistent and intuitive across platforms, out-of-the-box.
* **Powerful and extensible.** Customize, extend, and integrate Flarum to suit your community. Flarums architecture is amazingly flexible, with a powerful Extension API.
## Installation
This repository contains Flarum's core code. If you want to set up a forum, visit the [Flarum skeleton repository](https://github.com/flarum/flarum).
## Contributing ## Contributing
Thank you for considering contributing to Flarum! Please read the **[Contributing guide](https://flarum.org/docs/contributing.html)** to learn how you can help. Flarum is open-source and we would love your help building it! Please read the [Contributing Guide](https://github.com/flarum/flarum/blob/master/CONTRIBUTING.md) to learn how you can help.
## Security Vulnerabilities ### Security Vulnerabilities
If you discover a security vulnerability within Flarum, please send an e-mail to [security@flarum.org](mailto:security@flarum.org). All security vulnerabilities will be promptly addressed.
## License
Flarum is open-source software licensed under the [MIT License](https://github.com/flarum/flarum/blob/master/LICENSE).
If you discover a security vulnerability within Flarum, please send an email to [security@flarum.org](mailto:security@flarum.org).

View File

@@ -12,10 +12,6 @@
{ {
"name": "Franz Liedke", "name": "Franz Liedke",
"email": "franz@develophp.org" "email": "franz@develophp.org"
},
{
"name": "Daniel Klabbers",
"email": "daniel@klabbers.email"
} }
], ],
"support": { "support": {
@@ -26,25 +22,24 @@
"require": { "require": {
"php": ">=7.1", "php": ">=7.1",
"axy/sourcemap": "^0.1.4", "axy/sourcemap": "^0.1.4",
"components/font-awesome": "5.9.*", "components/font-awesome": "^5.0.6",
"dflydev/fig-cookies": "^1.0.2", "dflydev/fig-cookies": "^1.0.2",
"doctrine/dbal": "^2.7", "doctrine/dbal": "^2.7",
"franzl/whoops-middleware": "^0.4.0", "franzl/whoops-middleware": "^0.4.0",
"illuminate/bus": "5.7.*", "illuminate/bus": "5.5.*",
"illuminate/cache": "5.7.*", "illuminate/cache": "5.5.*",
"illuminate/config": "5.7.*", "illuminate/config": "5.5.*",
"illuminate/container": "5.7.*", "illuminate/container": "5.5.*",
"illuminate/contracts": "5.7.*", "illuminate/contracts": "5.5.*",
"illuminate/database": "5.7.*", "illuminate/database": "5.5.*",
"illuminate/events": "5.7.*", "illuminate/events": "5.5.*",
"illuminate/filesystem": "5.7.*", "illuminate/filesystem": "5.5.*",
"illuminate/hashing": "5.7.*", "illuminate/hashing": "5.5.*",
"illuminate/mail": "5.7.*", "illuminate/mail": "5.5.*",
"illuminate/queue": "5.7.*", "illuminate/session": "5.5.*",
"illuminate/session": "5.7.*", "illuminate/support": "5.5.*",
"illuminate/support": "5.7.*", "illuminate/validation": "5.5.*",
"illuminate/validation": "5.7.*", "illuminate/view": "5.5.*",
"illuminate/view": "5.7.*",
"intervention/image": "^2.3.0", "intervention/image": "^2.3.0",
"league/flysystem": "^1.0.11", "league/flysystem": "^1.0.11",
"matthiasmullie/minify": "^1.3", "matthiasmullie/minify": "^1.3",
@@ -59,8 +54,8 @@
"psr/http-server-middleware": "^1.0", "psr/http-server-middleware": "^1.0",
"s9e/text-formatter": "^1.2.0", "s9e/text-formatter": "^1.2.0",
"symfony/config": "^3.3", "symfony/config": "^3.3",
"symfony/console": "^4.2", "symfony/console": "^3.3",
"symfony/event-dispatcher": "^4.3.2", "symfony/http-foundation": "^3.3",
"symfony/translation": "^3.3", "symfony/translation": "^3.3",
"symfony/yaml": "^3.3", "symfony/yaml": "^3.3",
"tobscure/json-api": "^0.3.0", "tobscure/json-api": "^0.3.0",
@@ -69,8 +64,8 @@
"zendframework/zend-stratigility": "^3.0" "zendframework/zend-stratigility": "^3.0"
}, },
"require-dev": { "require-dev": {
"mockery/mockery": "^1.0", "mockery/mockery": "^0.9.4",
"phpunit/phpunit": "^7.0" "phpunit/phpunit": "^6.0"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@@ -92,20 +87,5 @@
"branch-alias": { "branch-alias": {
"dev-master": "0.1.x-dev" "dev-master": "0.1.x-dev"
} }
},
"scripts": {
"test": [
"@test:unit",
"@test:integration"
],
"test:unit": "phpunit -c tests/phpunit.unit.xml",
"test:integration": "phpunit -c tests/phpunit.integration.xml",
"test:setup": "@php tests/integration/setup.php"
},
"scripts-descriptions": {
"test": "Runs all tests.",
"test:unit": "Runs all unit tests.",
"test:integration": "Runs all integration tests.",
"test:setup": "Sets up a database for use with integration tests. Execute this only once."
} }
} }

22
js/dist/admin.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

24
js/dist/forum.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

5378
js/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,26 @@
{ {
"private": true,
"name": "@flarum/core", "name": "@flarum/core",
"version": "0.0.0",
"dependencies": { "dependencies": {
"bootstrap": "^3.4.1", "bootstrap": "^3.3.7",
"classnames": "^2.2.5", "classnames": "^2.2.5",
"color-thief-browser": "^2.0.2", "color-thief-browser": "^2.0.2",
"expose-loader": "^0.7.5", "expose-loader": "^0.7.5",
"flarum-webpack-config": "0.1.0-beta.10", "flarum-webpack-config": "^0.1.0-beta.9",
"jquery": "^3.4.1", "jquery": "^3.3.1",
"jquery.hotkeys": "^0.1.0", "jquery.hotkeys": "^0.1.0",
"lodash-es": "^4.17.14", "lodash-es": "^4.17.10",
"m.attrs.bidi": "github:tobscure/m.attrs.bidi", "m.attrs.bidi": "github:tobscure/m.attrs.bidi",
"mithril": "^0.2.8", "mithril": "^0.2.8",
"moment": "^2.22.2", "moment": "^2.22.2",
"punycode": "^2.1.1", "punycode": "^2.1.1",
"spin.js": "^3.1.0", "spin.js": "^3.1.0",
"webpack": "^4.26.0", "webpack": "^4.17.1",
"webpack-cli": "^3.1.2", "webpack-cli": "^2.1.5",
"webpack-merge": "^4.1.4" "webpack-merge": "^4.1.4"
}, },
"scripts": { "scripts": {
"dev": "webpack --mode development --watch", "build": "webpack --mode production",
"build": "webpack --mode production" "watch": "webpack --mode development --watch"
} }
} }

View File

@@ -84,21 +84,17 @@ export default class EditGroupModal extends Modal {
return items; return items;
} }
submitData() {
return {
nameSingular: this.nameSingular(),
namePlural: this.namePlural(),
color: this.color(),
icon: this.icon()
};
}
onsubmit(e) { onsubmit(e) {
e.preventDefault(); e.preventDefault();
this.loading = true; this.loading = true;
this.group.save(this.submitData(), {errorHandler: this.onerror.bind(this)}) this.group.save({
nameSingular: this.nameSingular(),
namePlural: this.namePlural(),
color: this.color(),
icon: this.icon()
}, {errorHandler: this.onerror.bind(this)})
.then(this.hide.bind(this)) .then(this.hide.bind(this))
.catch(() => { .catch(() => {
this.loading = false; this.loading = false;

View File

@@ -2,55 +2,36 @@ import Page from './Page';
import FieldSet from '../../common/components/FieldSet'; import FieldSet from '../../common/components/FieldSet';
import Button from '../../common/components/Button'; import Button from '../../common/components/Button';
import Alert from '../../common/components/Alert'; import Alert from '../../common/components/Alert';
import Select from '../../common/components/Select';
import LoadingIndicator from '../../common/components/LoadingIndicator';
import saveSettings from '../utils/saveSettings'; import saveSettings from '../utils/saveSettings';
export default class MailPage extends Page { export default class MailPage extends Page {
init() { init() {
super.init(); super.init();
this.loading = true; this.loading = false;
this.saving = false;
this.driverFields = {}; this.fields = [
this.fields = ['mail_driver', 'mail_from']; 'mail_driver',
'mail_host',
'mail_from',
'mail_port',
'mail_username',
'mail_password',
'mail_encryption'
];
this.values = {}; this.values = {};
const settings = app.data.settings; const settings = app.data.settings;
this.fields.forEach(key => this.values[key] = m.prop(settings[key])); this.fields.forEach(key => this.values[key] = m.prop(settings[key]));
app.request({ this.localeOptions = {};
method: 'GET', const locales = app.locales;
url: app.forum.attribute('apiUrl') + '/mail-drivers' for (const i in locales) {
}).then(response => { this.localeOptions[i] = `${locales[i]} (${i})`;
this.driverFields = response['data'].reduce(
(hash, driver) => ({...hash, [driver['id']]: driver['attributes']['fields']}),
{}
);
Object.keys(this.driverFields).flatMap(key => this.driverFields[key]).forEach(
key => {
this.fields.push(key);
this.values[key] = m.prop(settings[key]);
} }
);
this.loading = false;
m.redraw();
});
} }
view() { view() {
if (this.loading) {
return (
<div className="MailPage">
<div className="container">
<LoadingIndicator />
</div>
</div>
);
}
return ( return (
<div className="MailPage"> <div className="MailPage">
<div className="container"> <div className="container">
@@ -60,6 +41,36 @@ export default class MailPage extends Page {
{app.translator.trans('core.admin.email.text')} {app.translator.trans('core.admin.email.text')}
</div> </div>
{FieldSet.component({
label: app.translator.trans('core.admin.email.server_heading'),
className: 'MailPage-MailSettings',
children: [
<div className="MailPage-MailSettings-input">
<label>{app.translator.trans('core.admin.email.driver_label')}</label>
<input className="FormControl" value={this.values.mail_driver() || ''} oninput={m.withAttr('value', this.values.mail_driver)} />
<label>{app.translator.trans('core.admin.email.host_label')}</label>
<input className="FormControl" value={this.values.mail_host() || ''} oninput={m.withAttr('value', this.values.mail_host)} />
<label>{app.translator.trans('core.admin.email.port_label')}</label>
<input className="FormControl" value={this.values.mail_port() || ''} oninput={m.withAttr('value', this.values.mail_port)} />
<label>{app.translator.trans('core.admin.email.encryption_label')}</label>
<input className="FormControl" value={this.values.mail_encryption() || ''} oninput={m.withAttr('value', this.values.mail_encryption)} />
</div>
]
})}
{FieldSet.component({
label: app.translator.trans('core.admin.email.account_heading'),
className: 'MailPage-MailSettings',
children: [
<div className="MailPage-MailSettings-input">
<label>{app.translator.trans('core.admin.email.username_label')}</label>
<input className="FormControl" value={this.values.mail_username() || ''} oninput={m.withAttr('value', this.values.mail_username)} />
<label>{app.translator.trans('core.admin.email.password_label')}</label>
<input className="FormControl" value={this.values.mail_password() || ''} oninput={m.withAttr('value', this.values.mail_password)} />
</div>
]
})}
{FieldSet.component({ {FieldSet.component({
label: app.translator.trans('core.admin.email.addresses_heading'), label: app.translator.trans('core.admin.email.addresses_heading'),
className: 'MailPage-MailSettings', className: 'MailPage-MailSettings',
@@ -71,35 +82,11 @@ export default class MailPage extends Page {
] ]
})} })}
{FieldSet.component({
label: app.translator.trans('core.admin.email.driver_heading'),
className: 'MailPage-MailSettings',
children: [
<div className="MailPage-MailSettings-input">
<label>{app.translator.trans('core.admin.email.driver_label')}</label>
<Select value={this.values.mail_driver()} options={Object.keys(this.driverFields).reduce((memo, val) => ({...memo, [val]: val}), {})} onchange={this.values.mail_driver} />
</div>
]
})}
{Object.keys(this.driverFields[this.values.mail_driver()]).length > 0 && FieldSet.component({
label: app.translator.trans(`core.admin.email.${this.values.mail_driver()}_heading`),
className: 'MailPage-MailSettings',
children: [
<div className="MailPage-MailSettings-input">
{this.driverFields[this.values.mail_driver()].flatMap(field => [
<label>{app.translator.trans(`core.admin.email.${field}_label`)}</label>,
<input className="FormControl" value={this.values[field]() || ''} oninput={m.withAttr('value', this.values[field])} />
])}
</div>
]
})}
{Button.component({ {Button.component({
type: 'submit', type: 'submit',
className: 'Button Button--primary', className: 'Button Button--primary',
children: app.translator.trans('core.admin.email.submit_button'), children: app.translator.trans('core.admin.email.submit_button'),
loading: this.saving, loading: this.loading,
disabled: !this.changed() disabled: !this.changed()
})} })}
</form> </form>
@@ -115,9 +102,9 @@ export default class MailPage extends Page {
onsubmit(e) { onsubmit(e) {
e.preventDefault(); e.preventDefault();
if (this.saving) return; if (this.loading) return;
this.saving = true; this.loading = true;
app.alerts.dismiss(this.successAlert); app.alerts.dismiss(this.successAlert);
const settings = {}; const settings = {};
@@ -130,7 +117,7 @@ export default class MailPage extends Page {
}) })
.catch(() => {}) .catch(() => {})
.then(() => { .then(() => {
this.saving = false; this.loading = false;
m.redraw(); m.redraw();
}); });
} }

View File

@@ -228,12 +228,6 @@ export default class PermissionGrid extends Component {
permission: 'discussion.deletePosts' permission: 'discussion.deletePosts'
}, 60); }, 60);
items.add('userEdit', {
icon: 'fas fa-user-cog',
label: app.translator.trans('core.admin.permissions.edit_users_label'),
permission: 'user.edit'
}, 60);
return items; return items;
} }

View File

@@ -8,11 +8,9 @@
*/ */
import DashboardWidget from './DashboardWidget'; import DashboardWidget from './DashboardWidget';
import icon from '../../common/helpers/icon';
import listItems from '../../common/helpers/listItems'; import listItems from '../../common/helpers/listItems';
import ItemList from '../../common/utils/ItemList'; import ItemList from '../../common/utils/ItemList';
import Dropdown from '../../common/components/Dropdown';
import Button from '../../common/components/Button';
import LoadingModal from './LoadingModal';
export default class StatusWidget extends DashboardWidget { export default class StatusWidget extends DashboardWidget {
className() { className() {
@@ -28,16 +26,10 @@ export default class StatusWidget extends DashboardWidget {
items() { items() {
const items = new ItemList(); const items = new ItemList();
items.add('tools', ( items.add('help', (
<Dropdown <a href="http://flarum.org/docs/troubleshooting" target="_blank">
label={app.translator.trans('core.admin.dashboard.tools_button')} {icon('fas fa-question-circle')} {app.translator.trans('core.admin.dashboard.help_link')}
icon="fas fa-cog" </a>
buttonClassName="Button"
menuClassName="Dropdown-menu--right">
<Button onclick={this.handleClearCache.bind(this)}>
{app.translator.trans('core.admin.dashboard.clear_cache_button')}
</Button>
</Dropdown>
)); ));
items.add('version-flarum', [<strong>Flarum</strong>, <br/>, app.forum.attribute('version')]); items.add('version-flarum', [<strong>Flarum</strong>, <br/>, app.forum.attribute('version')]);
@@ -46,13 +38,4 @@ export default class StatusWidget extends DashboardWidget {
return items; return items;
} }
handleClearCache(e) {
app.modal.show(new LoadingModal());
app.request({
method: 'DELETE',
url: app.forum.attribute('apiUrl') + '/cache'
}).then(() => window.location.reload());
}
} }

View File

@@ -1,9 +1,7 @@
import ItemList from './utils/ItemList'; import ItemList from './utils/ItemList';
import Alert from './components/Alert'; import Alert from './components/Alert';
import Button from './components/Button';
import ModalManager from './components/ModalManager'; import ModalManager from './components/ModalManager';
import AlertManager from './components/AlertManager'; import AlertManager from './components/AlertManager';
import RequestErrorModal from './components/RequestErrorModal';
import Translator from './Translator'; import Translator from './Translator';
import Store from './Store'; import Store from './Store';
import Session from './Session'; import Session from './Session';
@@ -330,14 +328,9 @@ export default class Application {
children = app.translator.trans('core.lib.error.generic_message'); children = app.translator.trans('core.lib.error.generic_message');
} }
const isDebug = app.forum.attribute('debug');
error.alert = new Alert({ error.alert = new Alert({
type: 'error', type: 'error',
children, children
controls: isDebug && [
<Button className="Button Button--link" onclick={this.showDebug.bind(this, error)}>Debug</Button>
]
}); });
try { try {
@@ -352,16 +345,6 @@ export default class Application {
return deferred.promise; return deferred.promise;
} }
/**
* @param {RequestError} error
* @private
*/
showDebug(error) {
this.alerts.dismiss(this.requestError.alert);
this.modal.show(new RequestErrorModal({error}));
}
/** /**
* Construct a URL to the route with the given name. * Construct a URL to the route with the given name.
* *

View File

@@ -190,7 +190,7 @@ export default class Model {
* @public * @public
*/ */
delete(data, options = {}) { delete(data, options = {}) {
if (!this.exists) return m.deferred().resolve().promise; if (!this.exists) return m.deferred.resolve().promise;
return app.request(Object.assign({ return app.request(Object.assign({
method: 'DELETE', method: 'DELETE',

View File

@@ -37,7 +37,6 @@ import Placeholder from './components/Placeholder';
import Separator from './components/Separator'; import Separator from './components/Separator';
import Dropdown from './components/Dropdown'; import Dropdown from './components/Dropdown';
import SplitDropdown from './components/SplitDropdown'; import SplitDropdown from './components/SplitDropdown';
import RequestErrorModal from './components/RequestErrorModal';
import FieldSet from './components/FieldSet'; import FieldSet from './components/FieldSet';
import Select from './components/Select'; import Select from './components/Select';
import Navigation from './components/Navigation'; import Navigation from './components/Navigation';
@@ -101,7 +100,6 @@ export default {
'components/Separator': Separator, 'components/Separator': Separator,
'components/Dropdown': Dropdown, 'components/Dropdown': Dropdown,
'components/SplitDropdown': SplitDropdown, 'components/SplitDropdown': SplitDropdown,
'components/RequestErrorModal': RequestErrorModal,
'components/FieldSet': FieldSet, 'components/FieldSet': FieldSet,
'components/Select': Select, 'components/Select': Select,
'components/Navigation': Navigation, 'components/Navigation': Navigation,

View File

@@ -29,12 +29,6 @@ export default class Button extends Component {
attrs.className = attrs.className || ''; attrs.className = attrs.className || '';
attrs.type = attrs.type || 'button'; attrs.type = attrs.type || 'button';
// If a tooltip was provided for buttons without additional content, we also
// use this tooltip as text for screen readers
if (attrs.title && !this.props.children) {
attrs['aria-label'] = attrs.title;
}
// If nothing else is provided, we use the textual button content as tooltip // If nothing else is provided, we use the textual button content as tooltip
if (!attrs.title && this.props.children) { if (!attrs.title && this.props.children) {
attrs.title = extractText(this.props.children); attrs.title = extractText(this.props.children);

View File

@@ -1,30 +0,0 @@
import Modal from './Modal';
export default class RequestErrorModal extends Modal {
className() {
return 'RequestErrorModal Modal--large';
}
title() {
return this.props.error.xhr
? this.props.error.xhr.status+' '+this.props.error.xhr.statusText
: '';
}
content() {
let responseText;
try {
responseText = JSON.stringify(JSON.parse(this.props.error.responseText), null, 2);
} catch (e) {
responseText = this.props.error.responseText;
}
return <div className="Modal-body">
<pre>
{this.props.error.options.method} {this.props.error.options.url}<br/><br/>
{responseText}
</pre>
</div>;
}
}

View File

@@ -91,7 +91,6 @@ Object.assign(User.prototype, {
user.freshness = new Date(); user.freshness = new Date();
m.redraw(); m.redraw();
}; };
image.crossOrigin = 'anonymous';
image.src = this.avatarUrl(); image.src = this.avatarUrl();
}, },

View File

@@ -1,4 +1,4 @@
const later = window.requestAnimationFrame || const scroll = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame || window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame || window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame || window.msRequestAnimationFrame ||
@@ -17,7 +17,7 @@ export default class ScrollListener {
*/ */
constructor(callback) { constructor(callback) {
this.callback = callback; this.callback = callback;
this.ticking = false; this.lastTop = -1;
} }
/** /**
@@ -27,27 +27,27 @@ export default class ScrollListener {
* @protected * @protected
*/ */
loop() { loop() {
// THROTTLE: If the callback is still running (or hasn't yet run), we ignore if (!this.active) return;
// further scroll events.
if (this.ticking) return;
// Schedule the callback to be executed soon (TM), and stop throttling once
// the callback is done.
later(() => {
this.update(); this.update();
this.ticking = false;
});
this.ticking = true; scroll(this.loop.bind(this));
} }
/** /**
* Run the callback, whether there was a scroll event or not. * Check if the scroll position has changed; if it has, run the handler.
* *
* @param {Boolean} [force=false] Whether or not to force the handler to be
* run, even if the scroll position hasn't changed.
* @public * @public
*/ */
update() { update(force) {
this.callback(window.pageYOffset); const top = window.pageYOffset;
if (this.lastTop !== top || force) {
this.callback(top);
this.lastTop = top;
}
} }
/** /**
@@ -57,10 +57,8 @@ export default class ScrollListener {
*/ */
start() { start() {
if (!this.active) { if (!this.active) {
window.addEventListener( this.active = true;
'scroll', this.loop();
this.active = this.loop.bind(this)
);
} }
} }
@@ -70,8 +68,6 @@ export default class ScrollListener {
* @public * @public
*/ */
stop() { stop() {
window.removeEventListener('scroll', this.active); this.active = false;
this.active = null;
} }
} }

View File

@@ -31,7 +31,6 @@ import ComposerButton from './components/ComposerButton';
import DiscussionList from './components/DiscussionList'; import DiscussionList from './components/DiscussionList';
import ReplyPlaceholder from './components/ReplyPlaceholder'; import ReplyPlaceholder from './components/ReplyPlaceholder';
import TextEditor from './components/TextEditor'; import TextEditor from './components/TextEditor';
import TextEditorButton from './components/TextEditorButton';
import AvatarEditor from './components/AvatarEditor'; import AvatarEditor from './components/AvatarEditor';
import Post from './components/Post'; import Post from './components/Post';
import SettingsPage from './components/SettingsPage'; import SettingsPage from './components/SettingsPage';
@@ -100,7 +99,6 @@ export default Object.assign(compat, {
'components/DiscussionList': DiscussionList, 'components/DiscussionList': DiscussionList,
'components/ReplyPlaceholder': ReplyPlaceholder, 'components/ReplyPlaceholder': ReplyPlaceholder,
'components/TextEditor': TextEditor, 'components/TextEditor': TextEditor,
'components/TextEditorButton': TextEditorButton,
'components/AvatarEditor': AvatarEditor, 'components/AvatarEditor': AvatarEditor,
'components/Post': Post, 'components/Post': Post,
'components/SettingsPage': SettingsPage, 'components/SettingsPage': SettingsPage,

View File

@@ -3,7 +3,6 @@ import Button from '../../common/components/Button';
import GroupBadge from '../../common/components/GroupBadge'; import GroupBadge from '../../common/components/GroupBadge';
import Group from '../../common/models/Group'; import Group from '../../common/models/Group';
import extractText from '../../common/utils/extractText'; import extractText from '../../common/utils/extractText';
import ItemList from '../../common/utils/ItemList';
/** /**
* The `EditUserModal` component displays a modal dialog with a login form. * The `EditUserModal` component displays a modal dialog with a login form.
@@ -38,27 +37,17 @@ export default class EditUserModal extends Modal {
return ( return (
<div className="Modal-body"> <div className="Modal-body">
<div className="Form"> <div className="Form">
{this.fields().toArray()} <div className="Form-group">
</div>
</div>
);
}
fields() {
const items = new ItemList();
items.add('username', <div className="Form-group">
<label>{app.translator.trans('core.forum.edit_user.username_heading')}</label> <label>{app.translator.trans('core.forum.edit_user.username_heading')}</label>
<input className="FormControl" placeholder={extractText(app.translator.trans('core.forum.edit_user.username_label'))} <input className="FormControl" placeholder={extractText(app.translator.trans('core.forum.edit_user.username_label'))}
bidi={this.username} /> bidi={this.username} />
</div>, 40); </div>
if (app.session.user !== this.props.user) { {app.session.user !== this.props.user ? [
items.add('email', <div className="Form-group"> <div className="Form-group">
<label>{app.translator.trans('core.forum.edit_user.email_heading')}</label> <label>{app.translator.trans('core.forum.edit_user.email_heading')}</label>
<div> <div>
<input className="FormControl" <input className="FormControl" placeholder={extractText(app.translator.trans('core.forum.edit_user.email_label'))}
placeholder={extractText(app.translator.trans('core.forum.edit_user.email_label'))}
bidi={this.email} /> bidi={this.email} />
</div> </div>
{!this.isEmailConfirmed() ? ( {!this.isEmailConfirmed() ? (
@@ -71,13 +60,13 @@ export default class EditUserModal extends Modal {
})} })}
</div> </div>
) : ''} ) : ''}
</div>, 30); </div>,
items.add('password', <div className="Form-group"> <div className="Form-group">
<label>{app.translator.trans('core.forum.edit_user.password_heading')}</label> <label>{app.translator.trans('core.forum.edit_user.password_heading')}</label>
<div> <div>
<label className="checkbox"> <label className="checkbox">
<input type="checkbox" onchange={e => { <input type="checkbox" checked={this.setPassword()} onchange={e => {
this.setPassword(e.target.checked); this.setPassword(e.target.checked);
m.redraw(true); m.redraw(true);
if (e.target.checked) this.$('[name=password]').select(); if (e.target.checked) this.$('[name=password]').select();
@@ -86,16 +75,14 @@ export default class EditUserModal extends Modal {
{app.translator.trans('core.forum.edit_user.set_password_label')} {app.translator.trans('core.forum.edit_user.set_password_label')}
</label> </label>
{this.setPassword() ? ( {this.setPassword() ? (
<input className="FormControl" type="password" name="password" <input className="FormControl" type="password" name="password" placeholder={extractText(app.translator.trans('core.forum.edit_user.password_label'))}
placeholder={extractText(app.translator.trans('core.forum.edit_user.password_label'))}
bidi={this.password} /> bidi={this.password} />
) : ''} ) : ''}
</div> </div>
</div>, 20); </div>
] : ''}
} <div className="Form-group EditUserModal-groups">
items.add('groups', <div className="Form-group EditUserModal-groups">
<label>{app.translator.trans('core.forum.edit_user.groups_heading')}</label> <label>{app.translator.trans('core.forum.edit_user.groups_heading')}</label>
<div> <div>
{Object.keys(this.groups) {Object.keys(this.groups)
@@ -109,18 +96,19 @@ export default class EditUserModal extends Modal {
</label> </label>
))} ))}
</div> </div>
</div>, 10); </div>
items.add('submit', <div className="Form-group"> <div className="Form-group">
{Button.component({ {Button.component({
className: 'Button Button--primary', className: 'Button Button--primary',
type: 'submit', type: 'submit',
loading: this.loading, loading: this.loading,
children: app.translator.trans('core.forum.edit_user.submit_button') children: app.translator.trans('core.forum.edit_user.submit_button')
})} })}
</div>, -10); </div>
</div>
return items; </div>
);
} }
activate() { activate() {

View File

@@ -102,7 +102,7 @@ export default class IndexPage extends Page {
// previous hero. Maintain the same scroll position relative to the bottom // previous hero. Maintain the same scroll position relative to the bottom
// of the hero so that the sidebar doesn't jump around. // of the hero so that the sidebar doesn't jump around.
const oldHeroHeight = app.cache.heroHeight; const oldHeroHeight = app.cache.heroHeight;
const heroHeight = app.cache.heroHeight = this.$('.Hero').outerHeight() || 0; const heroHeight = app.cache.heroHeight = this.$('.Hero').outerHeight();
const scrollTop = app.cache.scrollTop; const scrollTop = app.cache.scrollTop;
$('#app').css('min-height', $(window).height() + heroHeight); $('#app').css('min-height', $(window).height() + heroHeight);

View File

@@ -13,7 +13,7 @@ export default class LogInButton extends Button {
props.className = (props.className || '') + ' LogInButton'; props.className = (props.className || '') + ' LogInButton';
props.onclick = function() { props.onclick = function() {
const width = 580; const width = 600;
const height = 400; const height = 400;
const $window = $(window); const $window = $(window);
@@ -22,7 +22,7 @@ export default class LogInButton extends Button {
`height=${height},` + `height=${height},` +
`top=${$window.height() / 2 - height / 2},` + `top=${$window.height() / 2 - height / 2},` +
`left=${$window.width() / 2 - width / 2},` + `left=${$window.width() / 2 - width / 2},` +
'status=no,scrollbars=yes,resizable=no'); 'status=no,scrollbars=no,resizable=no');
}; };
super.initProps(props); super.initProps(props);

View File

@@ -2,7 +2,6 @@ import Component from '../../common/Component';
import avatar from '../../common/helpers/avatar'; import avatar from '../../common/helpers/avatar';
import icon from '../../common/helpers/icon'; import icon from '../../common/helpers/icon';
import humanTime from '../../common/helpers/humanTime'; import humanTime from '../../common/helpers/humanTime';
import Button from '../../common/components/Button';
/** /**
* The `Notification` component abstract displays a single notification. * The `Notification` component abstract displays a single notification.
@@ -27,17 +26,6 @@ export default class Notification extends Component {
if (!isInitialized) $(element).click(this.markAsRead.bind(this)); if (!isInitialized) $(element).click(this.markAsRead.bind(this));
}}> }}>
{!notification.isRead() && Button.component({
className: 'Notification-action Button Button--icon Button--link',
icon: 'fas fa-check',
title: app.translator.trans('core.forum.notifications.mark_as_read_tooltip'),
onclick: e => {
e.preventDefault();
e.stopPropagation();
this.markAsRead();
}
})}
{avatar(notification.fromUser())} {avatar(notification.fromUser())}
{icon(this.icon(), {className: 'Notification-icon'})} {icon(this.icon(), {className: 'Notification-icon'})}
<span className="Notification-content">{this.content()}</span> <span className="Notification-content">{this.content()}</span>

View File

@@ -39,7 +39,7 @@ export default class Post extends Component {
view() { view() {
const attrs = this.attrs(); const attrs = this.attrs();
attrs.className = this.classes(attrs.className).join(' '); attrs.className = 'Post ' + (this.loading ? 'Post--loading ' : '') + (attrs.className || '');
return ( return (
<article {...attrs}> <article {...attrs}>
@@ -98,26 +98,6 @@ export default class Post extends Component {
return []; return [];
} }
/**
* Get the post's classes.
*
* @param string classes
* @returns {string[]}
*/
classes(existing) {
let classes = (existing || '').split(' ').concat(['Post']);
if (this.loading) {
classes.push('Post--loading');
}
if (this.props.post.user() === app.session.user) {
classes.push('Post--by-actor');
}
return classes;
}
/** /**
* Build an item list for the post's actions. * Build an item list for the post's actions.
* *

View File

@@ -2,6 +2,7 @@ import Component from '../../common/Component';
import ScrollListener from '../../common/utils/ScrollListener'; import ScrollListener from '../../common/utils/ScrollListener';
import PostLoading from './LoadingPost'; import PostLoading from './LoadingPost';
import anchorScroll from '../../common/utils/anchorScroll'; import anchorScroll from '../../common/utils/anchorScroll';
import mixin from '../../common/utils/mixin';
import evented from '../../common/utils/evented'; import evented from '../../common/utils/evented';
import ReplyPlaceholder from './ReplyPlaceholder'; import ReplyPlaceholder from './ReplyPlaceholder';
import Button from '../../common/components/Button'; import Button from '../../common/components/Button';
@@ -585,7 +586,7 @@ class PostStream extends Component {
*/ */
unpause() { unpause() {
this.paused = false; this.paused = false;
this.scrollListener.update(); this.scrollListener.update(true);
this.trigger('unpaused'); this.trigger('unpaused');
} }
} }

View File

@@ -2,6 +2,7 @@ import Component from '../../common/Component';
import icon from '../../common/helpers/icon'; import icon from '../../common/helpers/icon';
import ScrollListener from '../../common/utils/ScrollListener'; import ScrollListener from '../../common/utils/ScrollListener';
import SubtreeRetainer from '../../common/utils/SubtreeRetainer'; import SubtreeRetainer from '../../common/utils/SubtreeRetainer';
import computed from '../../common/utils/computed';
import formatNumber from '../../common/utils/formatNumber'; import formatNumber from '../../common/utils/formatNumber';
/** /**
@@ -98,7 +99,7 @@ export default class PostStreamScrubber extends Component {
<div className="Scrubber-bar"/> <div className="Scrubber-bar"/>
<div className="Scrubber-info"> <div className="Scrubber-info">
<strong>{viewing}</strong> <strong>{viewing}</strong>
<span className="Scrubber-description">{retain || this.description}</span> <span class="Scrubber-description">{retain || this.description}</span>
</div> </div>
</div> </div>
<div className="Scrubber-after"/> <div className="Scrubber-after"/>
@@ -131,7 +132,7 @@ export default class PostStreamScrubber extends Component {
*/ */
goToLast() { goToLast() {
this.props.stream.goToLast(); this.props.stream.goToLast();
this.index = this.count(); this.index = this.props.stream.count();
this.renderScrollbar(true); this.renderScrollbar(true);
} }
@@ -189,6 +190,7 @@ export default class PostStreamScrubber extends Component {
const marginTop = stream.getMarginTop(); const marginTop = stream.getMarginTop();
const viewportTop = scrollTop + marginTop; const viewportTop = scrollTop + marginTop;
const viewportHeight = $(window).height() - marginTop; const viewportHeight = $(window).height() - marginTop;
const viewportBottom = viewportTop + viewportHeight;
// Before looping through all of the posts, we reset the scrollbar // Before looping through all of the posts, we reset the scrollbar
// properties to a 'default' state. These values reflect what would be // properties to a 'default' state. These values reflect what would be
@@ -313,7 +315,7 @@ export default class PostStreamScrubber extends Component {
const visible = this.visible || 1; const visible = this.visible || 1;
const $scrubber = this.$(); const $scrubber = this.$();
$scrubber.find('.Scrubber-index').text(formatNumber(Math.min(Math.ceil(index + visible), count))); $scrubber.find('.Scrubber-index').text(formatNumber(Math.ceil(index + visible)));
$scrubber.find('.Scrubber-description').text(this.description); $scrubber.find('.Scrubber-description').text(this.description);
$scrubber.toggleClass('disabled', this.disabled()); $scrubber.toggleClass('disabled', this.disabled());
@@ -364,7 +366,7 @@ export default class PostStreamScrubber extends Component {
} }
onresize() { onresize() {
this.scrollListener.update(); this.scrollListener.update(true);
// Adjust the height of the scrollbar so that it fills the height of // Adjust the height of the scrollbar so that it fills the height of
// the sidebar and doesn't overlap the footer. // the sidebar and doesn't overlap the footer.

View File

@@ -160,7 +160,7 @@ export default class Search extends Component {
search.loadingSources++; search.loadingSources++;
source.search(query).then(() => { source.search(query).then(() => {
search.loadingSources = Math.max(0, search.loadingSources - 1); search.loadingSources--;
m.redraw(); m.redraw();
}); });
}); });
@@ -189,9 +189,6 @@ export default class Search extends Component {
* Navigate to the currently selected search result and close the list. * Navigate to the currently selected search result and close the list.
*/ */
selectResult() { selectResult() {
clearTimeout(this.searchTimeout);
this.loadingSources = 0;
if (this.value()) { if (this.value()) {
m.route(this.getItem(this.index).find('a').attr('href')); m.route(this.getItem(this.index).find('a').attr('href'));
} else { } else {

View File

@@ -36,9 +36,6 @@ export default class TextEditor extends Component {
<ul className="TextEditor-controls Composer-footer"> <ul className="TextEditor-controls Composer-footer">
{listItems(this.controlItems().toArray())} {listItems(this.controlItems().toArray())}
<li className="TextEditor-toolbar">
{this.toolbarItems().toArray()}
</li>
</ul> </ul>
</div> </div>
); );
@@ -73,7 +70,7 @@ export default class TextEditor extends Component {
items.add('submit', items.add('submit',
Button.component({ Button.component({
children: this.props.submitLabel, children: this.props.submitLabel,
icon: 'fas fa-paper-plane', icon: 'fas fa-check',
className: 'Button Button--primary', className: 'Button Button--primary',
itemClassName: 'App-primaryControl', itemClassName: 'App-primaryControl',
onclick: this.onsubmit.bind(this) onclick: this.onsubmit.bind(this)
@@ -83,11 +80,10 @@ export default class TextEditor extends Component {
if (this.props.preview) { if (this.props.preview) {
items.add('preview', items.add('preview',
Button.component({ Button.component({
icon: 'far fa-eye', icon: 'fas fa-eye',
className: 'Button Button--icon', className: 'Button Button--icon',
onclick: this.props.preview, onclick: this.props.preview,
title: app.translator.trans('core.forum.composer.preview_tooltip'), title: app.translator.trans('core.forum.composer.preview_tooltip')
config: elm => $(elm).tooltip()
}) })
); );
} }
@@ -95,15 +91,6 @@ export default class TextEditor extends Component {
return items; return items;
} }
/**
* Build an item list for the toolbar controls.
*
* @return {ItemList}
*/
toolbarItems() {
return new ItemList();
}
/** /**
* Set the value of the text editor. * Set the value of the text editor.
* *
@@ -122,8 +109,6 @@ export default class TextEditor extends Component {
setSelectionRange(start, end) { setSelectionRange(start, end) {
const $textarea = this.$('textarea'); const $textarea = this.$('textarea');
if (!$textarea.length) return;
$textarea[0].setSelectionRange(start, end); $textarea[0].setSelectionRange(start, end);
$textarea.focus(); $textarea.focus();
} }
@@ -136,8 +121,6 @@ export default class TextEditor extends Component {
getSelectionRange() { getSelectionRange() {
const $textarea = this.$('textarea'); const $textarea = this.$('textarea');
if (!$textarea.length) return [0, 0];
return [$textarea[0].selectionStart, $textarea[0].selectionEnd]; return [$textarea[0].selectionStart, $textarea[0].selectionEnd];
} }
@@ -158,8 +141,6 @@ export default class TextEditor extends Component {
const pos = index + insert.length; const pos = index + insert.length;
this.setSelectionRange(pos, pos); this.setSelectionRange(pos, pos);
} }
textarea.dispatchEvent(new CustomEvent('input', {bubbles: true, cancelable: true}));
} }
/** /**

View File

@@ -1,21 +0,0 @@
import Button from '../../common/components/Button';
/**
* The `TextEditorButton` component displays a button suitable for the text
* editor toolbar.
*/
export default class TextEditorButton extends Button {
static initProps(props) {
super.initProps(props);
props.className = props.className || 'Button Button--icon Button--link';
}
config(isInitialized, context) {
super.config(isInitialized, context);
if (isInitialized) return;
this.$().tooltip();
}
}

View File

@@ -86,10 +86,6 @@ export default class History {
* @public * @public
*/ */
back() { back() {
if (! this.canGoBack()) {
return this.home();
}
this.stack.pop(); this.stack.pop();
m.route(this.getCurrent().url); m.route(this.getCurrent().url);

View File

@@ -7,24 +7,10 @@
*/ */
export default class KeyboardNavigatable { export default class KeyboardNavigatable {
constructor() { constructor() {
/**
* Callback to be executed for a specified input.
*
* @callback KeyboardNavigatable~keyCallback
* @param {KeyboardEvent} event
* @returns {boolean}
*/
this.callbacks = {}; this.callbacks = {};
/** // By default, always handle keyboard navigation.
* Callback that determines whether keyboard input should be handled. this.whenCallback = () => true;
* By default, always handle keyboard navigation.
*
* @callback whenCallback
* @param {KeyboardEvent} event
* @returns {boolean}
*/
this.whenCallback = event => true;
} }
/** /**
@@ -33,7 +19,7 @@ export default class KeyboardNavigatable {
* This will be triggered by the Up key. * This will be triggered by the Up key.
* *
* @public * @public
* @param {KeyboardNavigatable~keyCallback} callback * @param {Function} callback
* @return {KeyboardNavigatable} * @return {KeyboardNavigatable}
*/ */
onUp(callback) { onUp(callback) {
@@ -51,7 +37,7 @@ export default class KeyboardNavigatable {
* This will be triggered by the Down key. * This will be triggered by the Down key.
* *
* @public * @public
* @param {KeyboardNavigatable~keyCallback} callback * @param {Function} callback
* @return {KeyboardNavigatable} * @return {KeyboardNavigatable}
*/ */
onDown(callback) { onDown(callback) {
@@ -69,7 +55,7 @@ export default class KeyboardNavigatable {
* This will be triggered by the Return and Tab keys.. * This will be triggered by the Return and Tab keys..
* *
* @public * @public
* @param {KeyboardNavigatable~keyCallback} callback * @param {Function} callback
* @return {KeyboardNavigatable} * @return {KeyboardNavigatable}
*/ */
onSelect(callback) { onSelect(callback) {
@@ -87,7 +73,7 @@ export default class KeyboardNavigatable {
* This will be triggered by the Escape key. * This will be triggered by the Escape key.
* *
* @public * @public
* @param {KeyboardNavigatable~keyCallback} callback * @param {Function} callback
* @return {KeyboardNavigatable} * @return {KeyboardNavigatable}
*/ */
onCancel(callback) { onCancel(callback) {
@@ -95,7 +81,7 @@ export default class KeyboardNavigatable {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
callback(e); callback(e);
}; }
return this; return this;
} }
@@ -106,7 +92,7 @@ export default class KeyboardNavigatable {
* This will be triggered by the Backspace key. * This will be triggered by the Backspace key.
* *
* @public * @public
* @param {KeyboardNavigatable~keyCallback} callback * @param {Function} callback
* @return {KeyboardNavigatable} * @return {KeyboardNavigatable}
*/ */
onRemove(callback) { onRemove(callback) {
@@ -124,7 +110,7 @@ export default class KeyboardNavigatable {
* Provide a callback that determines whether keyboard input should be handled. * Provide a callback that determines whether keyboard input should be handled.
* *
* @public * @public
* @param {KeyboardNavigatable~whenCallback} callback * @param {Function} callback
* @return {KeyboardNavigatable} * @return {KeyboardNavigatable}
*/ */
when(callback) { when(callback) {
@@ -152,7 +138,7 @@ export default class KeyboardNavigatable {
*/ */
navigate(event) { navigate(event) {
// This callback determines whether keyboard should be handled or ignored. // This callback determines whether keyboard should be handled or ignored.
if (!this.whenCallback(event)) return; if (!this.whenCallback()) return;
const keyCallback = this.callbacks[event.which]; const keyCallback = this.callbacks[event.which];
if (keyCallback) { if (keyCallback) {

View File

@@ -1,4 +1,3 @@
import Alert from '../../common/components/Alert';
import Button from '../../common/components/Button'; import Button from '../../common/components/Button';
import Separator from '../../common/components/Separator'; import Separator from '../../common/components/Separator';
import EditUserModal from '../components/EditUserModal'; import EditUserModal from '../components/EditUserModal';
@@ -62,7 +61,7 @@ export default {
items.add('edit', Button.component({ items.add('edit', Button.component({
icon: 'fas fa-pencil-alt', icon: 'fas fa-pencil-alt',
children: app.translator.trans('core.forum.user_controls.edit_button'), children: app.translator.trans('core.forum.user_controls.edit_button'),
onclick: this.editAction.bind(this, user) onclick: this.editAction.bind(user)
})); }));
} }
@@ -85,7 +84,7 @@ export default {
items.add('delete', Button.component({ items.add('delete', Button.component({
icon: 'fas fa-times', icon: 'fas fa-times',
children: app.translator.trans('core.forum.user_controls.delete_button'), children: app.translator.trans('core.forum.user_controls.delete_button'),
onclick: this.deleteAction.bind(this, user) onclick: this.deleteAction.bind(user)
})); }));
} }
@@ -94,51 +93,23 @@ export default {
/** /**
* Delete the user. * Delete the user.
*
* @param {User} user
*/ */
deleteAction(user) { deleteAction() {
if (!confirm(app.translator.trans('core.forum.user_controls.delete_confirmation'))) { if (confirm(app.translator.trans('core.forum.user_controls.delete_confirmation'))) {
return; this.delete().then(() => {
} if (app.current instanceof UserPage && app.current.user === this) {
user.delete().then(() => {
this.showDeletionAlert(user, 'success');
if (app.current instanceof UserPage && app.current.user === user) {
app.history.back(); app.history.back();
} else { } else {
window.location.reload(); window.location.reload();
} }
}).catch(() => this.showDeletionAlert(user, 'error')); });
}, }
/**
* Show deletion alert of user.
*
* @param {User} user
* @param {string} type
*/
showDeletionAlert(user, type) {
const { username, email } = user.data.attributes;
const message = {
success: 'core.forum.user_controls.delete_success_message',
error: 'core.forum.user_controls.delete_error_message',
}[type];
app.alerts.show(new Alert({
type,
children: app.translator.trans(
message, { username, email }
)
}));
}, },
/** /**
* Edit the user. * Edit the user.
*
* @param {User} user
*/ */
editAction(user) { editAction() {
app.modal.show(new EditUserModal({ user })); app.modal.show(new EditUserModal({user: this}));
} }
}; };

View File

@@ -38,7 +38,7 @@
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
&.item-tools { &.item-help {
float: right; float: right;
margin-right: 0; margin-right: 0;
} }

View File

@@ -29,10 +29,6 @@
margin-bottom: 7px; margin-bottom: 7px;
} }
.Select {
display: block;
}
:last-child { :last-child {
margin-bottom: 0; margin-bottom: 0;
} }

View File

@@ -56,9 +56,6 @@
opacity: 0.5; opacity: 0.5;
} }
} }
> .Button--icon {
width: 40px;
}
} }
.App-primaryControl { .App-primaryControl {
width: auto; width: auto;
@@ -74,15 +71,12 @@
} }
} }
.App-primaryControl, .App-backControl { .App-primaryControl, .App-backControl {
margin: 0 !important;
> .Button { > .Button {
color: @header-control-color !important; color: @header-control-color !important;
.Button-icon { .Button-icon {
display: block; display: block;
font-size: 20px; font-size: 20px;
margin: 0;
} }
.Button-label { .Button-label {
display: none; display: none;

View File

@@ -156,7 +156,6 @@
} }
} }
.Modal { .Modal {
max-width: 100%;
margin: 0; margin: 0;
-webkit-transform: none !important; -webkit-transform: none !important;
transform: none !important; transform: none !important;

View File

@@ -51,7 +51,7 @@
position: absolute; position: absolute;
background: @primary-color; background: @primary-color;
top: 10px; top: 10px;
right: 3px; right: 10px;
width: 14px; width: 14px;
height: 14px; height: 14px;
border-radius: 7px; border-radius: 7px;

View File

@@ -1,13 +1,14 @@
@import "fontawesome"; @import "fontawesome";
@import "brands"; @import "fa-brands";
@import "regular"; @import "fa-regular";
@import "solid"; @import "fa-solid";
@fa-font-path: "./fonts"; @fa-font-path: "./fonts";
@import "normalize"; @import "normalize";
@import "print"; @import "print";
@import "scaffolding"; @import "scaffolding";
@import "sideNav"; @import "sideNav";
@import "mixins";
@import "App"; @import "App";
@import "Alert"; @import "Alert";
@@ -26,3 +27,5 @@
@import "Search"; @import "Search";
@import "Select"; @import "Select";
@import "Tooltip"; @import "Tooltip";
@import "variables";

View File

@@ -343,19 +343,11 @@
} }
.TextEditor-controls { .TextEditor-controls {
margin: 0; margin: 0;
padding: 10px 0; padding: 15px 0;
list-style-type: none; list-style-type: none;
overflow-x: auto;
white-space: nowrap;
li { & li {
display: inline-block; display: inline-block;
margin-right: 10px;
}
}
.TextEditor-toolbar {
.Button--icon {
width: 28px;
} }
} }
@@ -365,6 +357,10 @@
padding: 10px 20px; padding: 10px 20px;
border-top: 1px solid @control-bg; border-top: 1px solid @control-bg;
li {
margin-right: 5px;
}
.fullScreen & { .fullScreen & {
margin: 0; margin: 0;
border-top: 0; border-top: 0;

View File

@@ -87,10 +87,6 @@
&:hover { &:hover {
text-decoration: none; text-decoration: none;
background: @control-bg; background: @control-bg;
.Notification-action {
display: block;
}
} }
.Avatar { .Avatar {
.Avatar--size(24px); .Avatar--size(24px);
@@ -102,27 +98,6 @@
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
} }
.Notification-action {
float: right;
display: none;
margin-top: -7px;
margin-right: -10px;
line-height: inherit;
padding: 5px 0;
& when (@config-colored-header = true) {
.Button--color(@control-color, @control-bg);
&:hover {
color: @link-color;
}
}
.icon {
font-size: 12px;
}
}
} }
.Notification-icon { .Notification-icon {
float: left; float: left;

View File

@@ -147,38 +147,26 @@
border-radius: 0; border-radius: 0;
} }
} }
h1, h2, h3, h4, h5, h6 {
margin-top: 1em;
margin-bottom: 16px;
font-weight: bold;
}
h1 { h1 {
font-size: 225%; font-size: 160%;
} }
h2 { h2 {
font-size: 175%; font-size: 120%;
font-weight: bold;
} }
h3 { h3 {
font-size: 150%;
}
h4 {
font-size: 125%;
}
h5, h6 {
font-size: 100%; font-size: 100%;
font-weight: bold;
text-transform: uppercase;
} }
h6 { h4, h5, h6 {
color: @muted-more-color; font-size: 100%;
font-weight: bold;
} }
img, iframe { img, iframe {
max-width: 100%; max-width: 100%;
} }
} }
.Post-body, .Post-preview {
> *:first-child {
margin-top: 0 !important;
}
}
.Post--hidden { .Post--hidden {
.Post-header, .Post-header a, .PostUser h3, .PostUser h3 a { .Post-header, .Post-header a, .PostUser h3, .PostUser h3 a {

View File

@@ -78,7 +78,6 @@
&, > li { &, > li {
display: inline-block; display: inline-block;
margin-right: 5px
} }
} }
.UserCard-info { .UserCard-info {

View File

@@ -1,5 +1,10 @@
.UserPage { .UserPage {
.UserHero .Dropdown-toggle .Button-icon { .UserCard-controls {
float: right;
.Dropdown-toggle .Button-icon {
display: none; display: none;
} }
} }
}

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Util\Str; use Flarum\Util\Str;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,24 +3,25 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\Builder; use Illuminate\Database\Schema\Builder;
// https://github.com/doctrine/dbal/issues/2566#issuecomment-480217999
return [ return [
'up' => function (Builder $schema) { 'up' => function (Builder $schema) {
$schema->table('posts', function (Blueprint $table) { $schema->table('posts', function (Blueprint $table) {
$table->mediumText('content')->comment(' ')->change(); $table->mediumText('content')->change();
}); });
}, },
'down' => function (Builder $schema) { 'down' => function (Builder $schema) {
$schema->table('posts', function (Blueprint $table) { $schema->table('posts', function (Blueprint $table) {
$table->text('content')->comment('')->change(); $table->text('content')->change();
}); });
} }
]; ];

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Builder; use Illuminate\Database\Schema\Builder;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Builder; use Illuminate\Database\Schema\Builder;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Query\Expression; use Illuminate\Database\Query\Expression;
@@ -42,11 +44,10 @@ return [
'down' => function (Builder $schema) { 'down' => function (Builder $schema) {
$schema->table('discussions', function (Blueprint $table) { $schema->table('discussions', function (Blueprint $table) {
$table->dropForeign(['user_id']); $table->dropForeign([
$table->dropForeign(['last_posted_user_id']); 'user_id', 'last_posted_user_id', 'hidden_user_id',
$table->dropForeign(['hidden_user_id']); 'first_post_id', 'last_post_id'
$table->dropForeign(['first_post_id']); ]);
$table->dropForeign(['last_post_id']);
}); });
} }
]; ];

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
@@ -32,8 +34,7 @@ return [
'down' => function (Builder $schema) { 'down' => function (Builder $schema) {
$schema->table('discussion_user', function (Blueprint $table) { $schema->table('discussion_user', function (Blueprint $table) {
$table->dropForeign(['user_id']); $table->dropForeign(['user_id', 'discussion_id']);
$table->dropForeign(['discussion_id']);
}); });
} }
]; ];

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Builder; use Illuminate\Database\Schema\Builder;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Flarum\Database\Migration; use Flarum\Database\Migration;

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
@@ -32,8 +34,7 @@ return [
'down' => function (Builder $schema) { 'down' => function (Builder $schema) {
$schema->table('group_user', function (Blueprint $table) { $schema->table('group_user', function (Blueprint $table) {
$table->dropForeign(['user_id']); $table->dropForeign(['user_id', 'group_id']);
$table->dropForeign(['group_id']);
}); });
} }
]; ];

View File

@@ -3,8 +3,10 @@
/* /*
* This file is part of Flarum. * This file is part of Flarum.
* *
* For detailed copyright and license information, please view the * (c) Toby Zerner <toby.zerner@gmail.com>
* LICENSE file that was distributed with this source code. *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/ */
use Carbon\Carbon; use Carbon\Carbon;

Some files were not shown because too many files have changed in this diff Show More