From 8d5b169166ae984bc7f37da26bcd0d1dc04b15b2 Mon Sep 17 00:00:00 2001 From: Moyasee Date: Thu, 2 Oct 2025 21:22:09 +0300 Subject: [PATCH] Feat: updated input field design, fixed text overflow --- .../confirm-modal/confirm-modal.tsx | 13 +- .../game-details/game-details.context.tsx | 3 +- .../game-details/game-details-content.tsx | 68 +++++-- .../src/pages/game-details/game-details.scss | 185 ++++++------------ .../game-details/hero/hero-panel-actions.tsx | 32 ++- .../game-details/modals/repacks-modal.tsx | 2 +- 6 files changed, 153 insertions(+), 150 deletions(-) diff --git a/src/renderer/src/components/confirm-modal/confirm-modal.tsx b/src/renderer/src/components/confirm-modal/confirm-modal.tsx index d210c035..75a8f5c9 100644 --- a/src/renderer/src/components/confirm-modal/confirm-modal.tsx +++ b/src/renderer/src/components/confirm-modal/confirm-modal.tsx @@ -33,9 +33,18 @@ export function ConfirmModal({ }; return ( - +
- diff --git a/src/renderer/src/context/game-details/game-details.context.tsx b/src/renderer/src/context/game-details/game-details.context.tsx index 23ea3845..5be5cf98 100644 --- a/src/renderer/src/context/game-details/game-details.context.tsx +++ b/src/renderer/src/context/game-details/game-details.context.tsx @@ -201,7 +201,8 @@ export function GameDetailsContextProvider({ }, [objectId, gameTitle, dispatch]); useEffect(() => { - const state = (location && (location.state as Record)) || {}; + const state = + (location && (location.state as Record)) || {}; if (state.openRepacks) { setShowRepacksModal(true); try { diff --git a/src/renderer/src/pages/game-details/game-details-content.tsx b/src/renderer/src/pages/game-details/game-details-content.tsx index de66e5a6..bb6c2e85 100644 --- a/src/renderer/src/pages/game-details/game-details-content.tsx +++ b/src/renderer/src/pages/game-details/game-details-content.tsx @@ -104,6 +104,8 @@ export function GameDetailsContent() { const [reviewsLoading, setReviewsLoading] = useState(false); const [reviewScore, setReviewScore] = useState(5); const [submittingReview, setSubmittingReview] = useState(false); + const [reviewCharCount, setReviewCharCount] = useState(0); + const MAX_REVIEW_CHARS = 1000; const [reviewsSortBy, setReviewsSortBy] = useState("newest"); const [reviewsPage, setReviewsPage] = useState(0); const [hasMoreReviews, setHasMoreReviews] = useState(true); @@ -127,6 +129,31 @@ export function GameDetailsContent() { class: "game-details__review-editor", "data-placeholder": t("write_review_placeholder"), }, + handlePaste: (view, event) => { + // Strip formatting from pasted content to prevent overflow issues + const text = event.clipboardData?.getData('text/plain') || ''; + const currentText = view.state.doc.textContent; + const remainingChars = MAX_REVIEW_CHARS - currentText.length; + + if (text && remainingChars > 0) { + event.preventDefault(); + const truncatedText = text.slice(0, remainingChars); + view.dispatch(view.state.tr.insertText(truncatedText)); + return true; + } + return false; + }, + }, + onUpdate: ({ editor }) => { + const text = editor.getText(); + setReviewCharCount(text.length); + + // Prevent typing beyond character limit + if (text.length > MAX_REVIEW_CHARS) { + const truncatedContent = text.slice(0, MAX_REVIEW_CHARS); + editor.commands.setContent(truncatedContent); + setReviewCharCount(MAX_REVIEW_CHARS); + } }, }); @@ -266,7 +293,7 @@ export function GameDetailsContent() { console.log("reviewScore:", reviewScore); console.log("submittingReview:", submittingReview); - if (!objectId || !reviewHtml.trim() || submittingReview) { + if (!objectId || !reviewHtml.trim() || submittingReview || reviewCharCount > MAX_REVIEW_CHARS) { console.log("Early return - validation failed"); return; } @@ -523,11 +550,7 @@ export function GameDetailsContent() {
- -
+
- - +
+ MAX_REVIEW_CHARS ? "over-limit" : ""}> + {reviewCharCount}/{MAX_REVIEW_CHARS} + +
+
@@ -599,6 +619,18 @@ export function GameDetailsContent() {
+ +
diff --git a/src/renderer/src/pages/game-details/game-details.scss b/src/renderer/src/pages/game-details/game-details.scss index da3745e9..e9e94aea 100644 --- a/src/renderer/src/pages/game-details/game-details.scss +++ b/src/renderer/src/pages/game-details/game-details.scss @@ -30,12 +30,8 @@ $hero-height: 300px; &__review-form { display: flex; flex-direction: column; - gap: calc(globals.$spacing-unit * 2); - margin-bottom: calc(globals.$spacing-unit * 3); - padding: calc(globals.$spacing-unit * 2); - background: rgba(255, 255, 255, 0.02); - border-radius: 8px; - border: 1px solid rgba(255, 255, 255, 0.05); + gap: 16px; + margin-bottom: 24px; } &__review-form-controls { @@ -54,55 +50,35 @@ $hero-height: 300px; &__review-form-bottom { display: flex; justify-content: space-between; - align-items: flex-end; - gap: calc(globals.$spacing-unit * 2); - - @media (max-width: 768px) { - flex-direction: column; - align-items: stretch; - gap: calc(globals.$spacing-unit * 1.5); - } + align-items: center; + gap: 16px; + flex-wrap: wrap; } &__review-score-container { display: flex; - flex-direction: column; - gap: calc(globals.$spacing-unit * 0.75); - min-width: 120px; + align-items: center; + gap: 8px; } &__review-score-label { - display: block; - font-size: globals.$body-font-size; - color: globals.$body-color; + font-size: 14px; + color: #ffffff; + font-weight: 500; } &__review-score-select { - background-color: rgba(255, 255, 255, 0.05); - border: 1px solid globals.$border-color; + background-color: #2a2a2a; + border: 1px solid #3a3a3a; border-radius: 4px; - padding: calc(globals.$spacing-unit * 0.75) calc(globals.$spacing-unit * 1); - color: globals.$body-color; - font-size: globals.$body-font-size; - font-family: inherit; + color: #ffffff; + padding: 6px 12px; + font-size: 14px; cursor: pointer; - transition: - border-color 0.2s ease, - background-color 0.2s ease; &:focus { outline: none; - background-color: rgba(255, 255, 255, 0.08); - border-color: globals.$brand-teal; - } - - &:hover { - border-color: rgba(255, 255, 255, 0.15); - } - - option { - background-color: globals.$dark-background-color; - color: globals.$body-color; + border-color: #0078d4; } } @@ -150,19 +126,14 @@ $hero-height: 300px; &__review-submit-button { background-color: rgba(255, 255, 255, 0.05); - border: 1px solid globals.$border-color; - color: globals.$body-color; - padding: calc(globals.$spacing-unit * 0.75) - calc(globals.$spacing-unit * 1.5); + border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 6px; + color: #ffffff; + padding: 10px 20px; + font-size: 14px; + font-weight: 500; cursor: pointer; - font-size: globals.$small-font-size; - font-family: inherit; - transition: all ease 0.2s; - height: 32px; - display: flex; - align-items: center; - justify-content: center; + transition: all 0.2s ease; white-space: nowrap; &:hover:not(:disabled) { @@ -170,12 +141,8 @@ $hero-height: 300px; border-color: rgba(255, 255, 255, 0.15); } - &:active { - opacity: 0.9; - } - &:disabled { - background: rgba(255, 255, 255, 0.1); + background-color: rgba(255, 255, 255, 0.1); cursor: not-allowed; color: rgba(255, 255, 255, 0.5); } @@ -918,111 +885,87 @@ $hero-height: 300px; } &__review-input-container { - width: 100%; - position: relative; + display: flex; + flex-direction: column; + border: 1px solid #3a3a3a; + border-radius: 8px; + background-color: #1e1e1e; + overflow: hidden; } - &__review-input-bottom { - position: absolute; - bottom: 8px; - left: 8px; - right: 8px; + &__review-input-header { display: flex; justify-content: space-between; align-items: center; - gap: 8px; - z-index: 10; + padding: 8px 12px; + background-color: #2a2a2a; + border-bottom: 1px solid #3a3a3a; } &__review-editor-toolbar { display: flex; gap: 4px; - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 4px; - padding: 4px; - backdrop-filter: blur(10px); - background: rgba(0, 0, 0, 0.3); } &__editor-button { - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 3px; - color: globals.$body-color; - padding: 4px 6px; + background: none; + border: 1px solid #4a4a4a; + border-radius: 4px; + color: #ffffff; + padding: 4px 8px; cursor: pointer; font-size: 12px; - font-weight: 600; transition: all 0.2s ease; - min-width: 24px; - height: 24px; - display: flex; - align-items: center; - justify-content: center; - &:hover:not(:disabled) { - background: rgba(255, 255, 255, 0.1); - border-color: rgba(255, 255, 255, 0.2); + &:hover { + background-color: #3a3a3a; + border-color: #5a5a5a; + } + + &.is-active { + background-color: #0078d4; + border-color: #0078d4; } &:disabled { opacity: 0.5; cursor: not-allowed; } + } - &.is-active { - background: globals.$brand-teal; - border-color: globals.$brand-teal; - color: white; + &__review-char-counter { + font-size: 12px; + color: #888888; + + .over-limit { + color: #ff6b6b; } } &__review-input { - width: 100%; - background-color: rgba(255, 255, 255, 0.05); - border: 1px solid globals.$border-color; - border-radius: 6px; - padding: calc(globals.$spacing-unit * 1.5); - padding-bottom: calc(globals.$spacing-unit * 3.5); - color: globals.$body-color; - font-size: globals.$body-font-size; - font-family: inherit; - line-height: 1.5; - min-height: 100px; - transition: - border-color 0.2s ease, - background-color 0.2s ease; - - &:focus-within { - outline: none; - background-color: rgba(255, 255, 255, 0.08); - border-color: globals.$brand-teal; - } - - &:hover { - border-color: rgba(255, 255, 255, 0.15); - } - + min-height: 120px; + padding: 12px; + .ProseMirror { outline: none; - min-height: 80px; - - &:empty:before { - content: attr(data-placeholder); - color: rgba(208, 209, 215, 0.6); - pointer-events: none; + color: #ffffff; + font-size: 14px; + line-height: 1.5; + + &:focus { + outline: none; } p { margin: 0 0 8px 0; - + &:last-child { margin-bottom: 0; } } strong { - font-weight: 700; + font-weight: bold; } em { diff --git a/src/renderer/src/pages/game-details/hero/hero-panel-actions.tsx b/src/renderer/src/pages/game-details/hero/hero-panel-actions.tsx index ac8a1615..e23120a8 100644 --- a/src/renderer/src/pages/game-details/hero/hero-panel-actions.tsx +++ b/src/renderer/src/pages/game-details/hero/hero-panel-actions.tsx @@ -69,14 +69,32 @@ export function HeroPanelActions() { updateGame(); }; - window.addEventListener("hydra:game-favorite-toggled", onFavoriteToggled as EventListener); - window.addEventListener("hydra:game-removed-from-library", onGameRemoved as EventListener); - window.addEventListener("hydra:game-files-removed", onFilesRemoved as EventListener); + window.addEventListener( + "hydra:game-favorite-toggled", + onFavoriteToggled as EventListener + ); + window.addEventListener( + "hydra:game-removed-from-library", + onGameRemoved as EventListener + ); + window.addEventListener( + "hydra:game-files-removed", + onFilesRemoved as EventListener + ); return () => { - window.removeEventListener("hydra:game-favorite-toggled", onFavoriteToggled as EventListener); - window.removeEventListener("hydra:game-removed-from-library", onGameRemoved as EventListener); - window.removeEventListener("hydra:game-files-removed", onFilesRemoved as EventListener); + window.removeEventListener( + "hydra:game-favorite-toggled", + onFavoriteToggled as EventListener + ); + window.removeEventListener( + "hydra:game-removed-from-library", + onGameRemoved as EventListener + ); + window.removeEventListener( + "hydra:game-files-removed", + onFilesRemoved as EventListener + ); }; }, [updateLibrary, updateGame]); @@ -226,7 +244,7 @@ export function HeroPanelActions() { onClick={() => setShowRepacksModal(true)} theme="outline" disabled={isGameDownloading} - className={`hero-panel-actions__action ${!repacks.length ? 'hero-panel-actions__action--disabled' : ''}`} + className={`hero-panel-actions__action ${!repacks.length ? "hero-panel-actions__action--disabled" : ""}`} > {t("download")} diff --git a/src/renderer/src/pages/game-details/modals/repacks-modal.tsx b/src/renderer/src/pages/game-details/modals/repacks-modal.tsx index ec7dc3f8..97b8b1b5 100644 --- a/src/renderer/src/pages/game-details/modals/repacks-modal.tsx +++ b/src/renderer/src/pages/game-details/modals/repacks-modal.tsx @@ -277,4 +277,4 @@ export function RepacksModal({ ); -} \ No newline at end of file +}