Newer
Older
bremer-ios-app / BremerApp / View / SearchView.swift
//
//  SearchView.swift
//  Bremer
//
//  Created by yhornisse on 2023/07/17.
//

import SwiftUI
import AVFoundation

struct SearchView : View {
    
    @State
    private var searchText : String = ""
    @State
    private var showedLoginView = false
    @State
    private var showedUpdateAudioDialog = false
    @State
    private var showedErrorAlert = false
    @State
    private var showedSearchAudioDialog = false
    @State
    private var showedDeleteAudioDialog = false
    @State
    private var showedUpdateView = false
    @State
    private var audioTargetSlug = ""
    @State
    private var audioInfo = AudioInfo()
    @State
    private var audioTargetName = ""
    @State
    private var tagName = ""
    @State
    private var errorAlertTitle = ""
    @EnvironmentObject
    private var audioPlayerViewModel : AudioPlayerViewModel
    @EnvironmentObject
    private var settingViewModel : SettingViewModel
    @ObservedObject
    private var searchAudioViewModel = SearchAudioViewModel()
    
    var body : some View {
        NavigationView {
            VStack {
                if settingViewModel.getSetting().baseUrl == "" {
                    Text("Base URLを設定してください")
                } else if !searchAudioViewModel.messageText.isEmpty {
                    if (searchAudioViewModel.hasError) {
                        VStack {
                            Text(searchAudioViewModel.messageText)
                                .foregroundColor(.red)
                            if searchAudioViewModel.messageText == "ログインしてください" {
                                LoginButton(action: {
                                    self.showedLoginView = true
                                })
                            }
                        }
                    } else {
                        Text(searchAudioViewModel.messageText)
                    }
                }
                List {
                    ForEach(searchAudioViewModel.result, id:\.slug) { audio in
                        Button(action: {
                            audioPlayerViewModel.playAudioList(
                                audioList: searchAudioViewModel.result, audio: audio, usedBy: "search")
                        }) {
                            Text("\(audio.name) - \(audio.album ?? "")")
                                .font(.system(size: 14))
                                .frame(height: 35, alignment: .center)
                                .aspectRatio(contentMode: .fit)
                        }
                        .swipeActions(edge: .trailing) {
                            Button {
                                self.audioTargetSlug = audio.slug
                                self.audioTargetName = audio.name
                                self.showedDeleteAudioDialog = true
                            } label : {
                                Text("削除")
                            }
                            .tint(.red)
                            Button {
                                self.audioTargetSlug = audio.slug
                                self.audioInfo.audioName = audio.name
                                self.audioInfo.artistName = audio.artist ?? ""
                                self.audioInfo.albumName = audio.album ?? ""
                                self.audioInfo.localPath = audio.localPath
                                self.showedUpdateView = true
                            } label: {
                                Text("変更")
                            }
                            .tint(.green)
                        }
                    }
                }
                .listStyle(.plain)
                .searchable(text: $searchText, prompt: "検索キーワード")
                .onSubmit(of: .search) {
                    searchAudioViewModel.searchAudio(keyword: searchText)
                }
                .confirmationDialog(
                    "音楽削除",
                    isPresented: $showedDeleteAudioDialog,
                    actions: {
                        Button("OK", role: .destructive){
                            searchAudioViewModel.deleteAudio(audioTargetSlug)
                        }
                        Button("キャンセル", role: .cancel){
                            self.audioTargetSlug = ""
                            self.audioTargetName = ""
                        }
                    }, message: {
                        Text( "本当に \(audioTargetName) を削除しますか?\n一度消すとアプリからは戻せません!")
                    })
                Spacer()
                Divider()
                AudioPlayerView(audioPlayerViewModel: audioPlayerViewModel)
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: {
                        self.showedSearchAudioDialog = true
                    }) {
                        Image(systemName: "text.magnifyingglass")
                    }
                }
            }
        }
        .onAppear {
            searchAudioViewModel.bremerApiBaseUrl = settingViewModel.getSetting().baseApiUrl()
        }
        .sheet(isPresented: $showedLoginView) {
            LoginWebView()
                .onDisappear {
                    searchAudioViewModel.searchAudio(keyword: searchText)
                }
        }
        .sheet(isPresented: $showedUpdateView) {
            RenameAudioView(audioInfo: self.audioInfo){(audioInfo : AudioInfo) in
                searchAudioViewModel.updateAudio(
                    slug: self.audioTargetSlug,
                    audioName: audioInfo.audioName,
                    artistName: audioInfo.artistName,
                    albumName: audioInfo.albumName)
            }
        }
        .scrollDismissesKeyboard(.immediately)
        .onReceive(NotificationCenter.default.publisher(for: AVAudioSession.routeChangeNotification), perform: { param in
            audioPlayerViewModel.onChangeAudioSessionRoute(param)
        })
        .onReceive(NotificationCenter.default.publisher(for: AVAudioSession.interruptionNotification), perform: { param in
            audioPlayerViewModel.onInterrupted(param)
        })
        .alert("詳細検索", isPresented: $showedSearchAudioDialog) {
            SearchDetailAlertView(searchAction: searchAudioViewModel.searchAudio)
        } message: {
            Text("新しい名前を入力してください")
        }
    }
}