mirror of
https://github.com/rommapp/romm.git
synced 2026-02-18 00:27:41 +01:00
Added player count metadata from SS. Displays on game detail screen and added a filter under search for player counts.
This commit is contained in:
390
backend/alembic/versions/0063_roms_metadata_player_count.py
Normal file
390
backend/alembic/versions/0063_roms_metadata_player_count.py
Normal file
@@ -0,0 +1,390 @@
|
||||
"""Add player_count to roms_metadata view
|
||||
|
||||
Revision ID: 0063_roms_metadata_player_count
|
||||
Revises: 0062_rom_file_category_enum
|
||||
Create Date: 2026-01-02 14:45:00.000000
|
||||
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
from utils.database import is_postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "0063_roms_metadata_player_count"
|
||||
down_revision = "0062_rom_file_category_enum"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
connection = op.get_bind()
|
||||
if is_postgresql(connection):
|
||||
connection.execute(
|
||||
sa.text(
|
||||
"""
|
||||
CREATE OR REPLACE VIEW roms_metadata AS
|
||||
SELECT
|
||||
r.id AS rom_id,
|
||||
NOW() AS created_at,
|
||||
NOW() AS updated_at,
|
||||
COALESCE(
|
||||
(r.manual_metadata -> 'genres'),
|
||||
(r.igdb_metadata -> 'genres'),
|
||||
(r.moby_metadata -> 'genres'),
|
||||
(r.ss_metadata -> 'genres'),
|
||||
(r.launchbox_metadata -> 'genres'),
|
||||
(r.ra_metadata -> 'genres'),
|
||||
(r.flashpoint_metadata -> 'genres'),
|
||||
(r.gamelist_metadata -> 'genres'),
|
||||
'[]'::jsonb
|
||||
) AS genres,
|
||||
|
||||
COALESCE(
|
||||
(r.manual_metadata -> 'franchises'),
|
||||
(r.igdb_metadata -> 'franchises'),
|
||||
(r.ss_metadata -> 'franchises'),
|
||||
(r.flashpoint_metadata -> 'franchises'),
|
||||
(r.gamelist_metadata -> 'franchises'),
|
||||
'[]'::jsonb
|
||||
) AS franchises,
|
||||
|
||||
COALESCE(
|
||||
(r.igdb_metadata -> 'collections'),
|
||||
'[]'::jsonb
|
||||
) AS collections,
|
||||
|
||||
COALESCE(
|
||||
(r.manual_metadata -> 'companies'),
|
||||
(r.igdb_metadata -> 'companies'),
|
||||
(r.ss_metadata -> 'companies'),
|
||||
(r.ra_metadata -> 'companies'),
|
||||
(r.launchbox_metadata -> 'companies'),
|
||||
(r.flashpoint_metadata -> 'companies'),
|
||||
(r.gamelist_metadata -> 'companies'),
|
||||
'[]'::jsonb
|
||||
) AS companies,
|
||||
|
||||
COALESCE(
|
||||
(r.manual_metadata -> 'game_modes'),
|
||||
(r.igdb_metadata -> 'game_modes'),
|
||||
(r.ss_metadata -> 'game_modes'),
|
||||
(r.flashpoint_metadata -> 'game_modes'),
|
||||
'[]'::jsonb
|
||||
) AS game_modes,
|
||||
|
||||
COALESCE(
|
||||
(r.manual_metadata -> 'age_ratings'),
|
||||
CASE
|
||||
WHEN r.igdb_metadata IS NOT NULL
|
||||
AND r.igdb_metadata ? 'age_ratings'
|
||||
AND jsonb_array_length(r.igdb_metadata -> 'age_ratings') > 0
|
||||
THEN
|
||||
jsonb_path_query_array(r.igdb_metadata, '$.age_ratings[*].rating')
|
||||
ELSE
|
||||
'[]'::jsonb
|
||||
END,
|
||||
CASE
|
||||
WHEN r.launchbox_metadata IS NOT NULL
|
||||
AND r.launchbox_metadata ? 'esrb'
|
||||
AND r.launchbox_metadata ->> 'esrb' IS NOT NULL
|
||||
AND r.launchbox_metadata ->> 'esrb' != ''
|
||||
THEN
|
||||
jsonb_build_array(r.launchbox_metadata ->> 'esrb')
|
||||
ELSE
|
||||
'[]'::jsonb
|
||||
END,
|
||||
'[]'::jsonb
|
||||
) AS age_ratings,
|
||||
|
||||
COALESCE(r.ss_metadata ->> 'player_count', '1') AS player_count,
|
||||
|
||||
CASE
|
||||
WHEN r.manual_metadata IS NOT NULL AND r.manual_metadata ? 'first_release_date' AND
|
||||
r.manual_metadata ->> 'first_release_date' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.manual_metadata ->> 'first_release_date' ~ '^[0-9]+$'
|
||||
THEN (r.manual_metadata ->> 'first_release_date')::bigint
|
||||
|
||||
WHEN r.igdb_metadata IS NOT NULL AND r.igdb_metadata ? 'first_release_date' AND
|
||||
r.igdb_metadata ->> 'first_release_date' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.igdb_metadata ->> 'first_release_date' ~ '^[0-9]+$'
|
||||
THEN (r.igdb_metadata ->> 'first_release_date')::bigint * 1000
|
||||
|
||||
WHEN r.ss_metadata IS NOT NULL AND r.ss_metadata ? 'first_release_date' AND
|
||||
r.ss_metadata ->> 'first_release_date' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.ss_metadata ->> 'first_release_date' ~ '^[0-9]+$'
|
||||
THEN (r.ss_metadata ->> 'first_release_date')::bigint * 1000
|
||||
|
||||
WHEN r.ra_metadata IS NOT NULL AND r.ra_metadata ? 'first_release_date' AND
|
||||
r.ra_metadata ->> 'first_release_date' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.ra_metadata ->> 'first_release_date' ~ '^[0-9]+$'
|
||||
THEN (r.ra_metadata ->> 'first_release_date')::bigint * 1000
|
||||
|
||||
WHEN r.launchbox_metadata IS NOT NULL AND r.launchbox_metadata ? 'first_release_date' AND
|
||||
r.launchbox_metadata ->> 'first_release_date' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.launchbox_metadata ->> 'first_release_date' ~ '^[0-9]+$'
|
||||
THEN (r.launchbox_metadata ->> 'first_release_date')::bigint * 1000
|
||||
|
||||
WHEN r.flashpoint_metadata IS NOT NULL AND r.flashpoint_metadata ? 'first_release_date' AND
|
||||
r.flashpoint_metadata ->> 'first_release_date' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.flashpoint_metadata ->> 'first_release_date' ~ '^[0-9]+$'
|
||||
THEN (r.flashpoint_metadata ->> 'first_release_date')::bigint * 1000
|
||||
|
||||
WHEN r.gamelist_metadata IS NOT NULL
|
||||
AND r.gamelist_metadata ? 'first_release_date'
|
||||
AND r.gamelist_metadata ->> 'first_release_date' NOT IN ('null', 'None', '0', '0.0')
|
||||
AND r.gamelist_metadata ->> 'first_release_date' ~ '^[0-9]{8}T[0-9]{6}$'
|
||||
THEN (extract(epoch FROM to_timestamp(r.gamelist_metadata ->> 'first_release_date', 'YYYYMMDD"T"HH24MISS')) * 1000)::bigint
|
||||
|
||||
ELSE NULL
|
||||
END AS first_release_date,
|
||||
|
||||
CASE
|
||||
WHEN (igdb_rating IS NOT NULL OR moby_rating IS NOT NULL OR ss_rating IS NOT NULL OR launchbox_rating IS NOT NULL OR gamelist_rating IS NOT NULL) THEN
|
||||
(COALESCE(igdb_rating, 0) + COALESCE(moby_rating, 0) + COALESCE(ss_rating, 0) + COALESCE(launchbox_rating, 0) + COALESCE(gamelist_rating, 0)) /
|
||||
(CASE WHEN igdb_rating IS NOT NULL THEN 1 ELSE 0 END +
|
||||
CASE WHEN moby_rating IS NOT NULL THEN 1 ELSE 0 END +
|
||||
CASE WHEN ss_rating IS NOT NULL THEN 1 ELSE 0 END +
|
||||
CASE WHEN launchbox_rating IS NOT NULL THEN 1 ELSE 0 END +
|
||||
CASE WHEN gamelist_rating IS NOT NULL THEN 1 ELSE 0 END)
|
||||
ELSE NULL
|
||||
END AS average_rating
|
||||
FROM (
|
||||
SELECT
|
||||
r.id,
|
||||
r.manual_metadata,
|
||||
r.igdb_metadata,
|
||||
r.moby_metadata,
|
||||
r.ss_metadata,
|
||||
r.ra_metadata,
|
||||
r.launchbox_metadata,
|
||||
r.flashpoint_metadata,
|
||||
r.gamelist_metadata,
|
||||
CASE
|
||||
WHEN r.igdb_metadata IS NOT NULL AND r.igdb_metadata ? 'total_rating' AND
|
||||
r.igdb_metadata ->> 'total_rating' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.igdb_metadata ->> 'total_rating' ~ '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN (r.igdb_metadata ->> 'total_rating')::float
|
||||
ELSE NULL
|
||||
END AS igdb_rating,
|
||||
CASE
|
||||
WHEN r.moby_metadata IS NOT NULL AND r.moby_metadata ? 'moby_score' AND
|
||||
r.moby_metadata ->> 'moby_score' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.moby_metadata ->> 'moby_score' ~ '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN (r.moby_metadata ->> 'moby_score')::float * 10
|
||||
ELSE NULL
|
||||
END AS moby_rating,
|
||||
CASE
|
||||
WHEN r.ss_metadata IS NOT NULL AND r.ss_metadata ? 'ss_score' AND
|
||||
r.ss_metadata ->> 'ss_score' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.ss_metadata ->> 'ss_score' ~ '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN (r.ss_metadata ->> 'ss_score')::float * 10
|
||||
ELSE NULL
|
||||
END AS ss_rating,
|
||||
CASE
|
||||
WHEN r.launchbox_metadata IS NOT NULL AND r.launchbox_metadata ? 'community_rating' AND
|
||||
r.launchbox_metadata ->> 'community_rating' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.launchbox_metadata ->> 'community_rating' ~ '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN (r.launchbox_metadata ->> 'community_rating')::float * 20
|
||||
ELSE NULL
|
||||
END AS launchbox_rating,
|
||||
CASE
|
||||
WHEN r.gamelist_metadata IS NOT NULL AND r.gamelist_metadata ? 'rating' AND
|
||||
r.gamelist_metadata ->> 'rating' NOT IN ('null', 'None', '0', '0.0') AND
|
||||
r.gamelist_metadata ->> 'rating' ~ '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN (r.gamelist_metadata ->> 'rating')::float * 100
|
||||
ELSE NULL
|
||||
END AS gamelist_rating
|
||||
FROM roms r
|
||||
) AS r;
|
||||
"""
|
||||
)
|
||||
)
|
||||
else:
|
||||
connection.execute(
|
||||
sa.text(
|
||||
"""
|
||||
CREATE OR REPLACE VIEW roms_metadata AS
|
||||
SELECT
|
||||
r.id as rom_id,
|
||||
NOW() AS created_at,
|
||||
NOW() AS updated_at,
|
||||
COALESCE(
|
||||
JSON_EXTRACT(r.manual_metadata, '$.genres'),
|
||||
JSON_EXTRACT(r.igdb_metadata, '$.genres'),
|
||||
JSON_EXTRACT(r.moby_metadata, '$.genres'),
|
||||
JSON_EXTRACT(r.ss_metadata, '$.genres'),
|
||||
JSON_EXTRACT(r.launchbox_metadata, '$.genres'),
|
||||
JSON_EXTRACT(r.ra_metadata, '$.genres'),
|
||||
JSON_EXTRACT(r.flashpoint_metadata, '$.genres'),
|
||||
JSON_EXTRACT(r.gamelist_metadata, '$.genres'),
|
||||
JSON_ARRAY()
|
||||
) AS genres,
|
||||
|
||||
COALESCE(
|
||||
JSON_EXTRACT(r.manual_metadata, '$.franchises'),
|
||||
JSON_EXTRACT(r.igdb_metadata, '$.franchises'),
|
||||
JSON_EXTRACT(r.ss_metadata, '$.franchises'),
|
||||
JSON_EXTRACT(r.flashpoint_metadata, '$.franchises'),
|
||||
JSON_EXTRACT(r.gamelist_metadata, '$.franchises'),
|
||||
JSON_ARRAY()
|
||||
) AS franchises,
|
||||
|
||||
COALESCE(
|
||||
JSON_EXTRACT(r.igdb_metadata, '$.collections'),
|
||||
JSON_ARRAY()
|
||||
) AS collections,
|
||||
|
||||
COALESCE(
|
||||
JSON_EXTRACT(r.manual_metadata, '$.companies'),
|
||||
JSON_EXTRACT(r.igdb_metadata, '$.companies'),
|
||||
JSON_EXTRACT(r.ss_metadata, '$.companies'),
|
||||
JSON_EXTRACT(r.ra_metadata, '$.companies'),
|
||||
JSON_EXTRACT(r.launchbox_metadata, '$.companies'),
|
||||
JSON_EXTRACT(r.flashpoint_metadata, '$.companies'),
|
||||
JSON_EXTRACT(r.gamelist_metadata, '$.companies'),
|
||||
JSON_ARRAY()
|
||||
) AS companies,
|
||||
|
||||
COALESCE(
|
||||
JSON_EXTRACT(r.manual_metadata, '$.game_modes'),
|
||||
JSON_EXTRACT(r.igdb_metadata, '$.game_modes'),
|
||||
JSON_EXTRACT(r.ss_metadata, '$.game_modes'),
|
||||
JSON_EXTRACT(r.flashpoint_metadata, '$.game_modes'),
|
||||
JSON_ARRAY()
|
||||
) AS game_modes,
|
||||
|
||||
COALESCE(
|
||||
JSON_EXTRACT(r.manual_metadata, '$.age_ratings'),
|
||||
CASE
|
||||
WHEN JSON_CONTAINS_PATH(r.igdb_metadata, 'one', '$.age_ratings')
|
||||
AND JSON_LENGTH(JSON_EXTRACT(r.igdb_metadata, '$.age_ratings')) > 0
|
||||
THEN
|
||||
JSON_EXTRACT(r.igdb_metadata, '$.age_ratings[*].rating')
|
||||
ELSE
|
||||
JSON_ARRAY()
|
||||
END,
|
||||
CASE
|
||||
WHEN JSON_CONTAINS_PATH(r.launchbox_metadata, 'one', '$.esrb')
|
||||
AND JSON_EXTRACT(r.launchbox_metadata, '$.esrb') IS NOT NULL
|
||||
AND JSON_EXTRACT(r.launchbox_metadata, '$.esrb') != ''
|
||||
THEN
|
||||
JSON_ARRAY(JSON_EXTRACT(r.launchbox_metadata, '$.esrb'))
|
||||
ELSE
|
||||
JSON_ARRAY()
|
||||
END,
|
||||
JSON_ARRAY()
|
||||
) AS age_ratings,
|
||||
|
||||
COALESCE(JSON_UNQUOTE(JSON_EXTRACT(r.ss_metadata, '$.player_count')), '1') AS player_count,
|
||||
|
||||
CASE
|
||||
WHEN JSON_CONTAINS_PATH(r.manual_metadata, 'one', '$.first_release_date') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.manual_metadata, '$.first_release_date')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.manual_metadata, '$.first_release_date')) REGEXP '^[0-9]+$'
|
||||
THEN CAST(JSON_EXTRACT(r.manual_metadata, '$.first_release_date') AS SIGNED)
|
||||
|
||||
WHEN JSON_CONTAINS_PATH(r.igdb_metadata, 'one', '$.first_release_date') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.igdb_metadata, '$.first_release_date')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.igdb_metadata, '$.first_release_date')) REGEXP '^[0-9]+$'
|
||||
THEN CAST(JSON_EXTRACT(r.igdb_metadata, '$.first_release_date') AS SIGNED) * 1000
|
||||
|
||||
WHEN JSON_CONTAINS_PATH(r.ss_metadata, 'one', '$.first_release_date') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.ss_metadata, '$.first_release_date')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.ss_metadata, '$.first_release_date')) REGEXP '^[0-9]+$'
|
||||
THEN CAST(JSON_EXTRACT(r.ss_metadata, '$.first_release_date') AS SIGNED) * 1000
|
||||
|
||||
WHEN JSON_CONTAINS_PATH(r.ra_metadata, 'one', '$.first_release_date') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.ra_metadata, '$.first_release_date')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.ra_metadata, '$.first_release_date')) REGEXP '^[0-9]+$'
|
||||
THEN CAST(JSON_EXTRACT(r.ra_metadata, '$.first_release_date') AS SIGNED) * 1000
|
||||
|
||||
WHEN JSON_CONTAINS_PATH(r.launchbox_metadata, 'one', '$.first_release_date') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.launchbox_metadata, '$.first_release_date')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.launchbox_metadata, '$.first_release_date')) REGEXP '^[0-9]+$'
|
||||
THEN CAST(JSON_EXTRACT(r.launchbox_metadata, '$.first_release_date') AS SIGNED) * 1000
|
||||
|
||||
WHEN JSON_CONTAINS_PATH(r.flashpoint_metadata, 'one', '$.first_release_date') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.flashpoint_metadata, '$.first_release_date')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.flashpoint_metadata, '$.first_release_date')) REGEXP '^[0-9]+$'
|
||||
THEN CAST(JSON_EXTRACT(r.flashpoint_metadata, '$.first_release_date') AS SIGNED) * 1000
|
||||
|
||||
WHEN JSON_CONTAINS_PATH(r.gamelist_metadata, 'one', '$.first_release_date')
|
||||
AND JSON_UNQUOTE(JSON_EXTRACT(r.gamelist_metadata, '$.first_release_date')) NOT IN ('null', 'None', '0', '0.0')
|
||||
AND JSON_UNQUOTE(JSON_EXTRACT(r.gamelist_metadata, '$.first_release_date')) REGEXP '^[0-9]{8}T[0-9]{6}$'
|
||||
THEN UNIX_TIMESTAMP(
|
||||
STR_TO_DATE(
|
||||
JSON_UNQUOTE(JSON_EXTRACT(r.gamelist_metadata, '$.first_release_date')),
|
||||
'%Y%m%dT%H%i%S'
|
||||
)
|
||||
) * 1000
|
||||
|
||||
ELSE NULL
|
||||
END AS first_release_date,
|
||||
|
||||
CASE
|
||||
WHEN (igdb_rating IS NOT NULL OR moby_rating IS NOT NULL OR ss_rating IS NOT NULL OR launchbox_rating IS NOT NULL OR gamelist_rating IS NOT NULL) THEN
|
||||
(COALESCE(igdb_rating, 0) + COALESCE(moby_rating, 0) + COALESCE(ss_rating, 0) + COALESCE(launchbox_rating, 0) + COALESCE(gamelist_rating, 0)) /
|
||||
(CASE WHEN igdb_rating IS NOT NULL THEN 1 ELSE 0 END +
|
||||
CASE WHEN moby_rating IS NOT NULL THEN 1 ELSE 0 END +
|
||||
CASE WHEN ss_rating IS NOT NULL THEN 1 ELSE 0 END +
|
||||
CASE WHEN launchbox_rating IS NOT NULL THEN 1 ELSE 0 END +
|
||||
CASE WHEN gamelist_rating IS NOT NULL THEN 1 ELSE 0 END)
|
||||
ELSE NULL
|
||||
END AS average_rating
|
||||
FROM (
|
||||
SELECT
|
||||
id,
|
||||
manual_metadata,
|
||||
igdb_metadata,
|
||||
moby_metadata,
|
||||
ss_metadata,
|
||||
ra_metadata,
|
||||
launchbox_metadata,
|
||||
flashpoint_metadata,
|
||||
gamelist_metadata,
|
||||
CASE
|
||||
WHEN JSON_CONTAINS_PATH(igdb_metadata, 'one', '$.total_rating') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(igdb_metadata, '$.total_rating')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(igdb_metadata, '$.total_rating')) REGEXP '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN CAST(JSON_EXTRACT(igdb_metadata, '$.total_rating') AS DECIMAL(10,2))
|
||||
ELSE NULL
|
||||
END AS igdb_rating,
|
||||
CASE
|
||||
WHEN JSON_CONTAINS_PATH(moby_metadata, 'one', '$.moby_score') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(moby_metadata, '$.moby_score')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(moby_metadata, '$.moby_score')) REGEXP '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN CAST(JSON_EXTRACT(moby_metadata, '$.moby_score') AS DECIMAL(10,2)) * 10
|
||||
ELSE NULL
|
||||
END AS moby_rating,
|
||||
CASE
|
||||
WHEN JSON_CONTAINS_PATH(ss_metadata, 'one', '$.ss_score') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(ss_metadata, '$.ss_score')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(ss_metadata, '$.ss_score')) REGEXP '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN CAST(JSON_EXTRACT(ss_metadata, '$.ss_score') AS DECIMAL(10,2)) * 10
|
||||
ELSE NULL
|
||||
END AS ss_rating,
|
||||
CASE
|
||||
WHEN JSON_CONTAINS_PATH(launchbox_metadata, 'one', '$.community_rating') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(launchbox_metadata, '$.community_rating')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(launchbox_metadata, '$.community_rating')) REGEXP '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN CAST(JSON_EXTRACT(launchbox_metadata, '$.community_rating') AS DECIMAL(10,2)) * 20
|
||||
ELSE NULL
|
||||
END AS launchbox_rating,
|
||||
CASE
|
||||
WHEN JSON_CONTAINS_PATH(gamelist_metadata, 'one', '$.rating') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(gamelist_metadata, '$.rating')) NOT IN ('null', 'None', '0', '0.0') AND
|
||||
JSON_UNQUOTE(JSON_EXTRACT(gamelist_metadata, '$.rating')) REGEXP '^[0-9]+(\\.[0-9]+)?$'
|
||||
THEN CAST(JSON_EXTRACT(gamelist_metadata, '$.rating') AS DECIMAL(10,2)) * 100
|
||||
ELSE NULL
|
||||
END AS gamelist_rating
|
||||
FROM roms
|
||||
) AS r;
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.execute("DROP VIEW IF EXISTS roms_metadata")
|
||||
@@ -178,6 +178,7 @@ class RomMetadataSchema(BaseModel):
|
||||
companies: list[str]
|
||||
game_modes: list[str]
|
||||
age_ratings: list[str]
|
||||
player_count: str
|
||||
first_release_date: int | None
|
||||
average_rating: float | None
|
||||
|
||||
|
||||
@@ -333,6 +333,15 @@ def get_roms(
|
||||
),
|
||||
),
|
||||
] = None,
|
||||
player_counts: Annotated[
|
||||
list[str] | None,
|
||||
Query(
|
||||
description=(
|
||||
"Associated player count. Multiple values are allowed by repeating"
|
||||
" the parameter, and results that match any of the values will be returned."
|
||||
),
|
||||
),
|
||||
] = None,
|
||||
# Logic operators for multi-value filters
|
||||
genres_logic: Annotated[
|
||||
str,
|
||||
@@ -382,6 +391,12 @@ def get_roms(
|
||||
description="Logic operator for statuses filter: 'any' (OR) or 'all' (AND).",
|
||||
),
|
||||
] = "any",
|
||||
player_counts_logic: Annotated[
|
||||
str,
|
||||
Query(
|
||||
description="Logic operator for player counts filter: 'any' (OR) or 'all' (AND).",
|
||||
),
|
||||
] = "any",
|
||||
order_by: Annotated[
|
||||
str,
|
||||
Query(description="Field to order results by."),
|
||||
@@ -423,6 +438,7 @@ def get_roms(
|
||||
selected_statuses=selected_statuses,
|
||||
regions=regions,
|
||||
languages=languages,
|
||||
player_counts=player_counts,
|
||||
# Logic operators
|
||||
genres_logic=genres_logic,
|
||||
franchises_logic=franchises_logic,
|
||||
@@ -432,6 +448,7 @@ def get_roms(
|
||||
regions_logic=regions_logic,
|
||||
languages_logic=languages_logic,
|
||||
statuses_logic=statuses_logic,
|
||||
player_counts_logic=player_counts_logic,
|
||||
group_by_meta_id=group_by_meta_id,
|
||||
)
|
||||
|
||||
|
||||
@@ -462,6 +462,16 @@ class DBRomsHandler(DBBaseHandler):
|
||||
op = json_array_contains_all if match_all else json_array_contains_any
|
||||
return query.filter(op(Rom.languages, values, session=session))
|
||||
|
||||
def filter_by_player_counts(
|
||||
self,
|
||||
query: Query,
|
||||
*,
|
||||
session: Session,
|
||||
values: Sequence[str],
|
||||
match_all: bool = False,
|
||||
) -> Query:
|
||||
return query.filter(RomMetadata.player_count.in_(values))
|
||||
|
||||
@begin_session
|
||||
def filter_roms(
|
||||
self,
|
||||
@@ -488,6 +498,7 @@ class DBRomsHandler(DBBaseHandler):
|
||||
selected_statuses: Sequence[str] | None = None,
|
||||
regions: Sequence[str] | None = None,
|
||||
languages: Sequence[str] | None = None,
|
||||
player_counts: Sequence[str] | None = None,
|
||||
# Logic operators for multi-value filters
|
||||
genres_logic: str = "any",
|
||||
franchises_logic: str = "any",
|
||||
@@ -497,6 +508,7 @@ class DBRomsHandler(DBBaseHandler):
|
||||
regions_logic: str = "any",
|
||||
languages_logic: str = "any",
|
||||
statuses_logic: str = "any",
|
||||
player_counts_logic: str = "any",
|
||||
user_id: int | None = None,
|
||||
session: Session = None, # type: ignore
|
||||
) -> Query[Rom]:
|
||||
@@ -656,7 +668,7 @@ class DBRomsHandler(DBBaseHandler):
|
||||
|
||||
# Optimize JOINs - only join tables when needed
|
||||
needs_metadata_join = any(
|
||||
[genres, franchises, collections, companies, age_ratings]
|
||||
[genres, franchises, collections, companies, age_ratings, player_counts]
|
||||
)
|
||||
|
||||
if needs_metadata_join:
|
||||
@@ -671,6 +683,7 @@ class DBRomsHandler(DBBaseHandler):
|
||||
(age_ratings, age_ratings_logic, self.filter_by_age_ratings),
|
||||
(regions, regions_logic, self.filter_by_regions),
|
||||
(languages, languages_logic, self.filter_by_languages),
|
||||
(player_counts, player_counts_logic, self.filter_by_player_counts),
|
||||
]
|
||||
|
||||
for values, logic, filter_func in filters_to_apply:
|
||||
@@ -766,6 +779,7 @@ class DBRomsHandler(DBBaseHandler):
|
||||
selected_statuses=kwargs.get("selected_statuses", None),
|
||||
regions=kwargs.get("regions", None),
|
||||
languages=kwargs.get("languages", None),
|
||||
player_counts=kwargs.get("player_counts", None),
|
||||
# Logic operators for multi-value filters
|
||||
genres_logic=kwargs.get("genres_logic", "any"),
|
||||
franchises_logic=kwargs.get("franchises_logic", "any"),
|
||||
@@ -775,6 +789,7 @@ class DBRomsHandler(DBBaseHandler):
|
||||
regions_logic=kwargs.get("regions_logic", "any"),
|
||||
languages_logic=kwargs.get("languages_logic", "any"),
|
||||
statuses_logic=kwargs.get("statuses_logic", "any"),
|
||||
player_counts_logic=kwargs.get("player_counts_logic", "any"),
|
||||
user_id=kwargs.get("user_id", None),
|
||||
)
|
||||
return session.scalars(roms).all()
|
||||
|
||||
@@ -128,6 +128,7 @@ class SSMetadata(SSMetadataMedia):
|
||||
franchises: list[str]
|
||||
game_modes: list[str]
|
||||
genres: list[str]
|
||||
player_count: str
|
||||
|
||||
|
||||
class SSRom(BaseRom):
|
||||
@@ -352,6 +353,12 @@ def extract_metadata_from_ss_rom(rom: Rom, game: SSGame) -> SSMetadata:
|
||||
return modes
|
||||
return []
|
||||
|
||||
def _get_player_count(game: SSGame) -> str:
|
||||
player_count = game.get("joueurs", {}).get("text")
|
||||
if not player_count or str(player_count).lower() in ("null", "none"):
|
||||
return "1"
|
||||
return str(player_count)
|
||||
|
||||
return SSMetadata(
|
||||
{
|
||||
"ss_score": _normalize_score(game.get("note", {}).get("text", "")),
|
||||
@@ -366,6 +373,7 @@ def extract_metadata_from_ss_rom(rom: Rom, game: SSGame) -> SSMetadata:
|
||||
"first_release_date": _get_lowest_date(game.get("dates", [])),
|
||||
"franchises": _get_franchises(game),
|
||||
"game_modes": _get_game_modes(game),
|
||||
"player_count": _get_player_count(game),
|
||||
**extract_media_from_ss_game(rom, game),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -136,6 +136,7 @@ class RomMetadata(BaseModel):
|
||||
companies: Mapped[list[str] | None] = mapped_column(CustomJSON(), default=[])
|
||||
game_modes: Mapped[list[str] | None] = mapped_column(CustomJSON(), default=[])
|
||||
age_ratings: Mapped[list[str] | None] = mapped_column(CustomJSON(), default=[])
|
||||
player_count: Mapped[str | None] = mapped_column(String(length=100), default=1)
|
||||
first_release_date: Mapped[int | None] = mapped_column(BigInteger(), default=None)
|
||||
average_rating: Mapped[float | None] = mapped_column(default=None)
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ def test_update_rom(
|
||||
"genres": '[{"id": 5, "name": "Shooter"}, {"id": 8, "name": "Platform"}, {"id": 31, "name": "Adventure"}]',
|
||||
"franchises": '[{"id": 756, "name": "Metroid"}]',
|
||||
"collections": '[{"id": 243, "name": "Metroid"}, {"id": 6240, "name": "Metroid Prime"}]',
|
||||
"player_count": '1',
|
||||
"expansions": "[]",
|
||||
"dlcs": "[]",
|
||||
"companies": '[{"id": 203227, "company": {"id": 70, "name": "Nintendo"}}, {"id": 203307, "company": {"id": 766, "name": "Retro Studios"}}]',
|
||||
@@ -380,6 +381,7 @@ class TestUpdateRawMetadata:
|
||||
raw_metadata = {
|
||||
"ss_score": "85",
|
||||
"alternative_names": ["Test SS Game"],
|
||||
"player_count": "1-4",
|
||||
}
|
||||
|
||||
response = client.put(
|
||||
@@ -396,6 +398,7 @@ class TestUpdateRawMetadata:
|
||||
assert body["ss_metadata"] is not None
|
||||
assert body["ss_metadata"]["ss_score"] == "85"
|
||||
assert body["ss_metadata"]["alternative_names"] == ["Test SS Game"]
|
||||
assert body["ss_metadata"]["player_count"] == "1-4"
|
||||
|
||||
@patch.object(
|
||||
LaunchboxHandler,
|
||||
|
||||
@@ -10,6 +10,7 @@ export type RomMetadataSchema = {
|
||||
companies: Array<string>;
|
||||
game_modes: Array<string>;
|
||||
age_ratings: Array<string>;
|
||||
player_count: (string | null);
|
||||
first_release_date: (number | null);
|
||||
average_rating: (number | null);
|
||||
};
|
||||
|
||||
@@ -36,5 +36,6 @@ export type RomSSMetadata = {
|
||||
franchises?: Array<string>;
|
||||
game_modes?: Array<string>;
|
||||
genres?: Array<string>;
|
||||
player_count?: (string | null);
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,11 @@ const filters = [
|
||||
name: t("rom.collections"),
|
||||
},
|
||||
{ key: "company", path: "metadatum.companies", name: t("rom.companies") },
|
||||
{
|
||||
key: "players",
|
||||
path: "metadatum.player_count",
|
||||
name: t("rom.player-count"),
|
||||
},
|
||||
] as const;
|
||||
|
||||
const dataSources = computed(() => {
|
||||
@@ -217,17 +222,30 @@ function onFilterClick(filter: FilterType, value: string) {
|
||||
<span>{{ filter.name }}</span>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-chip
|
||||
v-for="value in get(rom, filter.path)"
|
||||
:key="value"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
class="my-1 mr-2"
|
||||
label
|
||||
@click="onFilterClick(filter.key, value)"
|
||||
>
|
||||
{{ value }}
|
||||
</v-chip>
|
||||
<template v-if="Array.isArray(get(rom, filter.path))">
|
||||
<v-chip
|
||||
v-for="value in get(rom, filter.path).filter((v: string) => !!v)"
|
||||
:key="value"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
class="my-1 mr-2"
|
||||
label
|
||||
@click="onFilterClick(filter.key, value)"
|
||||
>
|
||||
{{ value }}
|
||||
</v-chip>
|
||||
</template>
|
||||
<template v-else-if="get(rom, filter.path)">
|
||||
<v-chip
|
||||
size="small"
|
||||
variant="outlined"
|
||||
class="my-1 mr-2"
|
||||
label
|
||||
@click="onFilterClick(filter.key, get(rom, filter.path))"
|
||||
>
|
||||
{{ get(rom, filter.path) }}
|
||||
</v-chip>
|
||||
</template>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
@@ -75,6 +75,9 @@ const {
|
||||
filterLanguages,
|
||||
selectedLanguages,
|
||||
languagesLogic,
|
||||
filterPlayerCounts,
|
||||
selectedPlayerCounts,
|
||||
playerCountsLogic,
|
||||
} = storeToRefs(galleryFilterStore);
|
||||
const { allPlatforms } = storeToRefs(platformsStore);
|
||||
const emitter = inject<Emitter<Events>>("emitter");
|
||||
@@ -150,6 +153,12 @@ const onFilterChange = debounce(
|
||||
: null,
|
||||
statusesLogic:
|
||||
selectedStatuses.value.length > 1 ? statusesLogic.value : null,
|
||||
playerCounts:
|
||||
selectedPlayerCounts.value.length > 0
|
||||
? selectedPlayerCounts.value.join(",")
|
||||
: 1,
|
||||
playerCountsLogic:
|
||||
selectedPlayerCounts.value.length > 0 ? playerCountsLogic.value : 1,
|
||||
}).forEach(([key, value]) => {
|
||||
if (value) {
|
||||
url.searchParams.set(key, value);
|
||||
@@ -234,6 +243,14 @@ const filters = [
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
galleryFilterStore.setLanguagesLogic(logic),
|
||||
},
|
||||
{
|
||||
label: t("platform.player-count"),
|
||||
selected: selectedPlayerCounts,
|
||||
items: filterPlayerCounts,
|
||||
logic: playerCountsLogic,
|
||||
setLogic: (logic: "any" | "all") =>
|
||||
galleryFilterStore.setPlayerCountsLogic(logic),
|
||||
},
|
||||
{
|
||||
label: t("platform.status"),
|
||||
selected: selectedStatuses,
|
||||
@@ -341,6 +358,10 @@ function setFilters() {
|
||||
galleryFilterStore.setFilterLanguages([
|
||||
...new Set(romsForFilters.flatMap((rom) => rom.languages).sort()),
|
||||
]);
|
||||
galleryFilterStore.setFilterPlayerCounts([
|
||||
...new Set(romsForFilters.flatMap((rom) => rom.metadatum.player_count).sort(),
|
||||
),
|
||||
]);
|
||||
// Note: filterStatuses is static and doesn't need to be set dynamically
|
||||
}
|
||||
|
||||
@@ -373,6 +394,8 @@ onMounted(async () => {
|
||||
languagesLogic: urlLanguagesLogic,
|
||||
statuses: urlStatuses,
|
||||
statusesLogic: urlStatusesLogic,
|
||||
playerCounts: urlPlayerCounts,
|
||||
playerCountsLogic: urlPlayerCountsLogic,
|
||||
} = router.currentRoute.value.query;
|
||||
|
||||
// Check for query params to set filters
|
||||
@@ -535,6 +558,14 @@ onMounted(async () => {
|
||||
}
|
||||
}
|
||||
|
||||
if (urlPlayerCounts !== undefined) {
|
||||
const playerCounts = (urlPlayerCounts as string).split(",").filter((pc) => pc.trim());
|
||||
galleryFilterStore.setSelectedFilterPlayerCounts(playerCounts);
|
||||
if (urlPlayerCountsLogic !== undefined) {
|
||||
galleryFilterStore.setPlayerCountsLogic(urlPlayerCountsLogic as "any" | "all");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if search term is set in the URL (empty string is ok)
|
||||
const freshSearch = urlSearch !== undefined && urlSearch !== searchTerm.value;
|
||||
if (freshSearch) {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"no-firmware-found": "No firmware found",
|
||||
"old-horizontal-cases": "Old horizontal cases",
|
||||
"old-squared-cases": "Old squared cases",
|
||||
"player-count": "Player count",
|
||||
"region": "Region",
|
||||
"removing-platform-1": "Removing platform",
|
||||
"removing-platform-2": "] from RomM. Do you confirm?",
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
"no-states-found": "No states found",
|
||||
"now-playing": "Now playing",
|
||||
"personal": "Personal",
|
||||
"player-count": "Players",
|
||||
"public-notes": "Public notes",
|
||||
"rating": "Rating",
|
||||
"refresh-metadata": "Refresh metadata",
|
||||
|
||||
@@ -87,6 +87,7 @@ export interface GetRomsParams {
|
||||
selectedAgeRatings?: string[] | null;
|
||||
selectedRegions?: string[] | null;
|
||||
selectedLanguages?: string[] | null;
|
||||
selectedPlayerCounts?: string[] | null;
|
||||
selectedStatuses?: string[] | null;
|
||||
// Logic operators for multi-value filters
|
||||
genresLogic?: string | null;
|
||||
@@ -97,6 +98,7 @@ export interface GetRomsParams {
|
||||
regionsLogic?: string | null;
|
||||
languagesLogic?: string | null;
|
||||
statusesLogic?: string | null;
|
||||
playerCountsLogic?: string | null;
|
||||
}
|
||||
|
||||
async function getRoms({
|
||||
@@ -124,6 +126,7 @@ async function getRoms({
|
||||
selectedAgeRatings = null,
|
||||
selectedRegions = null,
|
||||
selectedLanguages = null,
|
||||
selectedPlayerCounts = null,
|
||||
selectedStatuses = null,
|
||||
// Logic operators
|
||||
genresLogic = null,
|
||||
@@ -134,6 +137,7 @@ async function getRoms({
|
||||
regionsLogic = null,
|
||||
languagesLogic = null,
|
||||
statusesLogic = null,
|
||||
playerCountsLogic = null,
|
||||
}: GetRomsParams): Promise<{ data: GetRomsResponse }> {
|
||||
const params = {
|
||||
platform_ids:
|
||||
@@ -177,6 +181,10 @@ async function getRoms({
|
||||
selectedLanguages && selectedLanguages.length > 0
|
||||
? selectedLanguages
|
||||
: undefined,
|
||||
player_counts:
|
||||
selectedPlayerCounts && selectedPlayerCounts.length > 0
|
||||
? selectedPlayerCounts
|
||||
: undefined,
|
||||
// Logic operators
|
||||
genres_logic:
|
||||
selectedGenres && selectedGenres.length > 1
|
||||
@@ -210,6 +218,10 @@ async function getRoms({
|
||||
selectedStatuses && selectedStatuses.length > 1
|
||||
? statusesLogic || "any"
|
||||
: undefined,
|
||||
player_counts_logic:
|
||||
selectedPlayerCounts && selectedPlayerCounts.length > 1
|
||||
? playerCountsLogic || "any"
|
||||
: undefined,
|
||||
...(filterMatched !== null ? { matched: filterMatched } : {}),
|
||||
...(filterFavorites !== null ? { favorite: filterFavorites } : {}),
|
||||
...(filterDuplicates !== null ? { duplicate: filterDuplicates } : {}),
|
||||
|
||||
8
frontend/src/services/cache/api.ts
vendored
8
frontend/src/services/cache/api.ts
vendored
@@ -74,6 +74,10 @@ class CachedApiService {
|
||||
params.selectedLanguages && params.selectedLanguages.length > 0
|
||||
? params.selectedLanguages
|
||||
: undefined,
|
||||
player_counts:
|
||||
params.selectedPlayerCounts && params.selectedPlayerCounts.length > 0
|
||||
? params.selectedPlayerCounts
|
||||
: undefined,
|
||||
// Logic operators
|
||||
genres_logic:
|
||||
params.selectedGenres && params.selectedGenres.length > 1
|
||||
@@ -107,6 +111,10 @@ class CachedApiService {
|
||||
params.selectedStatuses && params.selectedStatuses.length > 1
|
||||
? params.statusesLogic || "any"
|
||||
: undefined,
|
||||
player_counts_logic:
|
||||
params.selectedPlayerCounts && params.selectedPlayerCounts.length > 1
|
||||
? params.playerCountsLogic || "any"
|
||||
: undefined,
|
||||
...(params.filterMatched !== null
|
||||
? { matched: params.filterMatched }
|
||||
: {}),
|
||||
|
||||
@@ -12,7 +12,8 @@ export type FilterType =
|
||||
| "ageRating"
|
||||
| "status"
|
||||
| "region"
|
||||
| "language";
|
||||
| "language"
|
||||
| "playerCount";
|
||||
|
||||
const defaultFilterState = {
|
||||
activeFilterDrawer: false,
|
||||
@@ -25,6 +26,7 @@ const defaultFilterState = {
|
||||
filterAgeRatings: [] as string[],
|
||||
filterRegions: [] as string[],
|
||||
filterLanguages: [] as string[],
|
||||
filterPlayerCounts: [] as string[],
|
||||
filterStatuses: Object.values(romStatusMap).map((status) => status.text),
|
||||
filterMatched: null as boolean | null, // null = all, true = matched, false = unmatched
|
||||
filterFavorites: null as boolean | null, // null = all, true = favorites, false = not favorites
|
||||
@@ -42,6 +44,7 @@ const defaultFilterState = {
|
||||
selectedAgeRatings: [] as string[],
|
||||
selectedRegions: [] as string[],
|
||||
selectedLanguages: [] as string[],
|
||||
selectedPlayerCounts: [] as string[],
|
||||
selectedStatuses: [] as string[],
|
||||
// Logic operators for multi-select filters
|
||||
genresLogic: "any" as "any" | "all",
|
||||
@@ -52,6 +55,7 @@ const defaultFilterState = {
|
||||
regionsLogic: "any" as "any" | "all",
|
||||
languagesLogic: "any" as "any" | "all",
|
||||
statusesLogic: "any" as "any" | "all",
|
||||
playerCountsLogic: "any" as "any" | "all",
|
||||
};
|
||||
|
||||
export default defineStore("galleryFilter", {
|
||||
@@ -85,6 +89,9 @@ export default defineStore("galleryFilter", {
|
||||
setFilterLanguages(languages: string[]) {
|
||||
this.filterLanguages = languages;
|
||||
},
|
||||
setFilterPlayerCounts(playerCounts: string[]) {
|
||||
this.filterPlayerCounts = playerCounts;
|
||||
},
|
||||
setSelectedFilterPlatform(platform: Platform) {
|
||||
this.selectedPlatform = platform
|
||||
? this.filterPlatforms.find((p) => p.id === platform.id) || null
|
||||
@@ -137,6 +144,12 @@ export default defineStore("galleryFilter", {
|
||||
setLanguagesLogic(logic: "any" | "all") {
|
||||
this.languagesLogic = logic;
|
||||
},
|
||||
setSelectedFilterPlayerCounts(playerCounts: string[]) {
|
||||
this.selectedPlayerCounts = playerCounts;
|
||||
},
|
||||
setPlayerCountsLogic(logic: "any" | "all") {
|
||||
this.playerCountsLogic = logic;
|
||||
},
|
||||
setSelectedFilterStatuses(statuses: string[]) {
|
||||
this.selectedStatuses = statuses;
|
||||
},
|
||||
@@ -336,6 +349,7 @@ export default defineStore("galleryFilter", {
|
||||
this.selectedAgeRatings.length > 0 ||
|
||||
this.selectedRegions.length > 0 ||
|
||||
this.selectedLanguages.length > 0 ||
|
||||
this.selectedPlayerCounts.length > 0 ||
|
||||
this.selectedStatuses.length > 0,
|
||||
);
|
||||
},
|
||||
@@ -352,6 +366,7 @@ export default defineStore("galleryFilter", {
|
||||
this.selectedAgeRatings = [];
|
||||
this.selectedRegions = [];
|
||||
this.selectedLanguages = [];
|
||||
this.selectedPlayerCounts = [];
|
||||
this.selectedStatuses = [];
|
||||
this.filterMatched = null;
|
||||
this.filterFavorites = null;
|
||||
@@ -369,6 +384,7 @@ export default defineStore("galleryFilter", {
|
||||
this.regionsLogic = "any";
|
||||
this.languagesLogic = "any";
|
||||
this.statusesLogic = "any";
|
||||
this.playerCountsLogic = "any";
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -135,6 +135,7 @@ export default defineStore("roms", {
|
||||
selectedAgeRatings: galleryFilter.selectedAgeRatings,
|
||||
selectedRegions: galleryFilter.selectedRegions,
|
||||
selectedLanguages: galleryFilter.selectedLanguages,
|
||||
selectedPlayerCounts: galleryFilter.selectedPlayerCounts,
|
||||
selectedStatuses: galleryFilter.selectedStatuses,
|
||||
// Logic operators
|
||||
genresLogic: galleryFilter.genresLogic,
|
||||
@@ -145,6 +146,7 @@ export default defineStore("roms", {
|
||||
regionsLogic: galleryFilter.regionsLogic,
|
||||
languagesLogic: galleryFilter.languagesLogic,
|
||||
statusesLogic: galleryFilter.statusesLogic,
|
||||
playerCountsLogic: galleryFilter.playerCountsLogic,
|
||||
};
|
||||
return params;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user