|
|
@@ -179,18 +179,26 @@ struct LanguageTranslatorView: View {
|
|
|
|
|
|
private var targetPanel: some View {
|
|
|
VStack(alignment: .leading, spacing: 12) {
|
|
|
- LanguagePicker(
|
|
|
- title: "To",
|
|
|
- selection: $viewModel.targetLanguage,
|
|
|
- languages: viewModel.targetLanguageOptions
|
|
|
- )
|
|
|
+ HStack(spacing: 8) {
|
|
|
+ LanguagePicker(
|
|
|
+ title: "To",
|
|
|
+ selection: $viewModel.targetLanguage,
|
|
|
+ languages: viewModel.targetLanguageOptions
|
|
|
+ )
|
|
|
+
|
|
|
+ ToolbarButton(title: "Copy", iconName: "doc.on.doc") {
|
|
|
+ viewModel.copyTranslatedText()
|
|
|
+ }
|
|
|
+ .disabled(viewModel.translatedText.isEmpty || viewModel.isTranslating)
|
|
|
+ .opacity(viewModel.translatedText.isEmpty || viewModel.isTranslating ? 0.55 : 1)
|
|
|
+
|
|
|
+ Spacer()
|
|
|
+ }
|
|
|
|
|
|
- ZStack(alignment: .topLeading) {
|
|
|
+ ZStack {
|
|
|
ThinCaretTextEditor(
|
|
|
text: $viewModel.translatedText,
|
|
|
- placeholder: viewModel.isTranslating
|
|
|
- ? "Translating..."
|
|
|
- : "Translation will appear here...",
|
|
|
+ placeholder: "Translation will appear here...",
|
|
|
isEditable: false
|
|
|
)
|
|
|
.font(.system(size: 14))
|
|
|
@@ -203,6 +211,24 @@ struct LanguageTranslatorView: View {
|
|
|
RoundedRectangle(cornerRadius: AppTheme.inputCornerRadius)
|
|
|
.stroke(AppTheme.inputBorder, lineWidth: 1)
|
|
|
)
|
|
|
+
|
|
|
+ if viewModel.isTranslating {
|
|
|
+ VStack(spacing: 12) {
|
|
|
+ ProgressView()
|
|
|
+ .controlSize(.regular)
|
|
|
+
|
|
|
+ Text("Loading...")
|
|
|
+ .font(.system(size: 16, weight: .semibold))
|
|
|
+ .foregroundStyle(AppTheme.textPrimary)
|
|
|
+
|
|
|
+ Text("Translating your content")
|
|
|
+ .font(.system(size: 14))
|
|
|
+ .foregroundStyle(AppTheme.textSecondary)
|
|
|
+ }
|
|
|
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
|
+ .background(Color.white.opacity(0.92))
|
|
|
+ .clipShape(RoundedRectangle(cornerRadius: AppTheme.inputCornerRadius))
|
|
|
+ }
|
|
|
}
|
|
|
.frame(maxHeight: .infinity)
|
|
|
}
|