diff --git a/app/Libraries/BBCodeFromDB.php b/app/Libraries/BBCodeFromDB.php index 1abe791a85c..d043398c180 100644 --- a/app/Libraries/BBCodeFromDB.php +++ b/app/Libraries/BBCodeFromDB.php @@ -75,7 +75,7 @@ public function parseBoxHelperPrefix($linkText = null) { $linkText = presence($linkText) ?? 'SPOILER'; - return "
"; + return "
{$linkText}
"; } public function parseBoxHelperSuffix() diff --git a/app/Libraries/CleanHTML.php b/app/Libraries/CleanHTML.php index c7a5b2cd4e9..0a7ead84c8c 100644 --- a/app/Libraries/CleanHTML.php +++ b/app/Libraries/CleanHTML.php @@ -47,14 +47,6 @@ public function __construct() ] ); - $def->addElement( - 'button', - 'Formctrl', - 'Optional: #PCDATA | Heading | List | Block | Inline', - 'Common', - ['type' => 'Enum#button'], - ); - $def->addAttribute('audio', 'preload', 'Text'); $def->addAttribute('img', 'loading', 'Text'); diff --git a/app/Libraries/Search/ScoreSearch.php b/app/Libraries/Search/ScoreSearch.php index 1d1c138395b..79b3da52651 100644 --- a/app/Libraries/Search/ScoreSearch.php +++ b/app/Libraries/Search/ScoreSearch.php @@ -119,11 +119,13 @@ public function queueForIndex(?array $schemas, array $ids): void $schemas ??= $this->getActiveSchemas(); + $values = array_map( + static fn (int $id): string => json_encode(['ScoreId' => $id]), + $ids, + ); + foreach ($schemas as $schema) { - LaravelRedis::lpush("osu-queue:score-index-{$schema}", ...array_map( - fn (int $id): string => json_encode(['ScoreId' => $id]), - $ids, - )); + LaravelRedis::lpush("osu-queue:score-index-{$schema}", ...$values); } } diff --git a/app/Models/Solo/Score.php b/app/Models/Solo/Score.php index 24d865f027d..4bd02dc6857 100644 --- a/app/Models/Solo/Score.php +++ b/app/Models/Solo/Score.php @@ -24,12 +24,14 @@ /** * @property int $beatmap_id * @property \Carbon\Carbon|null $created_at - * @property \stdClass $data - * @property \Carbon\Carbon|null $deleted_at + * @property string|null $created_at_json + * @property ScoreData $data + * @property bool $has_replay * @property int $id * @property bool $preserve + * @property bool $ranked * @property int $ruleset_id - * @property \Carbon\Carbon|null $updated_at + * @property int $unix_updated_at * @property User $user * @property int $user_id */ @@ -39,6 +41,8 @@ class Score extends Model implements Traits\ReportableInterface const PROCESSING_QUEUE = 'osu-queue:score-statistics'; + public $timestamps = false; + protected $casts = [ 'data' => ScoreData::class, 'has_replay' => 'boolean', @@ -160,18 +164,17 @@ public function getAttribute($key) 'beatmap_id', 'id', 'ruleset_id', + 'unix_updated_at', 'user_id' => $this->getRawAttribute($key), 'data' => $this->getClassCastableAttributeValue($key, $this->getRawAttribute($key)), 'has_replay', - 'preserve' => (bool) $this->getRawAttribute($key), - - 'created_at', - 'updated_at' => $this->getTimeFast($key), + 'preserve', + 'ranked' => (bool) $this->getRawAttribute($key), - 'created_at_json', - 'updated_at_json' => $this->getJsonTimeFast($key), + 'created_at' => $this->getTimeFast($key), + 'created_at_json' => $this->getJsonTimeFast($key), 'pp' => $this->performance?->pp, diff --git a/database/migrations/2023_12_18_085034_update_scores_table.php b/database/migrations/2023_12_18_085034_update_scores_table.php new file mode 100644 index 00000000000..d67902fb822 --- /dev/null +++ b/database/migrations/2023_12_18_085034_update_scores_table.php @@ -0,0 +1,69 @@ +. Licensed under the GNU Affero General Public License v3.0. +// See the LICENCE file in the repository root for full licence text. + +declare(strict_types=1); + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + private static function resetView(): void + { + DB::statement('DROP VIEW scores'); + DB::statement('CREATE VIEW scores AS SELECT * FROM solo_scores'); + } + + public function up(): void + { + Schema::table('solo_scores', function (Blueprint $table) { + $table->dropColumn('updated_at'); + + $table->dropIndex('solo_scores_beatmap_id_index'); + $table->dropIndex('solo_scores_preserve_index'); + $table->dropIndex('user_ruleset_id_index'); + + $table->boolean('ranked')->default(true)->after('preserve'); + $table->unsignedInteger('unix_updated_at')->default(DB::raw('(unix_timestamp())')); + $table->timestamp('created_at')->useCurrent()->change(); + + $table->index(['user_id', 'ruleset_id'], 'user_ruleset_index'); + $table->index(['beatmap_id', 'user_id'], 'beatmap_user_index'); + }); + + DB::statement('ALTER TABLE solo_scores MODIFY id bigint unsigned NOT NULL'); + DB::statement('ALTER TABLE solo_scores DROP PRIMARY KEY'); + DB::statement('ALTER TABLE solo_scores ADD PRIMARY KEY (id, preserve, unix_updated_at)'); + DB::statement('ALTER TABLE solo_scores MODIFY id bigint unsigned NOT NULL AUTO_INCREMENT'); + + static::resetView(); + } + + public function down(): void + { + Schema::table('solo_scores', function (Blueprint $table) { + $table->dropColumn('unix_updated_at'); + $table->dropColumn('ranked'); + + $table->dropIndex('user_ruleset_index'); + $table->dropIndex('beatmap_user_index'); + + $table->datetime('created_at')->change(); + $table->timestamp('updated_at')->nullable(true); + + $table->index('preserve', 'solo_scores_preserve_index'); + $table->index('beatmap_id', 'solo_scores_beatmap_id_index'); + $table->index(['user_id', 'ruleset_id', DB::raw('id DESC')], 'user_ruleset_id_index'); + }); + + DB::statement('ALTER TABLE solo_scores MODIFY id bigint unsigned NOT NULL'); + DB::statement('ALTER TABLE solo_scores DROP PRIMARY KEY'); + DB::statement('ALTER TABLE solo_scores ADD PRIMARY KEY (id)'); + DB::statement('ALTER TABLE solo_scores MODIFY id bigint unsigned NOT NULL AUTO_INCREMENT'); + + static::resetView(); + } +}; diff --git a/database/mods.json b/database/mods.json index bf82cf1b2f5..0fb0df78b26 100644 --- a/database/mods.json +++ b/database/mods.json @@ -37,7 +37,6 @@ "SD", "PF", "AC", - "RX", "AP" ], "RequiresConfiguration": false, @@ -142,7 +141,6 @@ "NF", "PF", "TP", - "RX", "AP" ], "RequiresConfiguration": false, @@ -168,7 +166,6 @@ "NF", "SD", "AC", - "RX", "AP" ], "RequiresConfiguration": false, @@ -357,7 +354,6 @@ "EZ", "NF", "PF", - "RX", "AP" ], "RequiresConfiguration": false, @@ -634,10 +630,6 @@ "Type": "Automation", "Settings": [], "IncompatibleMods": [ - "NF", - "SD", - "PF", - "AC", "AL", "SG", "AT", @@ -1222,8 +1214,7 @@ "IncompatibleMods": [ "SD", "PF", - "AC", - "RX" + "AC" ], "RequiresConfiguration": false, "UserPlayable": true, @@ -1324,8 +1315,7 @@ ], "IncompatibleMods": [ "NF", - "PF", - "RX" + "PF" ], "RequiresConfiguration": false, "UserPlayable": true, @@ -1349,8 +1339,7 @@ "IncompatibleMods": [ "NF", "SD", - "AC", - "RX" + "AC" ], "RequiresConfiguration": false, "UserPlayable": true, @@ -1486,8 +1475,7 @@ ], "IncompatibleMods": [ "NF", - "PF", - "RX" + "PF" ], "RequiresConfiguration": false, "UserPlayable": true, @@ -1647,10 +1635,6 @@ "Type": "Automation", "Settings": [], "IncompatibleMods": [ - "NF", - "SD", - "PF", - "AC", "SG", "AT", "CN" @@ -1864,8 +1848,7 @@ "IncompatibleMods": [ "SD", "PF", - "AC", - "RX" + "AC" ], "RequiresConfiguration": false, "UserPlayable": true, @@ -1964,8 +1947,7 @@ ], "IncompatibleMods": [ "NF", - "PF", - "RX" + "PF" ], "RequiresConfiguration": false, "UserPlayable": true, @@ -1989,8 +1971,7 @@ "IncompatibleMods": [ "NF", "SD", - "AC", - "RX" + "AC" ], "RequiresConfiguration": false, "UserPlayable": true, @@ -2125,8 +2106,7 @@ "IncompatibleMods": [ "EZ", "NF", - "PF", - "RX" + "PF" ], "RequiresConfiguration": false, "UserPlayable": true, @@ -2253,10 +2233,6 @@ "Type": "Automation", "Settings": [], "IncompatibleMods": [ - "NF", - "SD", - "PF", - "AC", "AT", "CN" ], diff --git a/resources/css/bem/profile-info.less b/resources/css/bem/profile-info.less index ce11d01d982..00fe84197d5 100644 --- a/resources/css/bem/profile-info.less +++ b/resources/css/bem/profile-info.less @@ -130,6 +130,8 @@ &--supporter { .center-content(); + .link-plain(); + .link-white(); border-radius: 10000px; background-color: @osu-colour-h1; padding: 0 10px; diff --git a/resources/js/beatmapsets-show/header.tsx b/resources/js/beatmapsets-show/header.tsx index b3124acbda5..8dbc6034909 100644 --- a/resources/js/beatmapsets-show/header.tsx +++ b/resources/js/beatmapsets-show/header.tsx @@ -352,13 +352,23 @@ export default class Header extends React.Component {
} -
+ {trans(`beatmapsets.show.status.${this.controller.currentBeatmap.status}`)} -
+
); } + private statusToWikiLink(status: string): string { + let fragment: string; + if (status === 'wip' || status === 'pending') { + fragment = 'wip-and-pending'; + } else { + fragment = status; + } + return wikiUrl(`Beatmap/Category#${fragment}`); + } + private readonly updateFavouritePopup = () => { if (!this.hoveredFavouriteIcon) { return; diff --git a/resources/js/profile-page/cover.tsx b/resources/js/profile-page/cover.tsx index da2f5591c48..b608920468b 100644 --- a/resources/js/profile-page/cover.tsx +++ b/resources/js/profile-page/cover.tsx @@ -126,9 +126,9 @@ export default class Cover extends React.Component { return ( <> {this.props.user.is_supporter && - + {times(this.props.user.support_level ?? 0, (i) => )} - + } diff --git a/tests/Libraries/ModsTest.php b/tests/Libraries/ModsTest.php index 9e2fcb9e885..ddf54798ad5 100644 --- a/tests/Libraries/ModsTest.php +++ b/tests/Libraries/ModsTest.php @@ -152,12 +152,12 @@ public static function modComboExclusives() [Ruleset::mania, ['DT'], ['PF'], true], // conflicting exclusive required mods - [Ruleset::osu, ['RX', 'PF'], [], false], + [Ruleset::osu, ['HT', 'DT'], [], false], [Ruleset::mania, ['FI', 'HD'], [], false], // allowed mods conflicts with exclusive required mods - [Ruleset::osu, ['RX'], ['PF'], false], - [Ruleset::taiko, ['RX'], ['PF'], false], + [Ruleset::osu, ['HT'], ['DT'], false], + [Ruleset::taiko, ['HT'], ['DT'], false], ]; } } diff --git a/tests/Libraries/bbcode_examples/box_nested.html b/tests/Libraries/bbcode_examples/box_nested.html index 1a6195eb276..875c09151d7 100644 --- a/tests/Libraries/bbcode_examples/box_nested.html +++ b/tests/Libraries/bbcode_examples/box_nested.html @@ -1,12 +1,12 @@
- +
- +
Content
Another content diff --git a/tests/Libraries/bbcode_examples/box_with_bbcode_title.html b/tests/Libraries/bbcode_examples/box_with_bbcode_title.html index f827e8de58e..7a2a63dc1db 100644 --- a/tests/Libraries/bbcode_examples/box_with_bbcode_title.html +++ b/tests/Libraries/bbcode_examples/box_with_bbcode_title.html @@ -1,13 +1,13 @@
other content

- + [\[] weird \[ title
box content

other content 2
diff --git a/tests/Libraries/bbcode_examples/box_with_spoilerbox.base.txt b/tests/Libraries/bbcode_examples/box_with_spoilerbox.base.txt new file mode 100644 index 00000000000..464bc966fe4 --- /dev/null +++ b/tests/Libraries/bbcode_examples/box_with_spoilerbox.base.txt @@ -0,0 +1 @@ +[box=button[spoilerbox]in button[/spoilerbox]]best regex[/box] diff --git a/tests/Libraries/bbcode_examples/box_with_spoilerbox.db.txt b/tests/Libraries/bbcode_examples/box_with_spoilerbox.db.txt new file mode 100644 index 00000000000..5211ad089d2 --- /dev/null +++ b/tests/Libraries/bbcode_examples/box_with_spoilerbox.db.txt @@ -0,0 +1 @@ +[box=button[spoilerbox:1]in button[/spoilerbox:1]:1]best regex[/box:1] diff --git a/tests/Libraries/bbcode_examples/box_with_spoilerbox.html b/tests/Libraries/bbcode_examples/box_with_spoilerbox.html new file mode 100644 index 00000000000..d69735163e2 --- /dev/null +++ b/tests/Libraries/bbcode_examples/box_with_spoilerbox.html @@ -0,0 +1,12 @@ +
+ button +
+ +
+ in button +
+ +
+ +
best regex
+
diff --git a/tests/Libraries/bbcode_examples/box_with_surrounding_newlines.html b/tests/Libraries/bbcode_examples/box_with_surrounding_newlines.html index 028c3eec25a..20d4e5b464b 100644 --- a/tests/Libraries/bbcode_examples/box_with_surrounding_newlines.html +++ b/tests/Libraries/bbcode_examples/box_with_surrounding_newlines.html @@ -1,13 +1,13 @@ Upper line text.
-
Packed box.
+
First!
Packed box.
Bottom line text.

Prefix text. -
Inline box (except it's not).
+
Second box
Inline box (except it's not).
Suffix text.

Upper line text.

-
Box with blank lines.
+
Third box
Box with blank lines.

Bottom line text. diff --git a/tests/Libraries/bbcode_examples/spoilerbox_with_surrounding_newlines.html b/tests/Libraries/bbcode_examples/spoilerbox_with_surrounding_newlines.html index 966e9614b31..61a84425c37 100644 --- a/tests/Libraries/bbcode_examples/spoilerbox_with_surrounding_newlines.html +++ b/tests/Libraries/bbcode_examples/spoilerbox_with_surrounding_newlines.html @@ -1,13 +1,13 @@ Upper line text.
-
Packed spoilerbox.
+
SPOILER
Packed spoilerbox.
Bottom line text.

Prefix text. -
Inline spoilerbox (except it's not).
+
SPOILER
Inline spoilerbox (except it's not).
Suffix text.

Upper line text.

-
Spoilerbox with blank lines.
+
SPOILER
Spoilerbox with blank lines.

Bottom line text.