시리즈 상세 화면 현지화 문자열 제공
시리즈 상세 화면의 탭과 섹션 제목을 다국어로 제공한다. 가격 표시와 요일 표기를 로케일에 맞게 보여준다.
This commit is contained in:
@@ -722,6 +722,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"%@ (5일)" : {
|
"%@ (5일)" : {
|
||||||
|
"extractionState" : "stale",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
@@ -753,6 +754,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"%@ %@" : {
|
||||||
|
"localizations" : {
|
||||||
|
"ko" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "new",
|
||||||
|
"value" : "%1$@ %2$@"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"%@ 님의 시리즈 전체보기" : {
|
"%@ 님의 시리즈 전체보기" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
@@ -4065,22 +4076,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"목" : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Thu"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ja" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "木"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"모집완료" : {
|
"모집완료" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
@@ -4113,6 +4108,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"목" : {
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Thu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ja" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "木"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"무료" : {
|
"무료" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
@@ -6769,6 +6780,54 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"이벤트" : {
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Events"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ja" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "イベント"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"인기 캐릭터" : {
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Popular Characters"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ja" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "人気キャラクター"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"일" : {
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Sun"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ja" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "日"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"이메일" : {
|
"이메일" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
@@ -6801,22 +6860,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"일" : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Sun"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ja" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "日"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"이미지" : {
|
"이미지" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
@@ -6849,22 +6892,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"이벤트" : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Events"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ja" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "イベント"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"이벤트 참여하기" : {
|
"이벤트 참여하기" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
@@ -6945,22 +6972,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"인기 캐릭터" : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Popular Characters"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ja" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "人気キャラクター"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"인기 캐릭터 채팅" : {
|
"인기 캐릭터 채팅" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
@@ -8513,22 +8524,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"캐릭터 정보" : {
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Character info"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ja" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "キャラクター情報"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"캔" : {
|
"캔" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
@@ -8545,6 +8540,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"캐릭터 정보" : {
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Character info"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ja" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "キャラクター情報"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"캔 충전" : {
|
"캔 충전" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ struct SeriesDetailIntroductionView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 16) {
|
VStack(alignment: .leading, spacing: 16) {
|
||||||
Text("키워드")
|
Text(I18n.SeriesDetail.keywords)
|
||||||
.font(.custom(Font.bold.rawValue, size: 14.7))
|
.font(.custom(Font.bold.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.grayee)
|
.foregroundColor(Color.grayee)
|
||||||
.padding(.top, 16)
|
.padding(.top, 16)
|
||||||
@@ -31,7 +31,7 @@ struct SeriesDetailIntroductionView: View {
|
|||||||
.foregroundColor(Color.gray22)
|
.foregroundColor(Color.gray22)
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 13.3) {
|
VStack(alignment: .leading, spacing: 13.3) {
|
||||||
Text("작품소개")
|
Text(I18n.SeriesDetail.workIntro)
|
||||||
.font(.custom(Font.bold.rawValue, size: 14.7))
|
.font(.custom(Font.bold.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.grayee)
|
.foregroundColor(Color.grayee)
|
||||||
|
|
||||||
@@ -47,37 +47,37 @@ struct SeriesDetailIntroductionView: View {
|
|||||||
.foregroundColor(Color.gray22)
|
.foregroundColor(Color.gray22)
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 16) {
|
VStack(alignment: .leading, spacing: 16) {
|
||||||
Text("상세정보")
|
Text(I18n.SeriesDetail.details)
|
||||||
.font(.custom(Font.bold.rawValue, size: 14.7))
|
.font(.custom(Font.bold.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.grayee)
|
.foregroundColor(Color.grayee)
|
||||||
|
|
||||||
HStack(spacing: 30) {
|
HStack(spacing: 30) {
|
||||||
VStack(alignment: .leading, spacing: 13.3) {
|
VStack(alignment: .leading, spacing: 13.3) {
|
||||||
Text("장르")
|
Text(I18n.SeriesDetail.genre)
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.gray77)
|
.foregroundColor(Color.gray77)
|
||||||
|
|
||||||
Text("연령제한")
|
Text(I18n.SeriesDetail.ageLimit)
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.gray77)
|
.foregroundColor(Color.gray77)
|
||||||
|
|
||||||
if let _ = seriesDetail.writer {
|
if let _ = seriesDetail.writer {
|
||||||
Text("작가")
|
Text(I18n.SeriesDetail.writer)
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.gray77)
|
.foregroundColor(Color.gray77)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let _ = seriesDetail.studio {
|
if let _ = seriesDetail.studio {
|
||||||
Text("제작사")
|
Text(I18n.SeriesDetail.studio)
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.gray77)
|
.foregroundColor(Color.gray77)
|
||||||
}
|
}
|
||||||
|
|
||||||
Text("연재")
|
Text(I18n.SeriesDetail.schedule)
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.gray77)
|
.foregroundColor(Color.gray77)
|
||||||
|
|
||||||
Text("출시일")
|
Text(I18n.SeriesDetail.releaseDate)
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.gray77)
|
.foregroundColor(Color.gray77)
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ struct SeriesDetailIntroductionView: View {
|
|||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
|
|
||||||
Text(seriesDetail.isAdult ? "19세 이상" : "전체연령가")
|
Text(seriesDetail.isAdult ? I18n.SeriesDetail.age19Plus : I18n.SeriesDetail.ageAll)
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ struct SeriesDetailIntroductionView: View {
|
|||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(seriesDetail.publishedDaysOfWeek == "랜덤" ? seriesDetail.publishedDaysOfWeek : "\(seriesDetail.publishedDaysOfWeek)")
|
Text(seriesDetail.publishedDaysOfWeek == "랜덤" ? I18n.SeriesDetail.random : "\(seriesDetail.publishedDaysOfWeek)")
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.white)
|
.foregroundColor(Color.white)
|
||||||
|
|
||||||
@@ -116,23 +116,23 @@ struct SeriesDetailIntroductionView: View {
|
|||||||
.padding(.horizontal, 13.3)
|
.padding(.horizontal, 13.3)
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 13.3) {
|
VStack(alignment: .leading, spacing: 13.3) {
|
||||||
Text("가격")
|
Text(I18n.SeriesDetail.price)
|
||||||
.font(.custom(Font.bold.rawValue, size: 14.7))
|
.font(.custom(Font.bold.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.grayee)
|
.foregroundColor(Color.grayee)
|
||||||
|
|
||||||
HStack(spacing: 30) {
|
HStack(spacing: 30) {
|
||||||
VStack(alignment: .leading, spacing: 13.3) {
|
VStack(alignment: .leading, spacing: 13.3) {
|
||||||
Text("대여")
|
Text(I18n.SeriesDetail.rentLabel)
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.gray77)
|
.foregroundColor(Color.gray77)
|
||||||
|
|
||||||
Text("소장")
|
Text(I18n.SeriesDetail.buyLabel)
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.gray77)
|
.foregroundColor(Color.gray77)
|
||||||
}
|
}
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 13.3) {
|
VStack(alignment: .leading, spacing: 13.3) {
|
||||||
Text("\(calculatePriceInfo(seriesDetail.rentalMinPrice, seriesDetail.rentalMaxPrice)) (5일)")
|
Text("\(calculatePriceInfo(seriesDetail.rentalMinPrice, seriesDetail.rentalMaxPrice)) \(I18n.SeriesDetail.daysSuffix(5))")
|
||||||
.font(.custom(Font.medium.rawValue, size: 14.7))
|
.font(.custom(Font.medium.rawValue, size: 14.7))
|
||||||
.foregroundColor(Color.button)
|
.foregroundColor(Color.button)
|
||||||
|
|
||||||
@@ -147,14 +147,6 @@ struct SeriesDetailIntroductionView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func calculatePriceInfo(_ minPrice: Int, _ maxPrice: Int) -> String {
|
func calculatePriceInfo(_ minPrice: Int, _ maxPrice: Int) -> String {
|
||||||
if minPrice == maxPrice {
|
I18n.SeriesDetail.priceInfo(min: minPrice, max: maxPrice)
|
||||||
if maxPrice == 0 {
|
|
||||||
return "무료"
|
|
||||||
} else {
|
|
||||||
return "\(maxPrice)"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "\(minPrice == 0 ? "무료" : "\(minPrice)") ~ \(maxPrice)캔"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ struct SeriesDetailView: View {
|
|||||||
|
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
SeriesDetailTabView(
|
SeriesDetailTabView(
|
||||||
title: "홈",
|
title: I18n.SeriesDetail.home,
|
||||||
width: screenSize().width / 2,
|
width: screenSize().width / 2,
|
||||||
isSelected: viewModel.currentTab == .home
|
isSelected: viewModel.currentTab == .home
|
||||||
) {
|
) {
|
||||||
@@ -184,7 +184,7 @@ struct SeriesDetailView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SeriesDetailTabView(
|
SeriesDetailTabView(
|
||||||
title: "작품소개",
|
title: I18n.SeriesDetail.introduction,
|
||||||
width: screenSize().width / 2,
|
width: screenSize().width / 2,
|
||||||
isSelected: viewModel.currentTab == .introduction
|
isSelected: viewModel.currentTab == .introduction
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -269,6 +269,60 @@ enum I18n {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 시리즈 상세 화면 관련 문자열 모음
|
||||||
|
enum SeriesDetail {
|
||||||
|
// 탭
|
||||||
|
static var home: String { pick(ko: "홈", en: "Home", ja: "ホーム") }
|
||||||
|
static var introduction: String { pick(ko: "작품소개", en: "Introduction", ja: "作品紹介") }
|
||||||
|
|
||||||
|
// 섹션 타이틀
|
||||||
|
static var keywords: String { pick(ko: "키워드", en: "Keywords", ja: "キーワード") }
|
||||||
|
static var workIntro: String { pick(ko: "작품소개", en: "Introduction", ja: "作品紹介") }
|
||||||
|
static var details: String { pick(ko: "상세정보", en: "Details", ja: "詳細情報") }
|
||||||
|
static var price: String { pick(ko: "가격", en: "Price", ja: "価格") }
|
||||||
|
|
||||||
|
// 상세 라벨
|
||||||
|
static var genre: String { pick(ko: "장르", en: "Genre", ja: "ジャンル") }
|
||||||
|
static var ageLimit: String { pick(ko: "연령제한", en: "Age rating", ja: "年齢制限") }
|
||||||
|
static var writer: String { pick(ko: "작가", en: "Writer", ja: "作家") }
|
||||||
|
static var studio: String { pick(ko: "제작사", en: "Studio", ja: "制作会社") }
|
||||||
|
static var schedule: String { pick(ko: "연재", en: "Schedule", ja: "連載") }
|
||||||
|
static var releaseDate: String { pick(ko: "출시일", en: "Release date", ja: "リリース日") }
|
||||||
|
|
||||||
|
// 가격 라벨(명사형)
|
||||||
|
static var rentLabel: String { pick(ko: "대여", en: "Rent", ja: "レンタル") }
|
||||||
|
static var buyLabel: String { pick(ko: "소장", en: "Buy", ja: "購入") }
|
||||||
|
|
||||||
|
// 값 표기
|
||||||
|
static var ageAll: String { pick(ko: "전체연령가", en: "All ages", ja: "全年齢") }
|
||||||
|
static var age19Plus: String { pick(ko: "19세 이상", en: "19+", ja: "19歳以上") }
|
||||||
|
static var random: String { pick(ko: "랜덤", en: "Random", ja: "ランダム") }
|
||||||
|
|
||||||
|
// 단위 및 포맷
|
||||||
|
static func cansUnit(_ value: Int) -> String {
|
||||||
|
pick(ko: "\(value)캔", en: "\(value) cans", ja: "\(value)缶")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func daysSuffix(_ days: Int) -> String {
|
||||||
|
pick(ko: "(\(days)일)", en: "(\(days) day\(days == 1 ? "" : "s"))", ja: "(\(days)日)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 가격 범위 표기: min==max==0 -> 무료, min==max>0 -> N캔, 범위 -> (무료|min) ~ max캔
|
||||||
|
static func priceInfo(min: Int, max: Int) -> String {
|
||||||
|
if min == max {
|
||||||
|
if max == 0 {
|
||||||
|
return CreateContent.free
|
||||||
|
} else {
|
||||||
|
return cansUnit(max)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let left = (min == 0) ? CreateContent.free : "\(min)"
|
||||||
|
// 범위 구분자는 로케일과 무관하게 시각적 구분자 유지
|
||||||
|
return "\(left) ~ \(cansUnit(max))"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 콘텐츠 구매/대여 관련 공통 액션 라벨
|
// 콘텐츠 구매/대여 관련 공통 액션 라벨
|
||||||
enum Purchase {
|
enum Purchase {
|
||||||
static var rent: String { pick(ko: "대여하기", en: "Rent", ja: "レンタルする") }
|
static var rent: String { pick(ko: "대여하기", en: "Rent", ja: "レンタルする") }
|
||||||
|
|||||||
Reference in New Issue
Block a user