언어 설정 화면 추가 및 언어 헤더 적용

설정에서 시스템/한국어/영어/일본어 선택을 지원한다.

선택 시 Accept-Language 헤더와 UI locale을 즉시 반영한다.

언어 변경 후 스플래시를 거쳐 메인으로 소프트 재시작한다.
This commit is contained in:
Yu Sung
2025-12-16 22:56:37 +09:00
parent b2c94a44d9
commit 0285f62ecb
22 changed files with 512 additions and 61 deletions

View File

@@ -0,0 +1,76 @@
//
// LanguageSettingsView.swift
// SodaLive
//
// Created by Junie (AI) on 2025/12/16.
//
import SwiftUI
struct LanguageSettingsView: View {
@StateObject private var viewModel = LanguageSettingsViewModel()
var body: some View {
let cardWidth = screenSize().width - 26.7
ZStack {
Color.black.ignoresSafeArea()
VStack(spacing: 0) {
DetailNavigationBar(title: String(localized: "언어 설정"))
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 0) {
// List ScrollView
// (SF Symbols) UI .
VStack(spacing: 0) {
ForEach(Array(LanguageOption.allCases.enumerated()), id: \.offset) { idx, option in
HStack(spacing: 0) {
Text(option.displayName)
.font(.custom(Font.preRegular.rawValue, size: 16))
.foregroundColor(Color.grayee)
Spacer()
if viewModel.pending == option {
Image(systemName: "checkmark")
.font(.system(size: 16, weight: .semibold))
.foregroundColor(Color.white)
}
}
.padding(.horizontal, 16.7)
.frame(height: 50)
.contentShape(Rectangle())
.onTapGesture { viewModel.select(option) }
if idx < LanguageOption.allCases.count - 1 {
Rectangle()
.frame(height: 0.3)
.foregroundColor(Color.gray90)
.padding(.leading, 16.7)
}
}
}
.frame(width: cardWidth)
.background(Color.gray22)
.cornerRadius(6.7)
.padding(.top, 26.7)
//
Button(action: {
Task { await viewModel.applyAndRestart() }
}) {
Text(String(localized: "적용"))
.font(.custom(Font.preBold.rawValue, size: 16))
.frame(width: cardWidth, height: 50)
.background(Color.button)
.cornerRadius(6.7)
.foregroundColor(.white)
}
.padding(.top, 20)
.padding(.bottom, 26.7)
}
}
}
.task { viewModel.onAppear() }
}
}
}