1
0
mirror of https://github.com/flarum/core.git synced 2025-08-13 03:44:32 +02:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Daniël Klabbers
dff35c1046 fix: mentions posts is not an array but collection 2023-05-15 12:20:02 +02:00
380 changed files with 1297 additions and 5078 deletions

View File

@@ -25,7 +25,7 @@ on:
description: Versions of PHP to test with. Should be array of strings encoded as JSON array
type: string
required: false
default: '["7.3", "7.4", "8.0", "8.1", "8.2", "8.3"]'
default: '["7.3", "7.4", "8.0", "8.1", "8.2"]'
php_extensions:
description: PHP extensions to install.
@@ -45,25 +45,13 @@ on:
required: false
default: error_reporting=E_ALL
runner_type:
description: The type of runner to use for the jobs. This should be one of the types supported by the `runs-on` keyword.
type: string
required: false
default: 'ubuntu-latest'
secrets:
composer_auth:
description: The Composer auth tokens to use for private packages.
required: false
env:
COMPOSER_ROOT_VERSION: dev-main
FLARUM_TEST_TMP_DIR_LOCAL: tests/integration/tmp
COMPOSER_AUTH: ${{ secrets.composer_auth }}
jobs:
test:
runs-on: ${{ inputs.runner_type }}
runs-on: ubuntu-latest
strategy:
matrix:
@@ -103,10 +91,6 @@ jobs:
# Include testing PHP 8.2 with deprecation warnings disabled.
- php: 8.2
php_ini_values: error_reporting=E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED
- php: 8.3
php_ini_values: error_reporting=E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED
# - php: 8.4
# php_ini_values: error_reporting=E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED
# To reduce number of actions, we exclude some PHP versions from running with some DB versions.
exclude:
@@ -174,13 +158,11 @@ jobs:
COMPOSER_PROCESS_TIMEOUT: 600
phpstan:
runs-on: ${{ inputs.runner_type }}
runs-on: ubuntu-latest
strategy:
matrix:
php: ${{ fromJSON(inputs.php_versions) }}
# exclude:
# - php: 8.4
name: 'PHPStan PHP ${{ matrix.php }}'

View File

@@ -74,7 +74,7 @@ on:
description: The node version to use for the workflow.
type: number
required: false
default: 20
default: 16
js_package_manager:
description: "Enable TypeScript?"
@@ -86,41 +86,30 @@ on:
type: string
required: false
runner_type:
description: The type of runner to use for the jobs. This should be one of the types supported by the `runs-on` keyword.
type: string
required: false
default: 'ubuntu-latest'
secrets:
bundlewatch_github_token:
description: The GitHub token to use for Bundlewatch.
required: false
composer_auth:
description: The Composer auth tokens to use for private packages.
required: false
env:
COMPOSER_ROOT_VERSION: dev-main
ci_script: ${{ inputs.js_package_manager == 'yarn' && 'yarn install --immutable' || 'npm ci' }}
cache_dependency_path: ${{ inputs.cache_dependency_path || format(inputs.js_package_manager == 'yarn' && '{0}/yarn.lock' || '{0}/package-lock.json', inputs.frontend_directory) }}
COMPOSER_AUTH: ${{ secrets.composer_auth }}
DISABLE_V8_COMPILE_CACHE: 1
jobs:
build:
name: Checks & Build
runs-on: ${{ inputs.runner_type }}
runs-on: ubuntu-latest
if: >-
((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) || github.event_name != 'pull_request')
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version: ${{ inputs.node_version }}
cache: ${{ inputs.js_package_manager }}
@@ -143,7 +132,7 @@ jobs:
working-directory: ${{ inputs.frontend_directory }}
- name: JS Checks & Production Build
uses: flarum/action-build@v4
uses: flarum/action-build@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
build_script: ${{ inputs.build_script }}

View File

@@ -1,4 +1,4 @@
name: Extension Manager PHP
name: Package Manager PHP
on: [workflow_dispatch, push, pull_request]

View File

@@ -10,7 +10,7 @@ jobs:
backend_directory: ./
js_package_manager: yarn
cache_dependency_path: ./yarn.lock
main_git_branch: 1.x
main_git_branch: main
enable_tests: true
# @TODO: fix bundlewatch
enable_bundlewatch: false

View File

@@ -20,7 +20,7 @@ jobs:
uses: actions/checkout@v3
- name: Prepare release
uses: flarum/action-release@master
with:
next_tag: ${{ inputs.version }}
github_token: ${{ secrets.GITHUB_TOKEN }}
open_collective_token: ${{ secrets.OPEN_COLLECTIVE_TOKEN }}
env:
NEXT_TAG: ${{ inputs.version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPEN_COLLECTIVE_TOKEN: ${{ secrets.OPEN_COLLECTIVE_TOKEN }}

View File

@@ -1,127 +1,5 @@
# Changelog
## [v1.8.9](https://github.com/flarum/framework/compare/v1.8.8...v1.8.9)
### Fixed
* change condition when unread label is shown in Scrubber (https://github.com/flarum/framework/pull/4116)
* resolve a11y warnings in Admin Frontend (https://github.com/flarum/framework/pull/4114)
* return empty object if selected mail driver is unavailable (https://github.com/flarum/framework/pull/4113)
### Changed
* change private to protected, allowing extensibility (https://github.com/flarum/framework/pull/4119)
* change length of email field (https://github.com/flarum/framework/pull/4117)
### Added
* Implement Support for Translatable Validation Attribute Errors (https://github.com/flarum/framework/pull/4070)
* PHP 8.4 support (https://github.com/flarum/framework/pull/4105)
* conditional extend whenExtensionDisabled (https://github.com/flarum/framework/pull/4107)
## [v1.8.8](https://github.com/flarum/framework/compare/v1.8.7...v1.8.8)
### Fixed
* previously suspended admin users cannot remove their avatar after suspension (https://github.com/flarum/framework/pull/4071)
* new search term not being passed (https://github.com/flarum/framework/pull/4083)
* postfooter did not apply the empty subclass (https://github.com/flarum/framework/pull/4085)
## [v1.8.7](https://github.com/flarum/framework/compare/v1.8.6...v1.8.7)
### Fixed
* BasicsPage not viewable if only one language pack enabled, and/or `flarum/nicknames` not enabled (https://github.com/flarum/framework/pull/4062)
## [v1.8.6](https://github.com/flarum/framework/compare/v1.8.5...v1.8.6)
### Fixed
* reset admin page save button in catch handler (https://github.com/flarum/framework/pull/3963)
* suspended users can remove avatar (https://github.com/flarum/framework/pull/3998)
* return null if content left empty in formatter (https://github.com/flarum/framework/pull/4059)
### Changed
* allow DiscussionsSearchSource to be extended (https://github.com/flarum/framework/pull/4025)
* allow modifying the discussion title on PostsUserPage (https://github.com/flarum/framework/pull/4031)
* make it easier to modify AppearancePage, BasicsPage, MailPage (https://github.com/flarum/framework/pull/4037)
* point fontawesome links at v5 free (https://github.com/flarum/framework/pull/4038)
* make WelcomeHero extensible (https://github.com/flarum/framework/pull/4039)
* make PostMeta extensible (https://github.com/flarum/framework/pull/4040)
* extensible TagHero (https://github.com/flarum/framework/pull/4041)
* allow extending PostPreview content (https://github.com/flarum/framework/pull/4043)
* allow classes that extends AbstractJob to be placed on a specified queue (https://github.com/flarum/framework/pull/4026)
* use common component for ip address display (https://github.com/flarum/framework/pull/4042)
* make it easier to add content after the first post (https://github.com/flarum/framework/pull/4050)
* improve extensibility of IndexPage (https://github.com/flarum/framework/pull/4045)
* improve extensibility of DiscussionPage (https://github.com/flarum/framework/pull/4046)
* backport & improve extensibility of DiscussionListItem (https://github.com/flarum/framework/pull/4048)
* improve & use extensibility of CommentPost & Post (https://github.com/flarum/framework/pull/4047)
* allow labels of PostStreamScrubber to be customized (https://github.com/flarum/framework/pull/4049)
* allow to customize time formats through translations (https://github.com/flarum/framework/pull/4053)
### Added
* Export all missing modules in compat (https://github.com/flarum/framework/pull/4044)
* Add (some) missing shims (https://github.com/flarum/framework/pull/4027)
* provide an 'actions' dropdown for extensions to add their additional buttons to the admin UserListPage (https://github.com/flarum/framework/pull/4054)
## [v1.8.5](https://github.com/flarum/framework/compare/v1.8.4...v1.8.5)
### Fixed
* Logout controller allows open redirects [#3948]
## [v1.8.4](https://github.com/flarum/framework/compare/v1.8.3...v1.8.4)
### Fixed
* `s9e/textformatter` 2.15 has breaking changes [#3946]
## [v1.8.3](https://github.com/flarum/framework/compare/v1.8.2...v1.8.3)
### Fixed
* Console extender does not accept ::class [#3900]
* Conditional extender instantiation [#3898]
## [v1.8.2](https://github.com/flarum/framework/compare/v1.8.1...v1.8.2)
### Fixed
* suspended users can abuse avatar upload [#3890]
* missing compat exports [#3888]
## [v1.8.1](https://github.com/flarum/framework/compare/v1.8.0...v1.8.1)
### Fixed
* recover temporary solution for html entities in browser title (e72541e35de4f71f9d870bbd9bb46ddf586bdf1d)
* custom contrast color affected by parents (577890d89c593ae5b6cb96083fab69e2f1ae600c)
* reply placeholder wrong positioning (253a3d281dbf5ce3fa712b629b80587cf67e7dbe)
* (mentions) missed post mentions UI changes with lazy loading [#3832]
* (mentions) cannot use newly introduced mentionables extender [#3849]
* (mentions) missing slug from post mention links ([5a4bb7c](5a4bb7ccf226f66dd44816cb69b3d7cfe4ad7f7c))
## [v1.8.0](https://github.com/flarum/framework/compare/v1.7.1...v1.8.0)
### Fixed
- (a11y) reply placeholder not accessible [#3793]
- (bbcode) highlight.js does not work after changing post content [#3817]
- (bbcode) localize quote `wrote` string [#3809]
- (mentions) mentions XHR fired even after mentioning is done [#3806]
- (package-manager) available core updates cause an error in the dashboard ([fab71f2](fab71f2d01fa20ce9b3002833339dc5ea3ea6301))
- (tags) not all tags are loaded in the permission grid [#3804]
- (tags) tag discussion modal filters with exact matches only after first index [#3786]
- (testing) always clear cache in integration test's tearDown [#3818]
- `UserSecurityPage` not exported ([232618a](232618aba604ab003425df38b895208c863d3260))
- `isDark()` utility can receive null value [#3774]
- approving a post does not bump user `comment_count` [#3790]
- circular dependencies disable all involved extensions [#3785]
- color input overflowing the input box [#3796]
- deleting a discussion from the profile does not visually remove it [#3799]
- discussion page showing horizontal scroll on iOS [#3821]
- empty string displayed as SelectDropdown title [#3773]
- filter values are not validated [#3795]
- infinite scroll not initialized for notifications on big screens [#3733]
- notification subject discussion eager loading fails [#3788]
- null as 2nd param in `preg_match` is deprecated [#3801]
- unread count in post stream not visible [#3791]
- unreadable badge icon on certain colors [#3810]
- integrity constraint violation [#3772]
### Changed
- (core,mentions) limit `mentionedBy` post relation results [#3780]
- (likes) limit `likes` relationship results [#3781]
- Change some methods from private to protected, to be able to extend the affected classes [#3802]
- Do not catch exceptions when testing Console commands [#3813]
- drop usage of jquery in `install` and `update` interfaces [#3797]
- extensibility improvements [#3729]
- major frontend JS cleanup [#3609]
- revert ineffective code for encoding of page title [#3768]
- speed up post creation time [#3808]
### Added
- (mentions,tags) tag mentions [#3769]
- add delete own posts permission [#3784]
- add a trait to flush the formatter cache in tests [#3811]
- add user creation to users list page [#3744]
- cli command for enabling or disabling an extension [#3816]
- conditional extenders [#3759]
- provide old content to `Revised` event [#3789]
## [v1.7.1](https://github.com/flarum/framework/compare/v1.7.0...v1.7.1)
### Fixed
- (tags) composer tag selection modal using wrong primary max & min numbers (abc9670659426b765274376945b818b70d84848c)

View File

@@ -1,5 +1,5 @@
<p align="center">
<a href="https://flarum.org/"><img src="https://flarum.org/images/flarum.svg"></a>
<a href="https://flarum.org/"><img src="https://flarum.org/assets/img/logo.png"></a>
</p>
<p align="center">
@@ -7,6 +7,7 @@
<a href="https://packagist.org/packages/flarum/core"><img src="https://img.shields.io/packagist/dt/flarum/core" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/flarum/core"><img src="https://img.shields.io/github/v/release/flarum/core?sort=semver" alt="Latest Version"></a>
<a href="https://packagist.org/packages/flarum/core"><img src="https://img.shields.io/packagist/l/flarum/core" alt="License"></a>
<a href="https://huntr.dev/bounties/disclose/?target=https://github.com/flarum/core"><img src="https://cdn.huntr.dev/huntr_security_badge_mono.svg" alt="huntr"></a>
<a href="https://github.styleci.io/repos/28257573"><img src="https://github.styleci.io/repos/28257573/shield?style=flat" alt="StyleCI"></a>
</p>
@@ -37,4 +38,3 @@ If you discover a security vulnerability within Flarum, please send an e-mail to
## License
Flarum is open-source software licensed under the [MIT License](https://github.com/flarum/flarum/blob/master/LICENSE).

View File

@@ -46,7 +46,7 @@
"Flarum\\Lock\\": "extensions/lock/src",
"Flarum\\Mentions\\": "extensions/mentions/src",
"Flarum\\Nicknames\\": "extensions/nicknames/src",
"Flarum\\ExtensionManager\\": "extensions/package-manager/src",
"Flarum\\PackageManager\\": "extensions/package-manager/src",
"Flarum\\Pusher\\": "extensions/pusher/src",
"Flarum\\Statistics\\": "extensions/statistics/src",
"Flarum\\Sticky\\": "extensions/sticky/src",
@@ -74,7 +74,7 @@
"flarum/markdown": "self.version",
"flarum/mentions": "self.version",
"flarum/nicknames": "self.version",
"flarum/extension-manager": "self.version",
"flarum/package-manager": "self.version",
"flarum/pusher": "self.version",
"flarum/statistics": "self.version",
"flarum/sticky": "self.version",
@@ -112,9 +112,9 @@
"illuminate/view": "^8.0",
"intervention/image": "2.5.* || ^2.6.1",
"jenssegers/agent": "^2.6",
"laminas/laminas-diactoros": "^2.4.1 || ^3.0.0",
"laminas/laminas-httphandlerrunner": "^1.2.0 || ^2.3.0 || ^3.0.0",
"laminas/laminas-stratigility": "^3.2.2 || ^4.0.0",
"laminas/laminas-diactoros": "^2.4.1",
"laminas/laminas-httphandlerrunner": "^1.2.0 || ^2.3.0",
"laminas/laminas-stratigility": "^3.2.2",
"league/flysystem": "^1.0.11",
"matthiasmullie/minify": "^1.3",
"middlewares/base-path": "^2.0.1",
@@ -127,7 +127,7 @@
"psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0",
"pusher/pusher-php-server": "^2.2",
"s9e/text-formatter": ">=2.3.6 <2.15",
"s9e/text-formatter": "^2.3.6",
"staudenmeir/eloquent-eager-limit": "^1.0",
"sycho/json-api": "^0.5.0",
"sycho/sourcemap": "^2.0.0",

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8",
"flarum/core": "^1.7",
"flarum/approval": "^1.7"
},
"autoload": {

View File

@@ -15,7 +15,6 @@
"declarationDir": "./dist-typings",
"paths": {
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
"flarum/flags/*": ["../../flags/js/dist-typings/*"]
}
}

View File

@@ -50,7 +50,7 @@ class Akismet
$client = new Client();
return $client->request('POST', "$this->apiUrl/$type", [
'headers' => [
'headers' => [
'User-Agent' => "Flarum/$this->flarumVersion | Akismet/$this->extensionVersion",
],
'form_params' => $this->params,

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8",
"flarum/core": "^1.7",
"flarum/flags": "^1.7"
},
"autoload": {

View File

@@ -1,15 +0,0 @@
import 'flarum/common/models/Discussion';
import 'flarum/common/models/Post';
declare module 'flarum/common/models/Discussion' {
export default interface Discussion {
isApproved(): boolean;
}
}
declare module 'flarum/common/models/Post' {
export default interface Post {
isApproved(): boolean;
canApprove(): boolean;
}
}

View File

@@ -11,7 +11,6 @@ namespace Flarum\Approval\Listener;
use Flarum\Approval\Event\PostWasApproved;
use Flarum\Post\Event\Saving;
use Flarum\User\Exception\PermissionDeniedException;
use Illuminate\Contracts\Events\Dispatcher;
class ApproveContent
@@ -24,42 +23,23 @@ class ApproveContent
$events->listen(Saving::class, [$this, 'approvePost']);
}
/**
* @throws PermissionDeniedException
*/
public function approvePost(Saving $event)
{
$attributes = $event->data['attributes'];
$post = $event->post;
// Nothing to do if it is already approved.
if ($post->is_approved) {
return;
}
/*
* We approve a post in one of two cases:
* - The post was unapproved and the allowed action is approving it. We trigger an event.
* - The post was unapproved and the allowed actor is hiding or un-hiding it.
* We approve it silently if the action is unhiding.
*/
$approvingSilently = false;
if (isset($attributes['isApproved'])) {
$event->actor->assertCan('approve', $post);
$isApproved = (bool) $attributes['isApproved'];
} elseif (isset($attributes['isHidden']) && $event->actor->can('approve', $post)) {
} elseif (! empty($attributes['isHidden']) && $event->actor->can('approve', $post)) {
$isApproved = true;
$approvingSilently = $attributes['isHidden'];
}
if (! empty($isApproved)) {
$post->is_approved = true;
if (! $approvingSilently) {
$post->raise(new PostWasApproved($post, $event->actor));
}
$post->raise(new PostWasApproved($post, $event->actor));
}
}
}

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8"
"flarum/core": "^1.7"
},
"autoload": {
"psr-4": {

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8"
"flarum/core": "^1.7"
},
"autoload": {
"psr-4": {

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8"
"flarum/core": "^1.7"
},
"extra": {
"branch-alias": {

2
extensions/emoji/js/dist/forum.js generated vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +0,0 @@
import AutocompleteDropdown from './fragments/AutocompleteDropdown';
import getEmojiIconCode from './helpers/getEmojiIconCode';
export default {
'emoji/fragments/AutocompleteDropdown': AutocompleteDropdown,
'emoji/helpers/getEmojiIconCode': getEmojiIconCode,
};

View File

@@ -11,9 +11,3 @@ app.initializers.add('flarum-emoji', () => {
// render emoji as image in Posts content and title.
renderEmoji();
});
// Expose compat API
import emojiCompat from './compat';
import { compat } from '@flarum/core/forum';
Object.assign(compat, emojiCompat);

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8.6"
"flarum/core": "^1.7"
},
"autoload": {
"psr-4": {

View File

@@ -1,7 +1,3 @@
import 'flarum/common/models/Post';
import 'flarum/forum/ForumApplication';
import 'flarum/forum/components/Post';
import Flag from '../forum/models/Flag';
import FlagListState from '../forum/states/FlagListState';
import Mithril from 'mithril';

View File

@@ -7,7 +7,6 @@ declare const _default: {
'flags/components/FlagPostModal': typeof FlagPostModal;
'flags/components/FlagsPage': typeof FlagsPage;
'flags/components/FlagsDropdown': typeof FlagsDropdown;
'flags/states/FlagListState': typeof FlagListState;
};
export default _default;
import addFlagsToPosts from "./addFlagsToPosts";
@@ -18,4 +17,3 @@ import FlagList from "./components/FlagList";
import FlagPostModal from "./components/FlagPostModal";
import FlagsPage from "./components/FlagsPage";
import FlagsDropdown from "./components/FlagsDropdown";
import FlagListState from "./states/FlagListState";

View File

@@ -1,2 +1,2 @@
declare const _default: (import("flarum/common/extenders/Routes").default | import("flarum/common/extenders/Store").default | import("flarum/common/extenders/Model").default)[];
declare const _default: (import("flarum/common/extenders/Model").default | import("flarum/common/extenders/Routes").default | import("flarum/common/extenders/Store").default)[];
export default _default;

2
extensions/flags/js/dist/forum.js generated vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,3 @@
import 'flarum/common/models/Post';
import 'flarum/forum/ForumApplication';
import 'flarum/forum/components/Post';
import Flag from '../forum/models/Flag';
import FlagListState from '../forum/states/FlagListState';
import Mithril from 'mithril';

View File

@@ -75,7 +75,7 @@ export default function () {
return items;
};
extend(Post.prototype, 'viewItems', function (items) {
extend(Post.prototype, 'content', function (vdom) {
const post = this.attrs.post;
const flags = post.flags();
@@ -83,8 +83,7 @@ export default function () {
if (post.isHidden()) this.revealContent = true;
items.add(
'flagged',
vdom.unshift(
<div className="Post-flagged">
<div className="Post-flagged-flags">
{flags.map((flag) => (
@@ -92,8 +91,7 @@ export default function () {
))}
</div>
<div className="Post-flagged-actions">{this.flagActionItems().toArray()}</div>
</div>,
110
</div>
);
});

View File

@@ -6,7 +6,6 @@ import FlagList from './components/FlagList';
import FlagPostModal from './components/FlagPostModal';
import FlagsPage from './components/FlagsPage';
import FlagsDropdown from './components/FlagsDropdown';
import FlagListState from './states/FlagListState';
export default {
'flags/addFlagsToPosts': addFlagsToPosts,
@@ -17,5 +16,4 @@ export default {
'flags/components/FlagPostModal': FlagPostModal,
'flags/components/FlagsPage': FlagsPage,
'flags/components/FlagsDropdown': FlagsDropdown,
'flags/states/FlagListState': FlagListState,
};

View File

@@ -40,7 +40,6 @@ class AddCanFlagAttribute
// If $actor is the post author, check to see if the setting is enabled
return (bool) $this->settings->get('flarum-flags.can_flag_own');
}
// $actor is not the post author
return true;
}

View File

@@ -31,10 +31,10 @@ class FlagSerializer extends AbstractSerializer
}
return [
'type' => $flag->type,
'reason' => $flag->reason,
'type' => $flag->type,
'reason' => $flag->reason,
'reasonDetail' => $flag->reason_detail,
'createdAt' => $this->formatDate($flag->created_at),
'createdAt' => $this->formatDate($flag->created_at),
];
}

View File

@@ -7,7 +7,7 @@
],
"license": "MIT",
"require": {
"flarum/core": "^1.8"
"flarum/core": "^1.7"
},
"extra": {
"branch-alias": {

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8"
"flarum/core": "^1.7"
},
"autoload": {
"psr-4": {

2
extensions/likes/js/dist/forum.js generated vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +1,9 @@
import 'flarum/common/models/Post';
import Post from 'flarum/common/models/Post';
import User from 'flarum/common/models/User';
declare module 'flarum/common/models/Post' {
export default interface Post {
likes(): User[];
likesCount(): number;
canLike(): boolean;
}
}

View File

@@ -1,11 +0,0 @@
import LikesUserPage from './components/LikesUserPage';
import PostLikedNotification from './components/PostLikedNotification';
import PostLikesModal from './components/PostLikesModal';
import PostLikesModalState from './states/PostLikesModalState';
export default {
'likes/components/LikesUserPage': LikesUserPage,
'likes/components/PostLikedNotification': PostLikedNotification,
'likes/components/PostLikesModal': PostLikesModal,
'likes/states/PostLikesModalState': PostLikesModalState,
};

View File

@@ -24,9 +24,3 @@ app.initializers.add('flarum-likes', () => {
});
});
});
// Expose compat API
import likesCompat from './compat';
import { compat } from '@flarum/core/forum';
Object.assign(compat, likesCompat);

View File

@@ -44,6 +44,7 @@ class LoadLikesRelationship
$loadable = null;
if ($data instanceof Discussion) {
// @phpstan-ignore-next-line
$loadable = $data->newCollection($data->posts)->filter(function ($post) {
return $post instanceof Post;
});

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8"
"flarum/core": "^1.7"
},
"autoload": {
"psr-4": {

2
extensions/lock/js/dist/forum.js generated vendored
View File

@@ -1,2 +1,2 @@
(()=>{var o={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return o.d(n,{a:n}),n},d:(t,n)=>{for(var c in n)o.o(n,c)&&!o.o(t,c)&&Object.defineProperty(t,c,{enumerable:!0,get:n[c]})},o:(o,t)=>Object.prototype.hasOwnProperty.call(o,t),r:o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})}},t={};(()=>{"use strict";o.r(t),o.d(t,{extend:()=>j});const n=flarum.core.compat["common/extend"],c=flarum.core.compat["forum/app"];var e=o.n(c);const r=flarum.core.compat["forum/components/NotificationGrid"];var s=o.n(r);function a(o,t){return a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(o,t){return o.__proto__=t,o},a(o,t)}function i(o,t){o.prototype=Object.create(t.prototype),o.prototype.constructor=o,a(o,t)}const u=flarum.core.compat["forum/components/Notification"];var l=function(o){function t(){return o.apply(this,arguments)||this}i(t,o);var n=t.prototype;return n.icon=function(){return"fas fa-lock"},n.href=function(){var o=this.attrs.notification;return e().route.discussion(o.subject(),o.content().postNumber)},n.content=function(){return e().translator.trans("flarum-lock.forum.notifications.discussion_locked_text",{user:this.attrs.notification.fromUser()})},t}(o.n(u)());const f=flarum.core.compat["common/models/Discussion"];var d=o.n(f);const p=flarum.core.compat["common/components/Badge"];var k=o.n(p);const y=flarum.core.compat["forum/utils/DiscussionControls"];var b=o.n(y);const _=flarum.core.compat["forum/components/DiscussionPage"];var v=o.n(_);const h=flarum.core.compat["common/components/Button"];var L=o.n(h);const g=flarum.core.compat["common/extenders"];var O=o.n(g);const x=flarum.core.compat["forum/components/EventPost"];var P=function(o){function t(){return o.apply(this,arguments)||this}i(t,o);var n=t.prototype;return n.icon=function(){return this.attrs.post.content().locked?"fas fa-lock":"fas fa-unlock"},n.descriptionKey=function(){return this.attrs.post.content().locked?"flarum-lock.forum.post_stream.discussion_locked_text":"flarum-lock.forum.post_stream.discussion_unlocked_text"},t}(o.n(x)());const j=[(new(O().PostTypes)).add("discussionLocked",P),new(O().Model)(d()).attribute("isLocked").attribute("canLock")],D={"lock/components/DiscussionLockedNotification":l,"lock/components/DiscussionLockedPost":P},S=flarum.core;e().initializers.add("flarum-lock",(function(){e().notificationComponents.discussionLocked=l,(0,n.extend)(d().prototype,"badges",(function(o){this.isLocked()&&o.add("locked",m(k(),{type:"locked",label:e().translator.trans("flarum-lock.forum.badge.locked_tooltip"),icon:"fas fa-lock"}))})),(0,n.extend)(b(),"moderationControls",(function(o,t){t.canLock()&&o.add("lock",m(L(),{icon:"fas fa-lock",onclick:this.lockAction.bind(t)},e().translator.trans("flarum-lock.forum.discussion_controls."+(t.isLocked()?"unlock":"lock")+"_button")))})),b().lockAction=function(){this.save({isLocked:!this.isLocked()}).then((function(){e().current.matches(v())&&e().current.get("stream").update(),m.redraw()}))},(0,n.extend)(s().prototype,"notificationTypes",(function(o){o.add("discussionLocked",{name:"discussionLocked",icon:"fas fa-lock",label:e().translator.trans("flarum-lock.forum.settings.notify_discussion_locked_label")})}))})),Object.assign(S.compat,D)})(),module.exports=t})();
(()=>{var o={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return o.d(n,{a:n}),n},d:(t,n)=>{for(var e in n)o.o(n,e)&&!o.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:n[e]})},o:(o,t)=>Object.prototype.hasOwnProperty.call(o,t),r:o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})}},t={};(()=>{"use strict";o.r(t),o.d(t,{extend:()=>j});const n=flarum.core.compat["common/extend"],e=flarum.core.compat["forum/app"];var c=o.n(e);const r=flarum.core.compat["forum/components/NotificationGrid"];var s=o.n(r);function a(o,t){return a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(o,t){return o.__proto__=t,o},a(o,t)}function i(o,t){o.prototype=Object.create(t.prototype),o.prototype.constructor=o,a(o,t)}const u=flarum.core.compat["forum/components/Notification"];var f=function(o){function t(){return o.apply(this,arguments)||this}i(t,o);var n=t.prototype;return n.icon=function(){return"fas fa-lock"},n.href=function(){var o=this.attrs.notification;return c().route.discussion(o.subject(),o.content().postNumber)},n.content=function(){return c().translator.trans("flarum-lock.forum.notifications.discussion_locked_text",{user:this.attrs.notification.fromUser()})},t}(o.n(u)());const l=flarum.core.compat["common/models/Discussion"];var d=o.n(l);const p=flarum.core.compat["common/components/Badge"];var k=o.n(p);const y=flarum.core.compat["forum/utils/DiscussionControls"];var b=o.n(y);const _=flarum.core.compat["forum/components/DiscussionPage"];var v=o.n(_);const h=flarum.core.compat["common/components/Button"];var g=o.n(h);const L=flarum.core.compat["common/extenders"];var x=o.n(L);const O=flarum.core.compat["forum/components/EventPost"];var P=function(o){function t(){return o.apply(this,arguments)||this}i(t,o);var n=t.prototype;return n.icon=function(){return this.attrs.post.content().locked?"fas fa-lock":"fas fa-unlock"},n.descriptionKey=function(){return this.attrs.post.content().locked?"flarum-lock.forum.post_stream.discussion_locked_text":"flarum-lock.forum.post_stream.discussion_unlocked_text"},t}(o.n(O)());const j=[(new(x().PostTypes)).add("discussionLocked",P),new(x().Model)(d()).attribute("isLocked").attribute("canLock")];c().initializers.add("flarum-lock",(function(){c().notificationComponents.discussionLocked=f,(0,n.extend)(d().prototype,"badges",(function(o){this.isLocked()&&o.add("locked",m(k(),{type:"locked",label:c().translator.trans("flarum-lock.forum.badge.locked_tooltip"),icon:"fas fa-lock"}))})),(0,n.extend)(b(),"moderationControls",(function(o,t){t.canLock()&&o.add("lock",m(g(),{icon:"fas fa-lock",onclick:this.lockAction.bind(t)},c().translator.trans("flarum-lock.forum.discussion_controls."+(t.isLocked()?"unlock":"lock")+"_button")))})),b().lockAction=function(){this.save({isLocked:!this.isLocked()}).then((function(){c().current.matches(v())&&c().current.get("stream").update(),m.redraw()}))},(0,n.extend)(s().prototype,"notificationTypes",(function(o){o.add("discussionLocked",{name:"discussionLocked",icon:"fas fa-lock",label:c().translator.trans("flarum-lock.forum.settings.notify_discussion_locked_label")})}))}))})(),module.exports=t})();
//# sourceMappingURL=forum.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,8 +0,0 @@
import 'flarum/common/models/Discussion';
declare module 'flarum/common/models/Discussion' {
export default interface Discussion {
isLocked(): boolean;
canLock(): boolean;
}
}

View File

@@ -1,7 +0,0 @@
import DiscussionLockedNotification from './components/DiscussionLockedNotification';
import DiscussionLockedPost from './components/DiscussionLockedPost';
export default {
'lock/components/DiscussionLockedNotification': DiscussionLockedNotification,
'lock/components/DiscussionLockedPost': DiscussionLockedPost,
};

View File

@@ -22,9 +22,3 @@ app.initializers.add('flarum-lock', () => {
});
});
});
// Expose compat API
import lockCompat from './compat';
import { compat } from '@flarum/core/forum';
Object.assign(compat, lockCompat);

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8"
"flarum/core": "^1.7"
},
"extra": {
"branch-alias": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +0,0 @@
import commonCompat from '../common/compat';
export default {
...commonCompat,
};

View File

@@ -2,9 +2,3 @@ import app from 'flarum/admin/app';
import { initialize } from '../common/index';
app.initializers.add('flarum-markdown', initialize);
// Expose compat API
import markdownCompat from './compat';
import { compat } from '@flarum/core/admin';
Object.assign(compat, markdownCompat);

View File

@@ -1,7 +0,0 @@
import MarkdownButton from './components/MarkdownButton';
import MarkdownToolbar from './components/MarkdownToolbar';
export default {
'markdown/components/MarkdownButton': MarkdownButton,
'markdown/components/MarkdownToolbar': MarkdownToolbar,
};

View File

@@ -1,5 +0,0 @@
import commonCompat from '../common/compat';
export default {
...commonCompat,
};

View File

@@ -2,9 +2,3 @@ import app from 'flarum/forum/app';
import { initialize } from '../common/index';
app.initializers.add('flarum-markdown', initialize);
// Expose compat API
import markdownCompat from './compat';
import { compat } from '@flarum/core/forum';
Object.assign(compat, markdownCompat);

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8"
"flarum/core": "^1.7"
},
"autoload": {
"psr-4": {

View File

@@ -51,7 +51,8 @@ return [
->belongsToMany('mentionedBy', Post::class, 'post_mentions_post', 'mentions_post_id', 'post_id')
->belongsToMany('mentionsPosts', Post::class, 'post_mentions_post', 'post_id', 'mentions_post_id')
->belongsToMany('mentionsUsers', User::class, 'post_mentions_user', 'post_id', 'mentions_user_id')
->belongsToMany('mentionsGroups', Group::class, 'post_mentions_group', 'post_id', 'mentions_group_id'),
->belongsToMany('mentionsGroups', Group::class, 'post_mentions_group', 'post_id', 'mentions_group_id')
->belongsToMany('mentionsUsers', User::class, 'post_mentions_user', 'post_id', 'mentions_user_id'),
new Extend\Locales(__DIR__.'/locale'),
@@ -77,17 +78,15 @@ return [
->addInclude(['posts.mentionedBy', 'posts.mentionedBy.user', 'posts.mentionedBy.discussion'])
->load([
'posts.mentionsUsers', 'posts.mentionsPosts', 'posts.mentionsPosts.user',
'posts.mentionsPosts.discussion', 'posts.mentionsGroups'
'posts.mentionsGroups'
])
->loadWhere('posts.mentionedBy', [LoadMentionedByRelationship::class, 'mutateRelation'])
->prepareDataForSerialization([LoadMentionedByRelationship::class, 'countRelation']),
(new Extend\ApiController(Controller\ListDiscussionsController::class))
->load([
'firstPost.mentionsUsers', 'firstPost.mentionsPosts',
'firstPost.mentionsPosts.user', 'firstPost.mentionsPosts.discussion', 'firstPost.mentionsGroups',
'lastPost.mentionsUsers', 'lastPost.mentionsPosts',
'lastPost.mentionsPosts.user', 'lastPost.mentionsPosts.discussion', 'lastPost.mentionsGroups',
'firstPost.mentionsUsers', 'firstPost.mentionsPosts', 'firstPost.mentionsPosts.user', 'firstPost.mentionsGroups',
'lastPost.mentionsUsers', 'lastPost.mentionsPosts', 'lastPost.mentionsPosts.user', 'lastPost.mentionsGroups',
]),
(new Extend\ApiController(Controller\ShowPostController::class))
@@ -99,7 +98,7 @@ return [
(new Extend\ApiController(Controller\ListPostsController::class))
->addInclude(['mentionedBy', 'mentionedBy.user', 'mentionedBy.discussion'])
->load(['mentionsUsers', 'mentionsPosts', 'mentionsPosts.user', 'mentionsPosts.discussion', 'mentionsGroups'])
->load(['mentionsUsers', 'mentionsPosts', 'mentionsPosts.user', 'mentionsGroups'])
->loadWhere('mentionedBy', [LoadMentionedByRelationship::class, 'mutateRelation'])
->prepareDataForSerialization([LoadMentionedByRelationship::class, 'countRelation']),

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,3 @@
import 'flarum/forum/ForumApplication';
import 'flarum/common/models/User';
import 'flarum/common/models/Post';
import MentionFormats from '../forum/mentionables/formats/MentionFormats';
import type BasePost from 'flarum/common/models/Post';

View File

@@ -5,9 +5,12 @@ import TextEditorButton from 'flarum/common/components/TextEditorButton';
import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable';
import AutocompleteDropdown from './fragments/AutocompleteDropdown';
import MentionFormats from './mentionables/formats/MentionFormats';
import MentionableModels from './mentionables/MentionableModels';
export default function addComposerAutocomplete() {
app.mentionFormats = new MentionFormats();
const $container = $('<div class="ComposerBody-mentionsDropdownContainer"></div>');
const dropdown = new AutocompleteDropdown();

View File

@@ -118,7 +118,7 @@ export default function addMentionedByList() {
});
const limit = 4;
const overLimit = post.mentionedByCount() > limit;
const overLimit = repliers.length > limit;
// Create a list of unique users who have replied. So even if a user has
// replied twice, they will only be in this array once.
@@ -136,7 +136,7 @@ export default function addMentionedByList() {
// others" name to the end of the list. Clicking on it will display a modal
// with a full list of names.
if (overLimit) {
const count = post.mentionedByCount() - names.length;
const count = repliers.length - names.length;
names.push(app.translator.trans('flarum-mentions.forum.post.others_text', { count }));
}

View File

@@ -1,6 +1,4 @@
import GroupMentionedNotification from './components/GroupMentionedNotification';
import MentionedByModal from './components/MentionedByModal';
import MentionsDropdownItem from './components/MentionsDropdownItem';
import MentionsUserPage from './components/MentionsUserPage';
import PostMentionedNotification from './components/PostMentionedNotification';
import UserMentionedNotification from './components/UserMentionedNotification';
@@ -11,24 +9,13 @@ import getMentionText from './utils/getMentionText';
import * as reply from './utils/reply';
import selectedText from './utils/selectedText';
import * as textFormatter from './utils/textFormatter';
import GroupMention from './mentionables/GroupMention';
import MentionableModel from './mentionables/MentionableModel';
import MentionableModels from './mentionables/MentionableModels';
import PostMention from './mentionables/PostMention';
import TagMention from './mentionables/TagMention';
import UserMention from './mentionables/UserMention';
import AtMentionFormat from './mentionables/formats/AtMentionFormat';
import HashMentionFormat from './mentionables/formats/HashMentionFormat';
import MentionFormat from './mentionables/formats/MentionFormat';
import MentionFormats from './mentionables/formats/MentionFormats';
import Mentionables from './extenders/Mentionables';
import MentionedByModalState from './state/MentionedByModalState';
export default {
'mentions/components/MentionsUserPage': MentionsUserPage,
'mentions/components/PostMentionedNotification': PostMentionedNotification,
'mentions/components/MentionedByModal': MentionedByModal,
'mentions/components/MentionsDropdownItem': MentionsDropdownItem,
'mentions/components/UserMentionedNotification': UserMentionedNotification,
'mentions/components/GroupMentionedNotification': GroupMentionedNotification,
'mentions/fragments/AutocompleteDropdown': AutocompleteDropdown,
@@ -38,16 +25,7 @@ export default {
'mentions/utils/reply': reply,
'mentions/utils/selectedText': selectedText,
'mentions/utils/textFormatter': textFormatter,
'mentions/mentionables/GroupMention': GroupMention,
'mentions/mentionables/MentionableModel': MentionableModel,
'mentions/mentionables/MentionableModels': MentionableModels,
'mentions/mentionables/PostMention': PostMention,
'mentions/mentionables/TagMention': TagMention,
'mentions/mentionables/UserMention': UserMention,
'mentions/mentionables/formats/AtMentionFormat': AtMentionFormat,
'mentions/mentionables/formats/HashMentionFormat': HashMentionFormat,
'mentions/mentionables/formats/MentionFormat': MentionFormat,
'mentions/mentionables/formats/MentionFormats': MentionFormats,
'mentions/extenders/Mentionables': Mentionables,
'mentions/state/MentionedByModalState': MentionedByModalState,
};

View File

@@ -5,7 +5,7 @@ import type MentionFormat from '../mentionables/formats/MentionFormat';
export default class Mentionables implements IExtender<ForumApplication> {
protected formats: (new () => MentionFormat)[] = [];
protected mentionables: Record<string, (new (...args: any[]) => MentionableModel)[]> = {};
protected mentionables: Record<string, (new () => MentionableModel)[]> = {};
/**
* Register a new mention format.
@@ -26,7 +26,7 @@ export default class Mentionables implements IExtender<ForumApplication> {
* @param mentionable The mentionable instance to register.
* Must extend MentionableModel.
*/
mentionable(symbol: string, mentionable: new (...args: any[]) => MentionableModel): this {
mentionable(symbol: string, mentionable: new () => MentionableModel): this {
if (!this.mentionables[symbol]) {
this.mentionables[symbol] = [];
}

View File

@@ -13,14 +13,11 @@ import addComposerAutocomplete from './addComposerAutocomplete';
import PostMentionedNotification from './components/PostMentionedNotification';
import UserMentionedNotification from './components/UserMentionedNotification';
import GroupMentionedNotification from './components/GroupMentionedNotification';
import MentionFormats from './mentionables/formats/MentionFormats';
import UserPage from 'flarum/forum/components/UserPage';
import LinkButton from 'flarum/common/components/LinkButton';
import User from 'flarum/common/models/User';
import Model from 'flarum/common/Model';
app.mentionFormats = new MentionFormats();
export { default as extend } from './extend';
app.initializers.add('flarum-mentions', function () {

View File

@@ -4,7 +4,7 @@ import TagMention from '../TagMention';
export default class HashMentionFormat extends MentionFormat {
public mentionables: (new (...args: any[]) => MentionableModel)[] = [TagMention];
protected extendable: boolean = true;
protected extendable: boolean = false;
public trigger(): string {
return '#';

View File

@@ -29,7 +29,7 @@ class LoadMentionedByRelationship
$actor = RequestUtil::getActor($request);
return $query
->with(['mentionsPosts', 'mentionsPosts.user', 'mentionsPosts.discussion', 'mentionsUsers'])
->with(['mentionsPosts', 'mentionsPosts.user', 'mentionsUsers'])
->whereVisibleTo($actor)
->oldest()
// Limiting a relationship results is only possible because
@@ -47,19 +47,10 @@ class LoadMentionedByRelationship
$loadable = null;
if ($data instanceof Discussion) {
$loadable = $data->newCollection($data->posts)->filter(function ($post) {
// @phpstan-ignore-next-line
$loadable = $data->newCollection((array) $data->posts)->filter(function ($post) {
return $post instanceof Post;
});
// firstPost and lastPost might have been included in the API response,
// so we have to make sure counts are also loaded for them.
if ($data->firstPost) {
$loadable->push($data->firstPost);
}
if ($data->lastPost) {
$loadable->push($data->lastPost);
}
} elseif ($data instanceof Collection) {
$loadable = $data;
} elseif ($data instanceof Post) {

View File

View File

@@ -9,9 +9,6 @@
namespace Flarum\Mentions\Formatter;
use Flarum\Discussion\Discussion;
use Flarum\Http\SlugManager;
use Flarum\Post\Post;
use Psr\Http\Message\ServerRequestInterface as Request;
use s9e\TextFormatter\Renderer;
use s9e\TextFormatter\Utils;
@@ -24,15 +21,9 @@ class FormatPostMentions
*/
private $translator;
/**
* @var SlugManager
*/
private $slugManager;
public function __construct(TranslatorInterface $translator, SlugManager $slugManager)
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
$this->slugManager = $slugManager;
}
/**
@@ -40,17 +31,16 @@ class FormatPostMentions
*
* @param \s9e\TextFormatter\Renderer $renderer
* @param mixed $context
* @param string $xml
* @param \Psr\Http\Message\ServerRequestInterface|null $request
* @return string $xml to be rendered
* @param string|null $xml
* @param \Psr\Http\Message\ServerRequestInterface $request
* @return string
*/
public function __invoke(Renderer $renderer, $context, $xml, Request $request = null)
{
return Utils::replaceAttributes($xml, 'POSTMENTION', function ($attributes) use ($context) {
$post = (($context && isset($context->getRelations()['mentionsPosts'])) || $context instanceof Post)
? $context->mentionsPosts->find($attributes['id'])
: Post::find($attributes['id']);
$post = $context;
return Utils::replaceAttributes($xml, 'POSTMENTION', function ($attributes) use ($post) {
$post = $post->mentionsPosts->find($attributes['id']);
if ($post && $post->user) {
$attributes['displayname'] = $post->user->display_name;
}
@@ -66,12 +56,6 @@ class FormatPostMentions
$attributes['displayname'] = $this->translator->trans('core.lib.username.deleted_text');
}
if ($post) {
$attributes['discussionid'] = $this->slugManager
->forResource(Discussion::class)
->toSlug($post->discussion);
}
return $attributes;
});
}

View File

@@ -9,7 +9,6 @@
namespace Flarum\Mentions\Formatter;
use Flarum\Post\Post;
use s9e\TextFormatter\Utils;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -28,16 +27,12 @@ class UnparsePostMentions
/**
* Configure rendering for user mentions.
*
* @param string|null $xml
* @param string $xml
* @param mixed $context
* @return mixed $xml to be unparsed
* @return string $xml to be unparsed
*/
public function __invoke($context, $xml)
public function __invoke($context, string $xml)
{
if ($xml === null) {
return $xml;
}
$xml = $this->updatePostMentionTags($context, $xml);
$xml = $this->unparsePostMentionTags($xml);
@@ -55,11 +50,8 @@ class UnparsePostMentions
{
$post = $context;
return Utils::replaceAttributes($xml, 'POSTMENTION', function ($attributes) use ($context) {
$post = (($context && isset($context->getRelations()['mentionsPosts'])) || $context instanceof Post)
? $context->mentionsPosts->find($attributes['id'])
: Post::find($attributes['id']);
return Utils::replaceAttributes($xml, 'POSTMENTION', function ($attributes) use ($post) {
$post = $post->mentionsPosts->find($attributes['id']);
if ($post && $post->user) {
$attributes['displayname'] = $post->user->display_name;
}

View File

@@ -18,16 +18,12 @@ class UnparseTagMentions
/**
* Configure rendering for user mentions.
*
* @param string|null $xml
* @param string $xml
* @param mixed $context
* @return mixed $xml to be unparsed
* @return string $xml to be unparsed
*/
public function __invoke($context, $xml)
public function __invoke($context, string $xml)
{
if ($xml === null) {
return $xml;
}
$xml = $this->updateTagMentionTags($context, $xml);
$xml = $this->unparseTagMentionTags($xml);

View File

@@ -29,16 +29,12 @@ class UnparseUserMentions
/**
* Configure rendering for user mentions.
*
* @param string|null $xml
* @param string $xml
* @param mixed $context
* @return mixed $xml to be unparsed
* @return string $xml to be unparsed
*/
public function __invoke($context, $xml)
public function __invoke($context, string $xml)
{
if ($xml === null) {
return $xml;
}
$xml = $this->updateUserMentionTags($context, $xml);
$xml = $this->unparseUserMentionTags($xml);

View File

@@ -47,8 +47,6 @@ class SendMentionsNotificationsJob extends AbstractJob
public function __construct(CommentPost $post, array $userMentions, array $postMentions, array $groupMentions)
{
parent::__construct();
$this->post = $post;
$this->userMentions = $userMentions;
$this->postMentions = $postMentions;

View File

@@ -1,137 +0,0 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Mentions\Tests\integration\api;
use Flarum\Extend;
use Flarum\Testing\integration\TestCase;
class CreateDiscussionTest extends TestCase
{
/**
* @inheritDoc
*/
protected function setUp(): void
{
parent::setUp();
$this->extension('flarum-mentions');
$this->extend(
(new Extend\Event())
->listen(\Flarum\Post\Event\Saving::class, function ($event) {
$event->post->content;
})
);
}
/**
* @test
*/
public function cannot_create_discussion_with_empty_string()
{
$response = $this->send(
$this->request('POST', '/api/discussions', [
'authenticatedAs' => 1,
'json' => [
'data' => [
'attributes' => [
'title' => 'Test post',
'content' => '',
],
],
],
])
);
$this->assertEquals(422, $response->getStatusCode());
$body = (string) $response->getBody();
$this->assertJson($body);
$this->assertEquals([
'errors' => [
[
'status' => '422',
'code' => 'validation_error',
'detail' => 'The content field is required.',
'source' => ['pointer' => '/data/attributes/content'],
],
],
], json_decode($body, true));
}
/**
* @test
*/
public function cannot_create_discussion_without_content_property()
{
$response = $this->send(
$this->request('POST', '/api/discussions', [
'authenticatedAs' => 1,
'json' => [
'data' => [
'attributes' => [
'title' => 'Test post',
],
],
],
])
);
$this->assertEquals(422, $response->getStatusCode());
$body = (string) $response->getBody();
$this->assertJson($body);
$this->assertEquals([
'errors' => [
[
'status' => '422',
'code' => 'validation_error',
'detail' => 'The content field is required.',
'source' => ['pointer' => '/data/attributes/content'],
],
],
], json_decode($body, true));
}
/**
* @test
*/
public function cannot_create_discussion_with_content_set_to_null()
{
$response = $this->send(
$this->request('POST', '/api/discussions', [
'authenticatedAs' => 1,
'json' => [
'data' => [
'attributes' => [
'title' => 'Test post',
'content' => null,
],
],
],
])
);
$this->assertEquals(422, $response->getStatusCode());
$body = (string) $response->getBody();
$this->assertJson($body);
$this->assertEquals([
'errors' => [
[
'status' => '422',
'code' => 'validation_error',
'detail' => 'The content field is required.',
'source' => ['pointer' => '/data/attributes/content'],
],
],
], json_decode($body, true));
}
}

View File

@@ -1,110 +0,0 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Mentions\Tests\integration\api;
use Flarum\Extend;
use Flarum\Testing\integration\TestCase;
class EditPostTest extends TestCase
{
/**
* @inheritDoc
*/
protected function setUp(): void
{
parent::setUp();
$this->extension('flarum-mentions');
$this->prepareDatabase([
'discussions' => [
['id' => 1, 'title' => 'Discussion with post', 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1],
],
'posts' => [
['id' => 1, 'discussion_id' => 1, 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>Text</p></t>'],
]
]);
$this->extend(
(new Extend\Event())
->listen(\Flarum\Post\Event\Saving::class, function ($event) {
$event->post->content;
})
);
}
/**
* @test
*/
public function cannot_update_post_with_empty_string()
{
$response = $this->send(
$this->request('PATCH', '/api/posts/1', [
'authenticatedAs' => 1,
'json' => [
'data' => [
'attributes' => [
'content' => '',
],
],
],
])
);
$this->assertEquals(422, $response->getStatusCode());
$body = (string) $response->getBody();
$this->assertJson($body);
$this->assertEquals([
'errors' => [
[
'status' => '422',
'code' => 'validation_error',
'detail' => 'The content field is required.',
'source' => ['pointer' => '/data/attributes/content'],
],
],
], json_decode($body, true));
}
/**
* @test
*/
public function cannot_update_post_with_invalid_content_type()
{
$response = $this->send(
$this->request('PATCH', '/api/posts/1', [
'authenticatedAs' => 1,
'json' => [
'data' => [
'attributes' => [
'content' => [],
],
],
],
])
);
$this->assertEquals(422, $response->getStatusCode());
$body = (string) $response->getBody();
$this->assertJson($body);
$this->assertEquals([
'errors' => [
[
'status' => '422',
'code' => 'validation_error',
'detail' => 'The content field is required.',
'source' => ['pointer' => '/data/attributes/content'],
],
],
], json_decode($body, true));
}
}

View File

@@ -11,9 +11,7 @@ namespace Flarum\Mentions\Tests\integration\api;
use Carbon\Carbon;
use Flarum\Extend;
use Flarum\Formatter\Formatter;
use Flarum\Post\CommentPost;
use Flarum\Post\Post;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\DisplayName\DriverInterface;
@@ -540,40 +538,6 @@ class PostMentionsTest extends TestCase
$this->assertStringContainsString('PostMention', $response['data']['attributes']['contentHtml']);
$this->assertNotNull(CommentPost::find($response['data']['id'])->mentionsPosts->find(11));
}
/**
* @test
*/
public function rendering_post_mention_with_a_post_context_works()
{
/** @var Formatter $formatter */
$formatter = $this->app()->getContainer()->make(Formatter::class);
$post = Post::find(4);
$user = User::find(1);
$xml = $formatter->parse($post->content, $post, $user);
$renderedHtml = $formatter->render($xml, $post);
$this->assertStringContainsString('TOBY$', $renderedHtml);
}
/**
* @test
*/
public function rendering_post_mention_without_a_context_works()
{
/** @var Formatter $formatter */
$formatter = $this->app()->getContainer()->make(Formatter::class);
$post = Post::find(4);
$user = User::find(1);
$xml = $formatter->parse($post->content, null, $user);
$renderedHtml = $formatter->render($xml);
$this->assertStringContainsString('TOBY$', $renderedHtml);
}
}
class CustomOtherDisplayNameDriver implements DriverInterface

View File

@@ -19,7 +19,7 @@
}
],
"require": {
"flarum/core": "^1.8"
"flarum/core": "^1.7"
},
"autoload": {
"psr-4": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +0,0 @@
import 'flarum/common/models/User';
declare module 'flarum/common/models/User' {
export default interface User {
canEditNickname(): boolean;
}
}

View File

@@ -1,5 +0,0 @@
import NicknameModal from './components/NicknameModal';
export default {
'nicknames/components/NicknameModal': NicknameModal,
};

View File

@@ -110,9 +110,3 @@ app.initializers.add('flarum/nicknames', () => {
}
});
});
// Expose compat API
import nicknamesCompat from './compat';
import { compat } from '@flarum/core/forum';
Object.assign(compat, nicknamesCompat);

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2024 Stichting Flarum (Flarum Foundation)
Copyright (c) Sami Mazouz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,18 +1,5 @@
# Extension Manager
# Package Manager
The extension manager is a tool that allows you to easily install and manage extensions. It runs [composer](https://getcomposer.org/) under the hood.
*An Experiment.*
## Security
If admin access is given to untrustworthy users, they can install malicious extensions. Please be careful.
This extension is optional and can be removed for those who prefer to manually manage installs and updates through the command line interface.
## Troubleshooting
If you have many extensions installed, you may run into memory issues when using the extension manager. If this happens, you can use an asynchronous queue that will run the extension manager in the background.
* Simple database queue guide: https://discuss.flarum.org/d/28151-database-queue-the-simplest-queue-even-for-shared-hosting
* (Advanced) Redis queue: https://discuss.flarum.org/d/21873-redis-sessions-cache-queues
You can find detailed logs on the extension manager operations in the `storage/logs/composer` directory. Please include the latest log file when reporting issues in the [Flarum support forum](https://discuss.flarum.org/t/support).
Read: https://github.com/flarum/package-manager/wiki

View File

@@ -1,6 +1,6 @@
{
"name": "flarum/extension-manager",
"description": "An extension manager to install, update and remove extension packages from the interface (Wrapper around composer).",
"name": "flarum/package-manager",
"description": "A Flarum Package Manager.",
"keywords": [
"extensions",
"composer",
@@ -18,12 +18,12 @@
}
],
"support": {
"issues": "https://github.com/flarum/framework/issues",
"source": "https://github.com/flarum/extension-manager"
"issues": "https://github.com/flarum/package-manager/issues",
"source": "https://github.com/flarum/package-manager"
},
"require": {
"flarum/core": "^1.8",
"composer/composer": "^2.7"
"flarum/core": "^1.5.0",
"composer/composer": "^2.3"
},
"require-dev": {
"flarum/testing": "^1.0.0",
@@ -31,7 +31,7 @@
},
"extra": {
"flarum-extension": {
"title": "Extension Manager",
"title": "Package Manager",
"icon": {
"name": "fas fa-box-open",
"backgroundColor": "#117187",
@@ -69,12 +69,12 @@
},
"autoload": {
"psr-4": {
"Flarum\\ExtensionManager\\": "src/"
"Flarum\\PackageManager\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Flarum\\ExtensionManager\\Tests\\": "tests/"
"Flarum\\PackageManager\\Tests\\": "tests/"
}
},
"scripts": {

View File

@@ -7,26 +7,32 @@
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\ExtensionManager;
namespace Flarum\PackageManager;
use Flarum\Extend;
use Flarum\Foundation\Paths;
use Flarum\Frontend\Document;
use Flarum\PackageManager\Exception\ComposerCommandFailedException;
use Flarum\PackageManager\Exception\ComposerRequireFailedException;
use Flarum\PackageManager\Exception\ComposerUpdateFailedException;
use Flarum\PackageManager\Exception\ExceptionHandler;
use Flarum\PackageManager\Exception\MajorUpdateFailedException;
use Flarum\PackageManager\Settings\LastUpdateCheck;
use Flarum\PackageManager\Settings\LastUpdateRun;
use Illuminate\Contracts\Queue\Queue;
use Illuminate\Queue\SyncQueue;
return [
(new Extend\Routes('api'))
->post('/extension-manager/extensions', 'extension-manager.extensions.require', Api\Controller\RequireExtensionController::class)
->patch('/extension-manager/extensions/{id}', 'extension-manager.extensions.update', Api\Controller\UpdateExtensionController::class)
->delete('/extension-manager/extensions/{id}', 'extension-manager.extensions.remove', Api\Controller\RemoveExtensionController::class)
->post('/extension-manager/check-for-updates', 'extension-manager.check-for-updates', Api\Controller\CheckForUpdatesController::class)
->post('/extension-manager/why-not', 'extension-manager.why-not', Api\Controller\WhyNotController::class)
->post('/extension-manager/minor-update', 'extension-manager.minor-update', Api\Controller\MinorUpdateController::class)
->post('/extension-manager/major-update', 'extension-manager.major-update', Api\Controller\MajorUpdateController::class)
->post('/extension-manager/global-update', 'extension-manager.global-update', Api\Controller\GlobalUpdateController::class)
->get('/extension-manager-tasks', 'extension-manager.tasks.index', Api\Controller\ListTasksController::class)
->post('/extension-manager/composer', 'extension-manager.composer', Api\Controller\ConfigureComposerController::class),
->post('/package-manager/extensions', 'package-manager.extensions.require', Api\Controller\RequireExtensionController::class)
->patch('/package-manager/extensions/{id}', 'package-manager.extensions.update', Api\Controller\UpdateExtensionController::class)
->delete('/package-manager/extensions/{id}', 'package-manager.extensions.remove', Api\Controller\RemoveExtensionController::class)
->post('/package-manager/check-for-updates', 'package-manager.check-for-updates', Api\Controller\CheckForUpdatesController::class)
->post('/package-manager/why-not', 'package-manager.why-not', Api\Controller\WhyNotController::class)
->post('/package-manager/minor-update', 'package-manager.minor-update', Api\Controller\MinorUpdateController::class)
->post('/package-manager/major-update', 'package-manager.major-update', Api\Controller\MajorUpdateController::class)
->post('/package-manager/global-update', 'package-manager.global-update', Api\Controller\GlobalUpdateController::class)
->get('/package-manager-tasks', 'package-manager.tasks.index', Api\Controller\ListTasksController::class),
(new Extend\Frontend('admin'))
->css(__DIR__.'/less/admin.less')
@@ -34,34 +40,31 @@ return [
->content(function (Document $document) {
$paths = resolve(Paths::class);
$document->payload['flarum-extension-manager.writable_dirs'] = is_writable($paths->vendor)
$document->payload['flarum-package-manager.writable_dirs'] = is_writable($paths->vendor)
&& is_writable($paths->storage)
&& (! file_exists($paths->storage.'/.composer') || is_writable($paths->storage.'/.composer'))
&& is_writable($paths->base.'/composer.json')
&& is_writable($paths->base.'/composer.lock');
$document->payload['flarum-extension-manager.using_sync_queue'] = resolve(Queue::class) instanceof SyncQueue;
$document->payload['flarum-package-manager.using_sync_queue'] = resolve(Queue::class) instanceof SyncQueue;
}),
new Extend\Locales(__DIR__.'/locale'),
(new Extend\Settings())
->default(Settings\LastUpdateCheck::key(), json_encode(Settings\LastUpdateCheck::default()))
->default(Settings\LastUpdateRun::key(), json_encode(Settings\LastUpdateRun::default()))
->default('flarum-extension-manager.queue_jobs', '0')
->default('flarum-extension-manager.minimum_stability', 'stable')
->default('flarum-extension-manager.task_retention_days', 7),
->default(LastUpdateCheck::key(), json_encode(LastUpdateCheck::default()))
->default(LastUpdateRun::key(), json_encode(LastUpdateRun::default()))
->default('flarum-package-manager.queue_jobs', false),
(new Extend\ServiceProvider)
->register(ExtensionManagerServiceProvider::class),
->register(PackageManagerServiceProvider::class),
(new Extend\ErrorHandling)
->handler(Exception\ComposerCommandFailedException::class, Exception\ExceptionHandler::class)
->handler(Exception\ComposerRequireFailedException::class, Exception\ExceptionHandler::class)
->handler(Exception\ComposerUpdateFailedException::class, Exception\ExceptionHandler::class)
->handler(Exception\MajorUpdateFailedException::class, Exception\ExceptionHandler::class)
->handler(ComposerCommandFailedException::class, ExceptionHandler::class)
->handler(ComposerRequireFailedException::class, ExceptionHandler::class)
->handler(ComposerUpdateFailedException::class, ExceptionHandler::class)
->handler(MajorUpdateFailedException::class, ExceptionHandler::class)
->status('extension_already_installed', 409)
->status('extension_not_installed', 409)
->status('no_new_major_version', 409)
->status('extension_not_directly_dependency', 409),
->status('no_new_major_version', 409),
];

View File

@@ -1,49 +0,0 @@
import AuthMethodModal from './components/AuthMethodModal';
import ConfigureAuth from './components/ConfigureAuth';
import ConfigureComposer from './components/ConfigureComposer';
import ConfigureJson from './components/ConfigureJson';
import ControlSection from './components/ControlSection';
import ExtensionItem from './components/ExtensionItem';
import Installer from './components/Installer';
import Label from './components/Label';
import MajorUpdater from './components/MajorUpdater';
import Pagination from './components/Pagination';
import QueueSection from './components/QueueSection';
import RepositoryModal from './components/RepositoryModal';
import SettingsPage from './components/SettingsPage';
import TaskOutputModal from './components/TaskOutputModal';
import Updater from './components/Updater';
import WhyNotModal from './components/WhyNotModal';
import Task from './models/Task';
import ControlSectionState from './states/ControlSectionState';
import ExtensionManagerState from './states/ExtensionManagerState';
import QueueState from './states/QueueState';
import errorHandler from './utils/errorHandler';
import humanDuration from './utils/humanDuration';
import jumpToQueue from './utils/jumpToQueue';
declare const _default: {
'extension-manager/components/AuthMethodModal': typeof AuthMethodModal;
'extension-manager/components/ConfigureAuth': typeof ConfigureAuth;
'extension-manager/components/ConfigureComposer': typeof ConfigureComposer;
'extension-manager/components/ConfigureJson': typeof ConfigureJson;
'extension-manager/components/ControlSection': typeof ControlSection;
'extension-manager/components/ExtensionItem': typeof ExtensionItem;
'extension-manager/components/Installer': typeof Installer;
'extension-manager/components/Label': typeof Label;
'extension-manager/components/MajorUpdater': typeof MajorUpdater;
'extension-manager/components/Pagination': typeof Pagination;
'extension-manager/components/QueueSection': typeof QueueSection;
'extension-manager/components/RepositoryModal': typeof RepositoryModal;
'extension-manager/components/SettingsPage': typeof SettingsPage;
'extension-manager/components/TaskOutputModal': typeof TaskOutputModal;
'extension-manager/components/Updater': typeof Updater;
'extension-manager/components/WhyNotModal': typeof WhyNotModal;
'extension-manager/models/Task': typeof Task;
'extension-manager/states/ControlSectionState': typeof ControlSectionState;
'extension-manager/states/ExtensionManagerState': typeof ExtensionManagerState;
'extension-manager/states/QueueState': typeof QueueState;
'extension-manager/utils/errorHandler': typeof errorHandler;
'extension-manager/utils/humanDuration': typeof humanDuration;
'extension-manager/utils/jumpToQueue': typeof jumpToQueue;
};
export default _default;

View File

@@ -1,19 +0,0 @@
import Modal, { IInternalModalAttrs } from 'flarum/common/components/Modal';
import Mithril from 'mithril';
import Stream from 'flarum/common/utils/Stream';
export interface IAuthMethodModalAttrs extends IInternalModalAttrs {
onsubmit: (type: string, host: string, token: string) => void;
type?: string;
host?: string;
token?: string;
}
export default class AuthMethodModal<CustomAttrs extends IAuthMethodModalAttrs = IAuthMethodModalAttrs> extends Modal<CustomAttrs> {
protected type: Stream<string>;
protected host: Stream<string>;
protected token: Stream<string>;
oninit(vnode: Mithril.Vnode<CustomAttrs, this>): void;
className(): string;
title(): Mithril.Children;
content(): Mithril.Children;
submit(): void;
}

View File

@@ -1,10 +0,0 @@
import type Mithril from 'mithril';
import ConfigureJson, { IConfigureJson } from './ConfigureJson';
export default class ConfigureAuth extends ConfigureJson<IConfigureJson> {
protected type: string;
title(): Mithril.Children;
className(): string;
content(): Mithril.Children;
submitButton(): Mithril.Children[];
onchange(oldHost: string | null, type: string, host: string, token: string): void;
}

View File

@@ -1,14 +0,0 @@
import type Mithril from 'mithril';
import ConfigureJson, { type IConfigureJson } from './ConfigureJson';
export declare type Repository = {
type: 'composer' | 'vcs' | 'path';
url: string;
};
export default class ConfigureComposer extends ConfigureJson<IConfigureJson> {
protected type: string;
title(): Mithril.Children;
className(): string;
content(): Mithril.Children;
submitButton(): Mithril.Children[];
onchange(repository: Repository, name: string): void;
}

View File

@@ -1,24 +0,0 @@
import type Mithril from 'mithril';
import Component, { type ComponentAttrs } from 'flarum/common/Component';
import { CommonSettingsItemOptions, type SettingsComponentOptions } from '@flarum/core/src/admin/components/AdminPage';
import type ItemList from 'flarum/common/utils/ItemList';
import Stream from 'flarum/common/utils/Stream';
export interface IConfigureJson extends ComponentAttrs {
buildSettingComponent: (entry: ((this: this) => Mithril.Children) | SettingsComponentOptions) => Mithril.Children;
}
export default abstract class ConfigureJson<CustomAttrs extends IConfigureJson = IConfigureJson> extends Component<CustomAttrs> {
protected settings: Record<string, Stream<any>>;
protected initialSettings: Record<string, any> | null;
protected loading: boolean;
oninit(vnode: Mithril.Vnode<CustomAttrs, this>): void;
protected abstract type: string;
abstract title(): Mithril.Children;
abstract content(): Mithril.Children;
className(): string;
view(): Mithril.Children;
submitButton(): Mithril.Children[];
customSettingComponents(): ItemList<(attributes: CommonSettingsItemOptions) => Mithril.Children>;
setting(key: string): Stream<any>;
submit(readOnly: boolean): void;
isDirty(): boolean;
}

View File

@@ -5,10 +5,7 @@ import { UpdatedPackage } from '../states/ControlSectionState';
export interface ExtensionItemAttrs extends ComponentAttrs {
extension: Extension;
updates: UpdatedPackage;
onClickUpdate: CallableFunction | {
soft: CallableFunction;
hard: CallableFunction;
};
onClickUpdate: CallableFunction;
whyNotWarning?: boolean;
isCore?: boolean;
updatable?: boolean;

View File

@@ -1,18 +0,0 @@
import Modal, { IInternalModalAttrs } from 'flarum/common/components/Modal';
import Mithril from 'mithril';
import Stream from 'flarum/common/utils/Stream';
import { type Repository } from './ConfigureComposer';
export interface IRepositoryModalAttrs extends IInternalModalAttrs {
onsubmit: (repository: Repository, key: string) => void;
name?: string;
repository?: Repository;
}
export default class RepositoryModal<CustomAttrs extends IRepositoryModalAttrs = IRepositoryModalAttrs> extends Modal<CustomAttrs> {
protected name: Stream<string>;
protected repository: Stream<Repository>;
oninit(vnode: Mithril.Vnode<CustomAttrs, this>): void;
className(): string;
title(): Mithril.Children;
content(): Mithril.Children;
submit(): void;
}

View File

@@ -2,7 +2,5 @@ import type Mithril from 'mithril';
import ExtensionPage, { ExtensionPageAttrs } from 'flarum/admin/components/ExtensionPage';
import ItemList from 'flarum/common/utils/ItemList';
export default class SettingsPage extends ExtensionPage {
content(): JSX.Element;
sections(vnode: Mithril.VnodeDOM<ExtensionPageAttrs, this>): ItemList<unknown>;
onsaved(): void;
}

View File

@@ -1,5 +1,5 @@
/// <reference types="mithril" />
/// <reference types="@flarum/core/dist-typings/@types/translator-icu-rich" />
/// <reference types="flarum/@types/translator-icu-rich" />
import Modal, { IInternalModalAttrs } from 'flarum/common/components/Modal';
import Task from '../models/Task';
interface TaskOutputModalAttrs extends IInternalModalAttrs {

View File

@@ -1,4 +1,4 @@
/// <reference types="@flarum/core/dist-typings/@types/translator-icu-rich" />
/// <reference types="flarum/@types/translator-icu-rich" />
import type Mithril from 'mithril';
import Modal, { IInternalModalAttrs } from 'flarum/common/components/Modal';
export interface WhyNotModalAttrs extends IInternalModalAttrs {

View File

@@ -1,12 +1,11 @@
import Model from 'flarum/common/Model';
export declare type TaskOperations = 'extension_install' | 'extension_remove' | 'extension_update' | 'update_global' | 'update_minor' | 'update_major' | 'update_check' | 'why_not';
export default class Task extends Model {
status(): "pending" | "running" | "failure" | "success";
status(): "running" | "pending" | "success" | "failure";
operation(): TaskOperations;
command(): string;
package(): string;
output(): string;
guessedCause(): string;
createdAt(): Date | null | undefined;
startedAt(): Date;
finishedAt(): Date;

View File

@@ -9,8 +9,6 @@ export declare type UpdatedPackage = {
'latest-minor': string | null;
'latest-major': string | null;
'latest-status': string;
'required-as': string;
'direct-dependency': boolean;
description: string;
};
export declare type ComposerUpdates = {
@@ -33,7 +31,7 @@ export declare type LastUpdateRun = {
} & {
limitedPackages: () => string[];
};
export declare type LoadingTypes = UpdaterLoadingTypes | InstallerLoadingTypes | MajorUpdaterLoadingTypes | 'queued-action';
export declare type LoadingTypes = UpdaterLoadingTypes | InstallerLoadingTypes | MajorUpdaterLoadingTypes;
export declare type CoreUpdate = {
package: UpdatedPackage;
extension: Extension;
@@ -47,17 +45,13 @@ export default class ControlSectionState {
get lastUpdateRun(): LastUpdateRun;
constructor();
isLoading(name?: LoadingTypes): boolean;
hasOperationRunning(): boolean;
isLoadingOtherThan(name: LoadingTypes): boolean;
setLoading(name: LoadingTypes): void;
requirePackage(data: any): void;
checkForUpdates(): void;
updateCoreMinor(): void;
updateExtension(extension: Extension, updateMode: 'soft' | 'hard'): void;
updateExtension(extension: Extension): void;
updateGlobally(): void;
formatExtensionUpdates(lastUpdateCheck: LastUpdateCheck): Extension[];
formatCoreUpdate(lastUpdateCheck: LastUpdateCheck): CoreUpdate | null;
majorUpdate({ dryRun }: {
dryRun: boolean;
}): void;
}
export {};

View File

@@ -1,6 +1,6 @@
import QueueState from './QueueState';
import ControlSectionState from './ControlSectionState';
export default class ExtensionManagerState {
export default class PackageManagerState {
queue: QueueState;
control: ControlSectionState;
}

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