// // Copyright 2022 New Vector Ltd // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // import SwiftUI struct ComposerLinkAction: View { enum Field { case text case link } @Environment(\.theme) private var theme: ThemeSwiftUI @ObservedObject private var viewModel: ComposerLinkActionViewModel.Context @State private var selectedField: Field? private var isTextFocused: Bool { selectedField == .text } private var isLinkFocused: Bool { selectedField == .link } var body: some View { NavigationView { VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 24) { if viewModel.viewState.shouldDisplayTextField { VStack(alignment: .leading, spacing: 8.0) { Text(VectorL10n.wysiwygComposerLinkActionText) .font(theme.fonts.subheadline) .foregroundColor(theme.colors.secondaryContent) TextField( "", text: $viewModel.text, onEditingChanged: { edit in selectedField = edit ? .text : nil } ) .textFieldStyle(BorderedInputFieldStyle(isEditing: isTextFocused)) .autocapitalization(.none) .accessibilityIdentifier("textTextField") .accessibilityLabel(VectorL10n.wysiwygComposerLinkActionText) } } VStack(alignment: .leading, spacing: 8.0) { Text(VectorL10n.wysiwygComposerLinkActionLink) .font(theme.fonts.subheadline) .foregroundColor(theme.colors.secondaryContent) TextField( "", text: $viewModel.linkUrl, onEditingChanged: { edit in selectedField = edit ? .link : nil } ) .keyboardType(.URL) .autocapitalization(.none) .textFieldStyle(BorderedInputFieldStyle(isEditing: isLinkFocused)) .accessibilityIdentifier("linkTextField") .accessibilityLabel(VectorL10n.wysiwygComposerLinkActionLink) } } Spacer() VStack(spacing: 16) { Button(VectorL10n.save) { viewModel.send(viewAction: .save) } .buttonStyle(PrimaryActionButtonStyle()) .disabled(viewModel.viewState.isSaveButtonDisabled) .animation(.easeInOut(duration: 0.15), value: viewModel.viewState.isSaveButtonDisabled) if viewModel.viewState.shouldDisplayRemoveButton { Button(VectorL10n.remove) { viewModel.send(viewAction: .remove) } .buttonStyle(PrimaryActionButtonStyle(customColor: theme.colors.alert)) } Button(VectorL10n.cancel) { viewModel.send(viewAction: .cancel) } .buttonStyle(SecondaryActionButtonStyle()) } } .padding(.top, 40.0) .padding(.bottom, 12.0) .padding(.horizontal, 16.0) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button { viewModel.send(viewAction: .cancel) } label: { Text(VectorL10n.cancel) .foregroundColor(Color(ThemeService.shared().theme.tintColor)) } } ToolbarItem(placement: .principal) { Text(viewModel.viewState.title) .font(.headline) .foregroundColor(theme.colors.primaryContent) } } .navigationBarTitleDisplayMode(.inline) .introspectNavigationController { navigationController in ThemeService.shared().theme.applyStyle(onNavigationBar: navigationController.navigationBar) } .accentColor(Color(ThemeService.shared().theme.tintColor)) .navigationViewStyle(StackNavigationViewStyle()) } } init(viewModel: ComposerLinkActionViewModel.Context) { self.viewModel = viewModel } } struct ComposerLinkActionView_Previews: PreviewProvider { static let stateRenderer = MockComposerLinkActionScreenState.stateRenderer static var previews: some View { stateRenderer.screenGroup() } }