715 lines
26 KiB
Plaintext
715 lines
26 KiB
Plaintext
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %>
|
|
<%@ page import="org.springframework.web.util.HtmlUtils" %>
|
|
<!DOCTYPE html>
|
|
<%
|
|
String ctx = request.getContextPath();
|
|
String rawDisplayName = session.getAttribute("displayName") == null ? "" : String.valueOf(session.getAttribute("displayName"));
|
|
String creatorValue = HtmlUtils.htmlEscape(rawDisplayName);
|
|
boolean editMode = Boolean.TRUE.equals(request.getAttribute("editMode"));
|
|
String editGameId = request.getAttribute("editGameId") == null ? "" : String.valueOf(request.getAttribute("editGameId"));
|
|
String formAction = ctx + (editMode ? "/game/" + editGameId + "/edit" : "/game/new");
|
|
String pageTitle = editMode ? "게임 수정" : "신규 게임 게시";
|
|
String submitText = editMode ? "수정" : "등록";
|
|
String editGameName = HtmlUtils.htmlEscape(request.getAttribute("editGameName") == null ? "" : String.valueOf(request.getAttribute("editGameName")));
|
|
String editCreatorNote = HtmlUtils.htmlEscape(request.getAttribute("editCreatorNote") == null ? "" : String.valueOf(request.getAttribute("editCreatorNote")));
|
|
String editGitUrl = HtmlUtils.htmlEscape(request.getAttribute("editGitUrl") == null ? "" : String.valueOf(request.getAttribute("editGitUrl")));
|
|
String editWebglPath = HtmlUtils.htmlEscape(request.getAttribute("editWebglPath") == null ? "" : String.valueOf(request.getAttribute("editWebglPath")));
|
|
String editThumbnailUrl = HtmlUtils.htmlEscape(request.getAttribute("editThumbnailUrl") == null ? "" : String.valueOf(request.getAttribute("editThumbnailUrl")));
|
|
String editGameUuid = HtmlUtils.htmlEscape(request.getAttribute("editGameUuid") == null ? "" : String.valueOf(request.getAttribute("editGameUuid")));
|
|
boolean editVisible = !editMode || Boolean.TRUE.equals(request.getAttribute("editVisible"));
|
|
%>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<jsp:include page="/WEB-INF/views/theme-init.jsp"/>
|
|
<title><%= pageTitle %> | bibimbap</title>
|
|
<style>
|
|
html {
|
|
color-scheme: light;
|
|
--surface: #faf8f5;
|
|
--card-bg: #fff;
|
|
--text: #1a1a1a;
|
|
--text-muted: #5c5c5c;
|
|
--accent: #e8a54b;
|
|
--border: rgba(0, 0, 0, 0.08);
|
|
--card-media-1: #f0ebe3;
|
|
--card-media-2: #e5ddd2;
|
|
--card-media-3: #dccfb8;
|
|
--card-shadow: rgba(0, 0, 0, 0.06);
|
|
--button-text: #1a1a1a;
|
|
--field-bg: #fff;
|
|
}
|
|
html[data-theme="dark"] {
|
|
color-scheme: dark;
|
|
--surface: #121212;
|
|
--card-bg: #1e1e1e;
|
|
--text: #ece8e1;
|
|
--text-muted: #a39e96;
|
|
--border: rgba(255, 255, 255, 0.1);
|
|
--card-media-1: #2a2620;
|
|
--card-media-2: #1f1c18;
|
|
--card-media-3: #3d3528;
|
|
--card-shadow: rgba(0, 0, 0, 0.35);
|
|
--button-text: #1a1a1a;
|
|
--field-bg: #181818;
|
|
}
|
|
body {
|
|
margin: 0;
|
|
min-height: 100vh;
|
|
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans KR", sans-serif;
|
|
background: var(--surface);
|
|
color: var(--text);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.game-register-main {
|
|
width: 100%;
|
|
max-width: 72rem;
|
|
box-sizing: border-box;
|
|
margin: 0 auto;
|
|
padding: 2rem max(1rem, env(safe-area-inset-left)) 3rem max(1rem, env(safe-area-inset-right));
|
|
flex: 1;
|
|
}
|
|
.game-register-heading {
|
|
width: min(100%, 56rem);
|
|
margin: 0 auto 1rem;
|
|
}
|
|
.game-register-heading__eyebrow {
|
|
margin: 0 0 0.35rem;
|
|
font-size: 0.75rem;
|
|
font-weight: 800;
|
|
color: var(--accent);
|
|
letter-spacing: 0.02em;
|
|
}
|
|
.game-register-heading__title {
|
|
margin: 0;
|
|
font-size: 1.75rem;
|
|
line-height: 1.2;
|
|
letter-spacing: 0;
|
|
}
|
|
.game-register-layout {
|
|
width: min(100%, 56rem);
|
|
margin: 0 auto;
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) 18rem;
|
|
gap: 1rem;
|
|
align-items: start;
|
|
}
|
|
.game-register-panel,
|
|
.game-preview {
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
background: var(--card-bg);
|
|
box-shadow: 0 2px 8px var(--card-shadow);
|
|
}
|
|
.game-register-panel {
|
|
padding: 1.5rem;
|
|
}
|
|
.game-form {
|
|
display: grid;
|
|
gap: 1rem;
|
|
}
|
|
.game-form__grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 0.875rem;
|
|
}
|
|
.game-field {
|
|
display: grid;
|
|
gap: 0.375rem;
|
|
}
|
|
.game-field--full {
|
|
grid-column: 1 / -1;
|
|
}
|
|
.game-field__label {
|
|
font-size: 0.8125rem;
|
|
font-weight: 700;
|
|
color: var(--text);
|
|
}
|
|
.game-field__input,
|
|
.game-field__textarea {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
background: var(--field-bg);
|
|
color: var(--text);
|
|
font-size: 1rem;
|
|
}
|
|
.game-field__input {
|
|
height: 3rem;
|
|
padding: 0 0.875rem;
|
|
}
|
|
.game-file {
|
|
min-height: 3rem;
|
|
padding: 0.625rem 0.75rem;
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.75rem;
|
|
background: var(--field-bg);
|
|
color: var(--text);
|
|
cursor: pointer;
|
|
box-sizing: border-box;
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
.game-file:hover {
|
|
border-color: rgba(232, 165, 75, 0.45);
|
|
}
|
|
.game-file__action {
|
|
flex-shrink: 0;
|
|
min-height: 2rem;
|
|
border-radius: 8px;
|
|
padding: 0 0.625rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
background: rgba(232, 165, 75, 0.18);
|
|
color: var(--text);
|
|
font-size: 0.8125rem;
|
|
font-weight: 800;
|
|
}
|
|
.game-file__name {
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
color: var(--text-muted);
|
|
font-size: 0.875rem;
|
|
}
|
|
.game-file__input {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 1px;
|
|
padding: 0;
|
|
margin: -1px;
|
|
overflow: hidden;
|
|
clip: rect(0, 0, 0, 0);
|
|
border: 0;
|
|
}
|
|
.game-field__textarea {
|
|
min-height: 8rem;
|
|
resize: vertical;
|
|
padding: 0.875rem;
|
|
line-height: 1.55;
|
|
}
|
|
.game-field__input::placeholder,
|
|
.game-field__textarea::placeholder {
|
|
color: var(--text-muted);
|
|
}
|
|
.game-field__input:focus,
|
|
.game-field__textarea:focus {
|
|
outline: none;
|
|
border-color: var(--accent);
|
|
box-shadow: 0 0 0 3px rgba(232, 165, 75, 0.25);
|
|
}
|
|
.game-req {
|
|
color: var(--accent);
|
|
font-weight: 900;
|
|
margin-left: 0.15em;
|
|
}
|
|
.game-preview__label {
|
|
margin: 0;
|
|
padding: 0.875rem 1rem 0;
|
|
color: var(--text-muted);
|
|
font-size: 0.75rem;
|
|
font-weight: 900;
|
|
}
|
|
.game-check {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
font-size: 0.875rem;
|
|
color: var(--text-muted);
|
|
}
|
|
.game-check input {
|
|
width: 1rem;
|
|
height: 1rem;
|
|
accent-color: var(--accent);
|
|
}
|
|
.game-form__actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 0.625rem;
|
|
}
|
|
.game-button {
|
|
min-height: 2.875rem;
|
|
border: 1px solid var(--border);
|
|
border-radius: 10px;
|
|
padding: 0 1rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.5rem;
|
|
background: var(--card-bg);
|
|
color: var(--text);
|
|
font-size: 0.9375rem;
|
|
font-weight: 800;
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
box-sizing: border-box;
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
.game-button:hover {
|
|
border-color: rgba(232, 165, 75, 0.45);
|
|
box-shadow: 0 4px 12px var(--card-shadow);
|
|
}
|
|
.game-button:active {
|
|
transform: scale(0.98);
|
|
}
|
|
.game-button--primary {
|
|
border-color: transparent;
|
|
background: var(--accent);
|
|
color: var(--button-text);
|
|
}
|
|
.game-button:disabled {
|
|
cursor: not-allowed;
|
|
opacity: 0.58;
|
|
box-shadow: none;
|
|
}
|
|
.game-button svg {
|
|
width: 1.125rem;
|
|
height: 1.125rem;
|
|
}
|
|
.game-preview {
|
|
overflow: hidden;
|
|
position: sticky;
|
|
top: 5rem;
|
|
}
|
|
.game-preview__media {
|
|
position: relative;
|
|
width: 100%;
|
|
aspect-ratio: 4 / 5;
|
|
background: linear-gradient(160deg, var(--card-media-1) 0%, var(--card-media-2) 45%, var(--card-media-3) 100%);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 14%;
|
|
box-sizing: border-box;
|
|
}
|
|
.game-preview__media img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
position: absolute;
|
|
inset: 0;
|
|
}
|
|
.game-preview__media img[hidden] {
|
|
display: none;
|
|
}
|
|
.game-preview__fallback {
|
|
width: min(52%, 7.5rem);
|
|
height: auto;
|
|
opacity: 0.88;
|
|
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.12));
|
|
}
|
|
html[data-theme="dark"] .game-preview__fallback {
|
|
opacity: 0.92;
|
|
filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.45));
|
|
}
|
|
.game-preview__body {
|
|
padding: 0.875rem 1rem 1rem;
|
|
}
|
|
.game-preview__name {
|
|
margin: 0;
|
|
font-size: 1rem;
|
|
line-height: 1.35;
|
|
letter-spacing: 0;
|
|
word-break: break-word;
|
|
}
|
|
.game-preview__creator,
|
|
.game-preview__note {
|
|
margin: 0.35rem 0 0;
|
|
color: var(--text-muted);
|
|
font-size: 0.8125rem;
|
|
line-height: 1.45;
|
|
word-break: break-word;
|
|
}
|
|
.game-preview__note {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 4;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
@media (max-width: 900px) {
|
|
.game-register-layout {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
.game-preview {
|
|
position: static;
|
|
width: min(100%, 24rem);
|
|
}
|
|
}
|
|
@media (max-width: 560px) {
|
|
.game-register-main {
|
|
padding-top: 1.5rem;
|
|
}
|
|
.game-register-panel {
|
|
padding: 1.25rem;
|
|
}
|
|
.game-form__grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
.game-form__actions {
|
|
flex-direction: column-reverse;
|
|
}
|
|
.game-button {
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<jsp:include page="/WEB-INF/views/header.jsp"/>
|
|
<main class="game-register-main">
|
|
<section class="game-register-heading" aria-labelledby="game-register-title">
|
|
<p class="game-register-heading__eyebrow">BIBIMBAP GAME</p>
|
|
<h1 class="game-register-heading__title" id="game-register-title"><%= pageTitle %></h1>
|
|
</section>
|
|
|
|
<div class="game-register-layout">
|
|
<section class="game-register-panel" aria-label="게임 등록 양식">
|
|
<form class="game-form" action="<%= formAction %>" method="post" id="game-register-form" data-edit-mode="<%= editMode %>">
|
|
<div class="game-form__grid">
|
|
<div class="game-field game-field--full">
|
|
<label class="game-field__label" for="game-name">게임 이름 <span class="game-req">*</span></label>
|
|
<input class="game-field__input" type="text" id="game-name" name="name" maxlength="80" autocomplete="off" value="<%= editGameName %>" required />
|
|
</div>
|
|
<div class="game-field">
|
|
<label class="game-field__label" for="game-git-url">소스 코드 URL</label>
|
|
<input class="game-field__input" type="url" id="game-git-url" name="gitUrl" placeholder="https://example.com/repository" autocomplete="url" value="<%= editGitUrl %>" />
|
|
</div>
|
|
<div class="game-field">
|
|
<label class="game-field__label" for="game-webgl-zip">WebGL zip <% if (!editMode) { %><span class="game-req">*</span><% } %></label>
|
|
<label class="game-file" for="game-webgl-zip">
|
|
<span class="game-file__action">zip 선택</span>
|
|
<span class="game-file__name" id="game-webgl-file-name"><%= editMode && !editWebglPath.isBlank() ? "기존 WebGL 유지" : "선택된 파일 없음" %></span>
|
|
</label>
|
|
<input class="game-file__input" type="file" id="game-webgl-zip" name="webglZip" accept=".zip,application/zip,application/x-zip-compressed" <%= editMode ? "" : "required" %> />
|
|
</div>
|
|
<div class="game-field">
|
|
<label class="game-field__label" for="game-thumbnail-image">썸네일 이미지</label>
|
|
<label class="game-file" for="game-thumbnail-image">
|
|
<span class="game-file__action">이미지 선택</span>
|
|
<span class="game-file__name" id="game-thumbnail-file-name"><%= editMode && !editThumbnailUrl.isBlank() ? "기존 썸네일 유지" : "선택된 파일 없음" %></span>
|
|
</label>
|
|
<input class="game-file__input" type="file" id="game-thumbnail-image" name="thumbnailImage" accept="image/png,image/jpeg,image/webp,image/gif" />
|
|
</div>
|
|
<div class="game-field game-field--full">
|
|
<label class="game-field__label" for="game-creator-note">소개</label>
|
|
<textarea class="game-field__textarea" id="game-creator-note" name="creatorNote" maxlength="600"><%= editCreatorNote %></textarea>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" id="game-uploaded-game-uuid" name="gameUuid" value="<%= editGameUuid %>" />
|
|
<input type="hidden" id="game-uploaded-webgl-path" name="webglPath" value="<%= editWebglPath %>" />
|
|
<input type="hidden" id="game-uploaded-thumbnail-url" name="thumbnailUrl" value="<%= editThumbnailUrl %>" />
|
|
|
|
<label class="game-check">
|
|
<input type="checkbox" name="visible" value="true" <%= editVisible ? "checked" : "" %> />
|
|
<span>목록에 공개</span>
|
|
</label>
|
|
|
|
<div class="game-form__actions">
|
|
<a class="game-button" href="<%= editMode ? ctx + "/game/" + editGameId : ctx + "/" %>">취소</a>
|
|
<button class="game-button game-button--primary" type="submit" id="game-register-submit">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
<path d="M12 5v14"/>
|
|
<path d="M5 12h14"/>
|
|
</svg>
|
|
<span id="game-register-submit-label"><%= submitText %></span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
|
|
<aside class="game-preview" aria-label="미리보기">
|
|
<p class="game-preview__label">미리보기</p>
|
|
<div class="game-preview__media">
|
|
<% if (editThumbnailUrl.isBlank()) { %>
|
|
<img id="preview-thumb" alt="" hidden />
|
|
<% } else { %>
|
|
<img id="preview-thumb" src="<%= ctx + editThumbnailUrl %>" alt="" />
|
|
<% } %>
|
|
<img class="game-preview__fallback" id="preview-fallback" src="<%= ctx %>/images/logo.png" alt="" width="120" height="120" <%= editThumbnailUrl.isBlank() ? "" : "hidden" %> />
|
|
</div>
|
|
<div class="game-preview__body">
|
|
<h2 class="game-preview__name" id="preview-name"><%= editGameName.isBlank() ? "게임 이름" : editGameName %></h2>
|
|
<p class="game-preview__creator" id="preview-creator"><%= creatorValue.isBlank() ? "제작자" : creatorValue %></p>
|
|
<p class="game-preview__note" id="preview-note"><%= editCreatorNote.isBlank() ? "소개" : editCreatorNote %></p>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
</main>
|
|
<jsp:include page="/WEB-INF/views/footer.jsp"/>
|
|
<script>
|
|
(function () {
|
|
var ctx = '<%= ctx %>';
|
|
var form = document.getElementById('game-register-form');
|
|
var editMode = form && form.getAttribute('data-edit-mode') === 'true';
|
|
var nameInput = document.getElementById('game-name');
|
|
var gitUrlInput = document.getElementById('game-git-url');
|
|
var noteInput = document.getElementById('game-creator-note');
|
|
var webglInput = document.getElementById('game-webgl-zip');
|
|
var thumbnailInput = document.getElementById('game-thumbnail-image');
|
|
var webglFileName = document.getElementById('game-webgl-file-name');
|
|
var thumbnailFileName = document.getElementById('game-thumbnail-file-name');
|
|
var uploadedGameUuid = document.getElementById('game-uploaded-game-uuid');
|
|
var uploadedWebglPath = document.getElementById('game-uploaded-webgl-path');
|
|
var uploadedThumbnailUrl = document.getElementById('game-uploaded-thumbnail-url');
|
|
var visibleInput = form ? form.querySelector('input[name="visible"]') : null;
|
|
var submitBtn = document.getElementById('game-register-submit');
|
|
var submitLabel = document.getElementById('game-register-submit-label');
|
|
var previewName = document.getElementById('preview-name');
|
|
var previewNote = document.getElementById('preview-note');
|
|
var previewThumb = document.getElementById('preview-thumb');
|
|
var previewFallback = document.getElementById('preview-fallback');
|
|
var thumbnailPreviewUrl = null;
|
|
var submitText = submitLabel ? submitLabel.textContent : '';
|
|
|
|
function valueOr(input, fallback) {
|
|
var value = input && input.value ? input.value.trim() : '';
|
|
return value || fallback;
|
|
}
|
|
|
|
function updatePreview() {
|
|
previewName.textContent = valueOr(nameInput, '게임 이름');
|
|
previewNote.textContent = valueOr(noteInput, '소개');
|
|
}
|
|
|
|
function setThumbnailPreview(file) {
|
|
if (thumbnailPreviewUrl) {
|
|
URL.revokeObjectURL(thumbnailPreviewUrl);
|
|
thumbnailPreviewUrl = null;
|
|
}
|
|
if (file) {
|
|
thumbnailPreviewUrl = URL.createObjectURL(file);
|
|
previewThumb.src = thumbnailPreviewUrl;
|
|
previewThumb.hidden = false;
|
|
if (previewFallback) {
|
|
previewFallback.hidden = true;
|
|
}
|
|
} else {
|
|
previewThumb.removeAttribute('src');
|
|
previewThumb.hidden = true;
|
|
if (previewFallback) {
|
|
previewFallback.hidden = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
function openModal(title, message, confirmText, onConfirm) {
|
|
if (window.BibimbapModal && typeof window.BibimbapModal.alert === 'function') {
|
|
window.BibimbapModal.alert({
|
|
title: title,
|
|
message: message,
|
|
confirmText: confirmText || '확인',
|
|
onConfirm: onConfirm
|
|
});
|
|
return;
|
|
}
|
|
alert(message);
|
|
if (typeof onConfirm === 'function') {
|
|
onConfirm();
|
|
}
|
|
}
|
|
|
|
function setSubmitting(submitting) {
|
|
if (!submitBtn) return;
|
|
submitBtn.disabled = submitting;
|
|
if (submitLabel) {
|
|
submitLabel.textContent = submitting ? (editMode ? '수정 중...' : '등록 중...') : submitText;
|
|
}
|
|
}
|
|
|
|
function uploadFile(url, file, fields) {
|
|
var body = new FormData();
|
|
body.append('file', file);
|
|
if (fields) {
|
|
Object.keys(fields).forEach(function (key) {
|
|
body.append(key, fields[key]);
|
|
});
|
|
}
|
|
return fetch(url, {
|
|
method: 'POST',
|
|
headers: window.BibimbapCsrf ? window.BibimbapCsrf.headers({
|
|
'Accept': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}) : {
|
|
'Accept': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: body
|
|
}).catch(function () {
|
|
throw new Error('Upload request failed before receiving a server response. Please check the server console and browser Network tab.');
|
|
}).then(function (res) {
|
|
return res.json().catch(function () {
|
|
return { message: '파일을 업로드하지 못했습니다.' };
|
|
}).then(function (data) {
|
|
if (!res.ok) {
|
|
var error = new Error(data && data.message ? data.message : '파일을 업로드하지 못했습니다.');
|
|
error.status = res.status;
|
|
throw error;
|
|
}
|
|
return data;
|
|
});
|
|
});
|
|
}
|
|
|
|
function saveGame() {
|
|
var body = new URLSearchParams();
|
|
body.set('name', valueOr(nameInput, ''));
|
|
body.set('gitUrl', valueOr(gitUrlInput, ''));
|
|
body.set('creatorNote', valueOr(noteInput, ''));
|
|
body.set('gameUuid', valueOr(uploadedGameUuid, ''));
|
|
body.set('webglPath', valueOr(uploadedWebglPath, ''));
|
|
body.set('thumbnailUrl', valueOr(uploadedThumbnailUrl, ''));
|
|
if (visibleInput && visibleInput.checked) {
|
|
body.set('visible', visibleInput.value || 'true');
|
|
}
|
|
|
|
return fetch(form.action, {
|
|
method: 'POST',
|
|
headers: window.BibimbapCsrf ? window.BibimbapCsrf.headers({
|
|
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
'Accept': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}) : {
|
|
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
'Accept': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: body
|
|
}).then(function (res) {
|
|
return res.json().catch(function () {
|
|
return { message: '게임을 등록하지 못했습니다.' };
|
|
}).then(function (data) {
|
|
if (!res.ok) {
|
|
var error = new Error(data && data.message ? data.message : '게임을 등록하지 못했습니다.');
|
|
error.status = res.status;
|
|
throw error;
|
|
}
|
|
return data;
|
|
});
|
|
});
|
|
}
|
|
|
|
if (nameInput) nameInput.addEventListener('input', updatePreview);
|
|
if (noteInput) noteInput.addEventListener('input', updatePreview);
|
|
if (webglInput) {
|
|
webglInput.addEventListener('change', function () {
|
|
var file = webglInput.files && webglInput.files[0];
|
|
webglFileName.textContent = file ? file.name : '선택된 파일 없음';
|
|
if (uploadedWebglPath) {
|
|
uploadedWebglPath.value = '';
|
|
}
|
|
if (uploadedGameUuid) {
|
|
uploadedGameUuid.value = '';
|
|
}
|
|
});
|
|
}
|
|
if (thumbnailInput) {
|
|
thumbnailInput.addEventListener('change', function () {
|
|
var file = thumbnailInput.files && thumbnailInput.files[0];
|
|
thumbnailFileName.textContent = file ? file.name : '선택된 파일 없음';
|
|
if (uploadedThumbnailUrl) {
|
|
uploadedThumbnailUrl.value = '';
|
|
}
|
|
if (file && file.type && file.type.indexOf('image/') === 0) {
|
|
setThumbnailPreview(file);
|
|
} else {
|
|
setThumbnailPreview(null);
|
|
if (file) {
|
|
thumbnailInput.value = '';
|
|
thumbnailFileName.textContent = '선택된 파일 없음';
|
|
openModal('썸네일 선택 실패', '이미지 파일만 선택해 주세요.');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
if (previewThumb) {
|
|
previewThumb.addEventListener('error', function () {
|
|
previewThumb.removeAttribute('src');
|
|
previewThumb.hidden = true;
|
|
if (previewFallback) {
|
|
previewFallback.hidden = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
if (form) {
|
|
form.addEventListener('submit', function (ev) {
|
|
ev.preventDefault();
|
|
if (!form.checkValidity()) {
|
|
form.reportValidity();
|
|
return;
|
|
}
|
|
|
|
var webglFile = webglInput && webglInput.files ? webglInput.files[0] : null;
|
|
var thumbnailFile = thumbnailInput && thumbnailInput.files ? thumbnailInput.files[0] : null;
|
|
if (!editMode && !webglFile) {
|
|
openModal('업로드 실패', 'WebGL zip 파일을 선택해 주세요.');
|
|
return;
|
|
}
|
|
|
|
setSubmitting(true);
|
|
(webglFile ? uploadFile(ctx + '/api/game-files/webgl-zip', webglFile) : Promise.resolve({
|
|
gameUuid: uploadedGameUuid ? uploadedGameUuid.value : '',
|
|
webglPath: uploadedWebglPath ? uploadedWebglPath.value : ''
|
|
})).then(function (webglResult) {
|
|
if (uploadedGameUuid && webglResult && webglResult.gameUuid) {
|
|
uploadedGameUuid.value = webglResult.gameUuid;
|
|
}
|
|
if (uploadedWebglPath && webglResult && webglResult.webglPath) {
|
|
uploadedWebglPath.value = webglResult.webglPath;
|
|
}
|
|
if (!thumbnailFile) {
|
|
return {
|
|
webglResult: webglResult,
|
|
thumbnailResult: null
|
|
};
|
|
}
|
|
return uploadFile(ctx + '/api/game-files/thumbnail', thumbnailFile, {
|
|
gameUuid: webglResult.gameUuid
|
|
}).then(function (thumbnailResult) {
|
|
return {
|
|
webglResult: webglResult,
|
|
thumbnailResult: thumbnailResult
|
|
};
|
|
});
|
|
}).then(function (results) {
|
|
var thumbnailResult = results.thumbnailResult;
|
|
if (uploadedThumbnailUrl && thumbnailResult && thumbnailResult.thumbnailUrl) {
|
|
uploadedThumbnailUrl.value = thumbnailResult.thumbnailUrl;
|
|
}
|
|
return saveGame();
|
|
}).then(function (registerResult) {
|
|
openModal(editMode ? '게임 수정 완료' : '게임 등록 완료', editMode ? '게임이 수정되었습니다.' : '게임 등록이 완료되었습니다.', '확인', function () {
|
|
if (registerResult && registerResult.gameId) {
|
|
window.location.href = ctx + '/game/' + registerResult.gameId;
|
|
} else if (registerResult && registerResult.location) {
|
|
window.location.href = ctx + registerResult.location;
|
|
} else {
|
|
window.location.href = ctx + '/';
|
|
}
|
|
});
|
|
}).catch(function (err) {
|
|
openModal('등록 실패', err.message || '게임을 등록하지 못했습니다.', '확인', function () {
|
|
if (err.status === 401) {
|
|
window.location.href = ctx + '/login';
|
|
}
|
|
});
|
|
}).finally(function () {
|
|
setSubmitting(false);
|
|
});
|
|
});
|
|
}
|
|
|
|
updatePreview();
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|