diff --git a/app/Console/Commands/FixEntriesEncodedDescription.php b/app/Console/Commands/FixEntriesEncodedDescription.php new file mode 100644 index 0000000..410ad0b --- /dev/null +++ b/app/Console/Commands/FixEntriesEncodedDescription.php @@ -0,0 +1,65 @@ +option('dry-run'); + $fixed = 0; + + Entry::withTrashed() + ->withoutGlobalScopes() + ->chunkById(100, function ($entries) use (&$fixed, $dryRun) { + foreach ($entries as $entry) { + $original = $entry->description; + if ($original === null || $original === '') { + continue; + } + + $decoded = $original; + for ($i = 0; $i < 20; $i++) { + $next = html_entity_decode($decoded, ENT_QUOTES | ENT_HTML5); + if ($next === $decoded) { + break; + } + $decoded = $next; + } + + $decoded = stripslashes($decoded); + + if ($decoded !== $original) { + $fixed++; + $this->line("Entry #{$entry->id}: " . $this->preview($original) . ' => ' . $this->preview($decoded)); + + if (!$dryRun) { + $entry->description = $decoded; + $entry->saveQuietly(); + } + } + } + }); + + $this->info(($dryRun ? '[DRY RUN] ' : '') . "{$fixed} entries fixed.)."); + + return self::SUCCESS; + } + + private function preview(string $text, int $len = 60): string + { + $text = str_replace(["\n", "\r"], ' ', $text); + return mb_strlen($text) > $len ? mb_substr($text, 0, $len) . '...' : $text; + } + +} diff --git a/extra.less b/extra.less index cfdded9..c5b85b2 100644 --- a/extra.less +++ b/extra.less @@ -10,7 +10,8 @@ body { background-color: var(--bg); color: var(--text); display: flex; - height: 100vh; + height: 100dvh; + min-height: 100dvh; overflow: hidden; } @@ -136,6 +137,7 @@ ul { border: 1px solid var(--border); display: flex; min-width: 0; + max-width: 100%; flex-direction: column; transition: transform 0.2s, border-color 0.2s; cursor: pointer; @@ -178,6 +180,7 @@ ul { .\$entry-card-info { padding: 15px; flex-grow: 1; + min-width: 0; display: flex; flex-direction: column; } @@ -188,13 +191,16 @@ ul { font-size: 1.1rem; margin-bottom: 5px; line-height: 1.3; - word-wrap: break-word; + overflow-wrap: anywhere; + word-break: break-word; } .\$entry-card-author { color: var(--rhpz-orange); font-size: 0.85rem; margin-bottom: 10px; + overflow-wrap: anywhere; + word-break: break-word; } .\$entry-card-meta { @@ -254,6 +260,9 @@ ul { .\$entry-card-meta { font-size: 0.75rem; + flex-direction: column; + align-items: flex-start; + gap: 6px; } } @@ -334,6 +343,45 @@ ul { background-color: rgba(129, 199, 132, 0.1); } +.\$back-to-top { + display: none; +} + +@media (max-width: 768px) { + .\$back-to-top { + display: none; + align-items: center; + justify-content: center; + gap: 8px; + position: fixed; + right: 14px; + bottom: 14px; + z-index: 1000; + padding: 10px 14px; + border-radius: 999px; + background-color: var(--bg2); + border: 1px solid var(--border); + color: var(--text); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2); + opacity: 0; + pointer-events: none; + transform: translateY(10px); + transition: opacity 0.2s ease, transform 0.2s ease; + } + + .\$back-to-top.visible { + display: inline-flex; + opacity: 1; + pointer-events: auto; + transform: translateY(0); + } + + .\$back-to-top span { + font-size: 0.78rem; + font-weight: 600; + } +} + /* BLOCK */ .\$block { @@ -385,21 +433,36 @@ ul { color: var(--text3); border-color: var(--rhpz-orange); } -.\$badge.blue, .\$badge.translations { +.\$badge.blue, .\$badge.romhacks { background-color: var(--info); color: var(--text); border-color: var(--info); } -.\$badge.green, .\$badge.romhacks { +.\$badge.green, .\$badge.translations { background-color: var(--success2); color: var(--text); border-color: var(--success2); } +.\$badge.red, .\$badge.homebrew { + background-color: #bf2323; + color: var(--text); + border-color: #bf2323; +} .\$badge.yellow, .\$badge.utilities { background-color: #fdeb0f; color: #000; border-color: #fdeb0f; } +.\$badge.purple, .\$badge.documents{ + background-color: #8b23bf; + color: var(--text); + border-color: #8b23bf; +} +.\$badge.brown, .\$badge.lua-scripts { + background-color: #b4825f; + color: var(--text); + border-color: #b4825f; +} .\$topbar-badge { position: absolute; @@ -575,448 +638,6 @@ ul { } -/* File: resources/css/components/database.css */ -.\$filter-bar { - display: flex; - gap: 15px; - background-color: var(--bg2); - padding: 15px; - border: 1px solid var(--border); - margin-bottom: 20px; - flex-wrap: wrap; - align-items: center; - - .\$filter-bar-search { - flex: 1; - max-width: 400px; - background-color: var(--bg); - border: 1px solid var(--border); - display: flex; - align-items: center; - padding: 8px 12px; - gap: 8px; - - } -} - -.\$database-wrapper { - display: flex; - gap: 20px; - align-items: flex-start; - - .\$database-filters { - width: 300px; - flex-shrink: 0; - display: flex; - flex-direction: column; - gap: 2px; - background-color: var(--bg2); - border: 1px solid var(--border); - - .\$filter-group { - border-bottom: 1px solid var(--border); - overflow: hidden; - &:last-child { - border-bottom: none; - } - } - - .\$filter-title-row { - display: flex; - align-items: center; - justify-content: space-between; - padding: 10px 14px; - background-color: var(--bg3); - cursor: pointer; - user-select: none; - - .\$filter-title { - font-size: 0.8rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.8px; - color: var(--text2); - margin: 0; - } - - } - - .\$filter-mode { - display: flex; - gap: 4px; - } - - .\$filter-btn-mode { - background: none; - border: 1px solid var(--border); - color: var(--text2); - font-size: 0.7rem; - font-weight: 600; - padding: 2px 7px; - cursor: pointer; - font-family: var(--typography); - transition: all 0.15s; - letter-spacing: 0.5px; - &:hover { - border-color: var(--rhpz-orange); - color: var(--rhpz-orange); - } - &.\$active { - background-color: var(--rhpz-orange); - border-color: var(--rhpz-orange); - color: var(--text3); - } - } - - .\$filter-options { - padding: 6px 0; - max-height: 180px; - overflow-y: auto; - &::-webkit-scrollbar { - width: 6px; - } - &::-webkit-scrollbar-track { - background: var(--bg2); - } - &::-webkit-scrollbar-thumb { - background: var(--border); - } - } - - .\$filter-option { - display: flex; - align-items: center; - gap: 9px; - padding: 6px 14px; - font-size: 0.88rem; - color: var(--text); - cursor: pointer; - transition: background-color 0.1s; - &:hover { - background-color: var(--bg4); - } - } - - .\$filter-option input[type="checkbox"] { - accent-color: var(--rhpz-orange); - width: 14px; - height: 14px; - cursor: pointer; - flex-shrink: 0; - } - - } - - .\$database-results { - flex: 1; - min-width: 0; - - .\$database-sort { - display: flex; - align-items: center; - gap: 8px; - margin-bottom: 15px; - padding-bottom: 15px; - border-bottom: 1px solid var(--border); - flex-wrap: wrap; - - .\$btn { - font-size: 0.85rem; - padding: 6px 12px; - &.\$active { - border-color: var(--rhpz-orange); - color: var(--rhpz-orange); - } - } - - } - - .\$database-results-count { - margin-left: auto; - font-size: 0.85rem; - color: var(--text2); - } - - .\$database-active-filters { - display: flex; - flex-wrap: wrap; - gap: 6px; - margin-bottom: 15px; - } - - .\$database-active-filter-tag { - display: inline-flex; - align-items: center; - gap: 6px; - background-color: var(--bg3); - border: 1px solid var(--border); - padding: 3px 10px; - font-size: 0.8rem; - color: var(--text); - .\$tag-type { - color: var(--rhpz-orange); - font-weight: 600; - font-size: 0.75rem; - text-transform: uppercase; - letter-spacing: 0.5px; - } - button { - background: none; - border: none; - color: var(--text2); - cursor: pointer; - padding: 0; - display: flex; - align-items: center; - transition: color 0.15s; - &:hover { - color: var(--text); - } - } - } - - .\$database-empty { - grid-column: 1 / -1; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 60px 20px; - color: var(--text2); - background-color: var(--bg2); - border: 1px solid var(--border); - gap: 15px; - text-align: center; - - i { - color: var(--border); - } - - p { - font-size: 0.95rem; - } - } - - } - -} - -.\$database-pagination { - display: flex; - justify-content: center; - align-items: center; - gap: 4px; - margin-top: 20px; - - .\$btn { - min-width: 36px; - padding: 6px 10px; - font-size: 0.85rem; - display: flex; - align-items: center; - justify-content: center; - } - - .\$active { - background-color: var(--rhpz-orange); - border-color: var(--rhpz-orange); - color: #111; - font-weight: 600; - } -} - -.\$database-search { - display: flex; - align-items: center; - gap: 10px; - margin-bottom: 20px; -} - -@media (max-width: 900px) { - .\$database-layout { - flex-direction: column; - } - - .\$database-wrapper { - flex-direction: column; - } - - .\$database-filters { - width: 100%; - display: grid; - grid-template-columns: repeat(2,1fr); - } - - .\$database-filter-group:last-child { - border-bottom: 1px solid var(--border); - } - - .\$database-results-count { - margin-left: 0; - width: 100%; - } -} - -@media (max-width: 768px) { - .\$database-search { - gap: 8px; - margin-bottom: 15px; - flex-wrap: wrap; - } - - .\$database-wrapper { - flex-direction: column; - gap: 15px; - } - - .\$database-filters { - width: 100%; - grid-template-columns: 1fr; - order: -1; - margin-bottom: 10px; - } - - .\$database-filter-group { - padding: 12px 0; - } - - .\$grid-entries { - grid-template-columns: repeat(3, 1fr); - gap: 15px; - } -} - -@media (max-width: 600px) { - .\$database-search { - flex-direction: column; - } - - .\$database-filters { - grid-template-columns: 1fr; - } - - .\$grid-entries { - grid-template-columns: repeat(2, 1fr); - gap: 12px; - } - - .\$database-filter-group { - padding: 10px 0; - } -} - -@media (max-width: 420px) { - .\$grid-entries { - grid-template-columns: 1fr; - gap: 10px; - } - - .\$database-search input { - font-size: 0.85rem; - padding: 6px 8px; - } -} - -.\$filter-chevron { - transition: transform 0.2s ease; - color: var(--text2); - flex-shrink: 0; -} - -.\$filter-chevron.rotated { - transform: rotate(-90deg); -} - -.\$internal-filter-search { - display: flex; - align-items: center; - gap: 7px; - padding: 7px 14px; - border-bottom: 1px solid var(--border); - background-color: var(--bg); - - i { - color: var(--text2); - flex-shrink: 0; - } - - input { - background: none; - border: none; - outline: none; - color: var(--text); - font-family: var(--typography); - font-size: 0.85rem; - width: 100%; - - &::placeholder { - color: var(--text2); - } - } -} - -.\$filter-title-left { - display: flex; - align-items: center; - gap: 7px; -} - -.\$filter-title-right { - display: flex; - align-items: center; - gap: 6px; -} - -.\$internal-filter-count { - display: inline-flex; - align-items: center; - justify-content: center; - background-color: var(--rhpz-orange); - color: #111; - font-size: 0.7rem; - font-weight: 700; - min-width: 18px; - height: 18px; - padding: 0 5px; - line-height: 1; -} - -.\$internal-filter-clear { - background: none; - border: 1px solid var(--border); - color: var(--text2); - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - width: 18px; - height: 18px; - padding: 0; - transition: all 0.15s; - - &:hover { - border-color: var(--error); - color: var(--error); - } -} - -.\$filter-search-clear { - background: none; - border: none; - color: var(--text2); - cursor: pointer; - display: flex; - align-items: center; - padding: 0; - flex-shrink: 0; - transition: color 0.15s; - &:hover { - color: var(--text); - } -} - - - /* File: resources/css/components/drafts.css */ .\$drafts-count { font-size: 0.85rem; @@ -1797,6 +1418,37 @@ ul { min-width: 20px; text-align: center; } + +.\$gallery-mobile-controls { + display: none; +} + +@media (max-width: 1024px) { + .\$gallery-mobile-controls { + display: flex; + justify-content: flex-end; + gap: 6px; + margin-top: 6px; + } + + .\$gallery-move-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border: 1px solid var(--border); + background-color: var(--bg2); + color: var(--text); + cursor: pointer; + padding: 0; + } + + .\$gallery-move-btn:disabled { + opacity: 0.4; + cursor: not-allowed; + } +} .\$authors-list { display: grid; grid-template-columns: repeat(4, 1fr); @@ -1914,13 +1566,30 @@ ul { } @media (max-width: 600px) { - .\$upload-item-actions { + .\$upload-item { flex-direction: column; + align-items: stretch; + } + + .\$upload-item-info { + width: 100%; + flex: 1 1 auto; + min-width: 0; + } + + .\$upload-item-actions { + flex-direction: row; + justify-content: flex-end; + align-items: center; gap: 8px; + width: 100%; + margin-top: 8px; + flex-basis: 100%; } .\$upload-item-actions .\$btn { - width: 100%; + width: auto; + flex: 0 0 auto; } } .file-state-icon { width: 18px; height: 18px; } @@ -2077,10 +1746,18 @@ ul { .\$grid-hashes { grid-template-columns: 1fr; } - + .\$grid-credits { + grid-template-columns: 1fr; + } + .\$grid-first { + display: none; + } .\$hash-first { display: none; } + .\$author-search-selected { + display: none; + } } @media (max-width: 600px) { @@ -2110,6 +1787,22 @@ ul { .\$form-error-text { font-size: 0.8rem; } + + .\$form-type-of-checkboxes { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1rem; + + label { + box-sizing: border-box; + margin: 0; + } + + input[type="checkbox"] { + transform: scale(1.5); + margin-right: 1.33rem; + } + } } @@ -2146,11 +1839,41 @@ ul { .\$grid-entries { display: grid; - grid-template-columns: repeat(6,1fr); + grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 20px; margin-bottom: 20px; } +@media (max-width: 1400px) { + .\$grid-entries { + grid-template-columns: repeat(5, minmax(0, 1fr)); + } +} + +@media (max-width: 1200px) { + .\$grid-entries { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} + +@media (max-width: 900px) { + .\$grid-entries { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} + +@media (max-width: 640px) { + .\$grid-entries { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 420px) { + .\$grid-entries { + grid-template-columns: 1fr; + } +} + /* File: resources/css/components/hovercard.css */ @@ -4024,7 +3747,7 @@ ul { .\$activity-tl-card-description { font-size: 0.8rem; color: var(--text2); - white-space: nowrap; + word-break: break-word; text-overflow: ellipsis; line-height: 1.3; } @@ -4066,13 +3789,15 @@ ul { @media (max-width: 600px) { .activity-tl-header { flex-direction: column; align-items: flex-start; } .activity-tl-thumb { display: none; } + .activity-tl-left { display: none; } + .activity-tl-card-description { display: none; } .activity-day-sep { padding-left: 44px; } .activity-tl-left { width: 44px; } - + .\$activity-tl-date { font-size: 0.75rem; } - + .\$activity-tl-content-title { font-size: 0.9rem; } @@ -4080,7 +3805,7 @@ ul { @media (max-width: 768px) { .\$activity-timeline { - padding-left: 50px; + padding-left: 0px; } .\$activity-tl-left { @@ -4362,6 +4087,7 @@ ul { display: flex; flex-direction: column; overflow: hidden; + min-height: 0; } #topbar { @@ -4674,6 +4400,30 @@ ul { line-height: 1.6; color: var(--text); margin-bottom: 30px; + word-break: break-word; + + p { + margin: 0 0 14px; + + &:last-child { + margin-bottom: 0; + } + } + + pre { + max-width: 100%; + overflow-x: auto; + white-space: pre-wrap; + word-break: break-word; + padding: 12px; + border-radius: 6px; + margin: 0 0 14px; + } + + code { + white-space: pre-wrap; + word-break: break-word; + } } .\$entry-gallery { @@ -4793,6 +4543,9 @@ ul { overflow: hidden; background-color: var(--bg4); border: 1px solid var(--border); + display: flex; + align-items: center; + justify-content: center; img { width: 100%; @@ -5175,6 +4928,7 @@ ul { flex-shrink: 0; transition: transform 0.3s ease; z-index: 100; + overflow: hidden; .\$menu-header { padding: 10px; @@ -5212,9 +4966,12 @@ ul { } .\$menu-navigation { - flex-grow: 1; + flex: 1 1 auto; + min-height: 0; padding: 10px 0; overflow-y: auto; + -webkit-overflow-scrolling: touch; + overscroll-behavior: contain; .\$menu-group { margin-bottom: 20px; @@ -5264,7 +5021,9 @@ ul { } .\$menu-user { - padding: 15px 20px; + flex-shrink: 0; + margin-top: auto; + padding: 15px 20px calc(15px + env(safe-area-inset-bottom)) 20px; border-top: 1px solid var(--border); display: flex; align-items: center; @@ -5299,6 +5058,7 @@ ul { &.\$username { font-size: 0.9rem; font-weight: 600; + text-decoration: none !important; } &.\$user_role { font-size: 0.75rem; @@ -5927,7 +5687,9 @@ ul { position: fixed; left: 0; top: 60px; - height: calc(100vh - 60px); + height: calc(100dvh - 60px); + max-height: calc(100dvh - 60px); + min-height: 0; transform: translateX(-100%); transition: transform 0.3s ease-in-out; z-index: 999; diff --git a/resources/views/news/form.blade.php b/resources/views/news/form.blade.php index c5f1c70..0480e71 100644 --- a/resources/views/news/form.blade.php +++ b/resources/views/news/form.blade.php @@ -34,7 +34,7 @@