Add new game badge

This commit is contained in:
2026-06-04 17:59:00 +09:00
parent 95a7d9a033
commit 79d92160de
2 changed files with 25 additions and 3 deletions
+14 -3
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
from datetime import datetime from datetime import datetime, timedelta
from sqlalchemy import desc from sqlalchemy import desc
from sqlalchemy import text from sqlalchemy import text
@@ -49,6 +49,7 @@ class ModelFreeGameItem(ModelBase):
return [] return []
def as_dict(self): def as_dict(self):
is_new = bool(self.created_time and self.created_time >= datetime.now() - timedelta(hours=48))
return { return {
"id": self.id, "id": self.id,
"external_id": self.external_id, "external_id": self.external_id,
@@ -66,6 +67,8 @@ class ModelFreeGameItem(ModelBase):
"metacritic_score": self.metacritic_score, "metacritic_score": self.metacritic_score,
"metacritic_url": self.metacritic_url, "metacritic_url": self.metacritic_url,
"genres": self.genres, "genres": self.genres,
"is_new": is_new,
"created_time": self.created_time.strftime("%Y-%m-%d %H:%M:%S") if self.created_time else "",
"updated_time": self.updated_time.strftime("%Y-%m-%d %H:%M:%S") if self.updated_time else "", "updated_time": self.updated_time.strftime("%Y-%m-%d %H:%M:%S") if self.updated_time else "",
} }
@@ -127,8 +130,16 @@ class ModelFreeGameItem(ModelBase):
@classmethod @classmethod
def replace_source_items(cls, source_name, items): def replace_source_items(cls, source_name, items):
with F.app.app_context(): with F.app.app_context():
F.db.session.query(cls).filter_by(platform=source_name).delete(synchronize_session=False) incoming_ids = {
F.db.session.commit() str(item.get("external_id") or "")
for item in items
if str(item.get("external_id") or "")
}
query = F.db.session.query(cls).filter_by(platform=source_name)
if incoming_ids:
query.filter(~cls.external_id.in_(incoming_ids)).delete(synchronize_session=False)
else:
query.delete(synchronize_session=False)
for item in items: for item in items:
cls.upsert(item) cls.upsert(item)
F.db.session.commit() F.db.session.commit()
+11
View File
@@ -83,6 +83,13 @@
background: #16a34a; background: #16a34a;
color: #fff; color: #fff;
} }
.ffg-badge-new {
left: 10px;
bottom: 10px;
background: #ef4444;
color: #fff;
box-shadow: 0 0 0 2px rgba(0, 0, 0, .18);
}
.ffg-platform-epic { background: #2f313a; } .ffg-platform-epic { background: #2f313a; }
.ffg-platform-steam { background: #1b4b91; color: #fff; } .ffg-platform-steam { background: #1b4b91; color: #fff; }
.ffg-platform-gog { background: #4a2876; } .ffg-platform-gog { background: #4a2876; }
@@ -249,6 +256,9 @@ function gameCard(item) {
const mcHtml = mcScore > 0 const mcHtml = mcScore > 0
? `<span class="ffg-mc" title="Metacritic score">MC ${Math.round(mcScore)}</span>` ? `<span class="ffg-mc" title="Metacritic score">MC ${Math.round(mcScore)}</span>`
: ""; : "";
const newHtml = item.is_new
? `<span class="ffg-badge ffg-badge-new">NEW</span>`
: "";
return ` return `
<article class="ffg-card" data-url="${escapeHtml(item.store_url || "")}"> <article class="ffg-card" data-url="${escapeHtml(item.store_url || "")}">
@@ -256,6 +266,7 @@ function gameCard(item) {
${imageHtml} ${imageHtml}
<span class="ffg-badge ffg-badge-platform ${platformClass(item.platform)}">${platformLabel(item.platform)}</span> <span class="ffg-badge ffg-badge-platform ${platformClass(item.platform)}">${platformLabel(item.platform)}</span>
<span class="ffg-badge ffg-badge-free">FREE</span> <span class="ffg-badge ffg-badge-free">FREE</span>
${newHtml}
</div> </div>
<div class="ffg-body"> <div class="ffg-body">
<div class="ffg-title" title="${escapeHtml(item.title)}">${escapeHtml(item.title)}</div> <div class="ffg-title" title="${escapeHtml(item.title)}">${escapeHtml(item.title)}</div>