mirror of
https://github.com/yattee/yattee.git
synced 2026-02-20 01:39:46 +00:00
Yattee v2 rewrite
This commit is contained in:
106
Yattee/Views/Settings/TranslationContributorsView.swift
Normal file
106
Yattee/Views/Settings/TranslationContributorsView.swift
Normal file
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// TranslationContributorsView.swift
|
||||
// Yattee
|
||||
//
|
||||
// Displays Weblate translation contributors.
|
||||
//
|
||||
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
|
||||
struct TranslationContributorsView: View {
|
||||
@State private var contributors: [TranslationContributor] = []
|
||||
|
||||
var body: some View {
|
||||
content
|
||||
.navigationTitle(String(localized: "settings.translators.title"))
|
||||
#if os(iOS)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#endif
|
||||
.task {
|
||||
contributors = TranslationContributorsLoader.load()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
@ViewBuilder
|
||||
private var content: some View {
|
||||
if contributors.isEmpty {
|
||||
ContentUnavailableView {
|
||||
Label(String(localized: "settings.translators.empty"), systemImage: "globe")
|
||||
}
|
||||
} else {
|
||||
contributorsList
|
||||
}
|
||||
}
|
||||
|
||||
private var contributorsList: some View {
|
||||
Form {
|
||||
Section {
|
||||
ForEach(contributors) { contributor in
|
||||
contributorRow(contributor)
|
||||
}
|
||||
} footer: {
|
||||
Text(String(localized: "settings.translators.section.footer"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func contributorRow(_ contributor: TranslationContributor) -> some View {
|
||||
HStack(spacing: 12) {
|
||||
// Avatar
|
||||
LazyImage(url: contributor.gravatarURL) { state in
|
||||
ZStack {
|
||||
Circle()
|
||||
.fill(.quaternary)
|
||||
.overlay {
|
||||
if state.image == nil {
|
||||
Text(String(contributor.displayName.prefix(1).uppercased()))
|
||||
.font(.subheadline)
|
||||
.fontWeight(.medium)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(width: 40, height: 40)
|
||||
.clipShape(Circle())
|
||||
|
||||
// Name and languages
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(contributor.displayName)
|
||||
.font(.body)
|
||||
.fontWeight(.semibold)
|
||||
|
||||
Text(contributor.languageSummary())
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
.lineLimit(2)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
// Total contributions badge
|
||||
Text("\(contributor.totalContributions)")
|
||||
.font(.caption)
|
||||
.fontWeight(.medium)
|
||||
.foregroundStyle(.secondary)
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 4)
|
||||
.background(.quaternary, in: Capsule())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
NavigationStack {
|
||||
TranslationContributorsView()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user