Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/main/java/com/swyp/picke/domain/oauth/jwt/JwtFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public class JwtFilter extends OncePerRequestFilter {
"/api/v1/notices", // 공지사항
"/api/test", // 테스트용
"/result", // 공유 링크 리다이렉트
"/report", // 철학자 리포트 딥링크
"/battle", // 배틀 딥링크
"/.well-known", // Android App Links 인증
"/api/v1/resources" // 이미지, 오디오 파일 (Presigned URL)
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.swyp.picke.domain.share.controller;

import com.swyp.picke.global.common.response.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/api/v1/share")
@RequiredArgsConstructor
public class ShareApiController {

@Value("${picke.baseUrl}")
private String baseUrl;

@GetMapping("/report")
public ApiResponse<Map<String, String>> getReportShareUrl(@RequestParam Long reportId) {
String shareUrl = baseUrl + "/report/" + reportId;
return ApiResponse.onSuccess(Map.of("shareUrl", shareUrl));
}

@GetMapping("/battle")
public ApiResponse<Map<String, String>> getBattleShareUrl(@RequestParam Long battleId) {
String shareUrl = baseUrl + "/battle/" + battleId;
return ApiResponse.onSuccess(Map.of("shareUrl", shareUrl));
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,45 @@
package com.swyp.picke.domain.share.controller;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.servlet.view.RedirectView;

@Controller
public class ShareController {

@GetMapping("/result/{userId}")
public String result(@PathVariable Long userId, Model model) {
model.addAttribute("userId", userId);
return "share/result";
//출시 이후 URL 필요
@Value("${picke.store.android:https://play.google.com/store/apps/details?id=com.swyp.picke}")
private String androidStoreUrl;

@GetMapping("/report/{reportId}")
public Object report(@PathVariable Long reportId, HttpServletRequest request, Model model) {
String ua = request.getHeader("User-Agent");
if (ua == null) ua = "";
ua = ua.toLowerCase();

if (ua.contains("android")) {
return new RedirectView(androidStoreUrl);
} else {
model.addAttribute("reportId", reportId);
return "share/report";
}
}

@GetMapping("/battle/{battleId}")
public Object battle(@PathVariable Long battleId, HttpServletRequest request, Model model) {
String ua = request.getHeader("User-Agent");
if (ua == null) ua = "";
ua = ua.toLowerCase();

if (ua.contains("android")) {
return new RedirectView(androidStoreUrl);
} else {
model.addAttribute("battleId", battleId);
return "share/battle";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
"/js/**", "/css/**", "/favicon.ico",
"/api/v1/admin/login", "/api/v1/admin",
"/result/**",
"/report/**",
"/battle/**",
"/.well-known/**",
"/api/v1/resources/images/**",
"/api/v1/resources/audio/**",
"/api/v1/admob/reward/**"
Expand Down
13 changes: 13 additions & 0 deletions src/main/resources/static/.well-known/assetlinks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.picke.app",
"sha256_cert_fingerprints": [
"8C:DA:C0:E5:4A:F3:24:AE:C4:AA:37:01:76:8E:CE:DA:D4:EE:0A:CB:09:29:45:45:A8:B4:BA:A6:F8:16:E8:BF",
"17:D6:B0:C3:F7:94:09:B3:62:78:C8:9B:1B:21:D0:C7:D9:AC:E0:0E:C8:8A:B3:5A:31:78:4D:50:A9:58:FB:45"
]
}
}
]
33 changes: 33 additions & 0 deletions src/main/resources/templates/share/battle.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pické - 배틀</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700;900&display=swap" rel="stylesheet">
<style>body { font-family: 'Noto Sans KR', sans-serif; }</style>
</head>
<body class="bg-[#FDF6F0] flex items-center justify-center min-h-screen">

<div class="w-full max-w-sm mx-auto flex flex-col items-center justify-center min-h-screen px-6 text-center gap-6">
<div class="text-6xl mb-2">🦉</div>
<h1 class="text-2xl font-black text-[#7A402D]">Pické</h1>
<p class="text-gray-600 text-base leading-relaxed">
배틀에 참여하려면<br>모바일 앱에서 확인하세요.
</p>
<div class="bg-white rounded-2xl p-6 shadow-sm border border-gray-100 w-full">
<p class="text-sm text-gray-500 mb-3">앱을 설치하고 배틀에 참여해보세요</p>
<div class="flex gap-3 justify-center">
<a href="https://play.google.com/store/apps/details?id=com.swyp.picke"
target="_blank"
class="px-4 py-2 bg-[#7A402D] text-white rounded-lg text-sm font-bold">
Google Play
</a>
</div>
</div>
</div>

</body>
</html>
33 changes: 33 additions & 0 deletions src/main/resources/templates/share/report.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pické - 철학자 리포트</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700;900&display=swap" rel="stylesheet">
<style>body { font-family: 'Noto Sans KR', sans-serif; }</style>
</head>
<body class="bg-[#FDF6F0] flex items-center justify-center min-h-screen">

<div class="w-full max-w-sm mx-auto flex flex-col items-center justify-center min-h-screen px-6 text-center gap-6">
<div class="text-6xl mb-2">🦉</div>
<h1 class="text-2xl font-black text-[#7A402D]">Pické</h1>
<p class="text-gray-600 text-base leading-relaxed">
친구의 철학자 리포트를 보려면<br>모바일 앱에서 확인하세요.
</p>
<div class="bg-white rounded-2xl p-6 shadow-sm border border-gray-100 w-full">
<p class="text-sm text-gray-500 mb-3">앱을 설치하고 리포트를 확인해보세요</p>
<div class="flex gap-3 justify-center">
<a href="https://play.google.com/store/apps/details?id=com.swyp.picke"
target="_blank"
class="px-4 py-2 bg-[#7A402D] text-white rounded-lg text-sm font-bold">
Google Play
</a>
</div>
</div>
</div>

</body>
</html>
92 changes: 0 additions & 92 deletions src/main/resources/templates/share/result.html

This file was deleted.