Commit f588da6c authored by shigemi miura's avatar shigemi miura

動画再生

iPad表示一部対応
parent 7913f764
......@@ -63,6 +63,9 @@
02CE4DDA2ADFBA72002E79BC /* MapRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02CE4DD92ADFBA72002E79BC /* MapRepresentable.swift */; };
02F4DB672B2C173F00E86C41 /* SessionGetManualUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02F4DB662B2C173F00E86C41 /* SessionGetManualUrl.swift */; };
A0F472F6BC78C5F1C5471836 /* Pods_SailAssistTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D252BA721FD314FAE4C2B4C /* Pods_SailAssistTests.framework */; };
D5056D3E2E8F4DE20076AC88 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5056D3D2E8F4DD80076AC88 /* SafariView.swift */; };
D5056D482E925FE90076AC88 /* LayoutConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5056D472E925FDF0076AC88 /* LayoutConstants.swift */; };
D5056D522E9343300076AC88 /* TaskTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5056D512E9343270076AC88 /* TaskTitleView.swift */; };
D51AA4072B099FCC00EBBDD4 /* AlertDB.swift in Sources */ = {isa = PBXBuildFile; fileRef = D51AA4062B099FCC00EBBDD4 /* AlertDB.swift */; };
D524DAF82B5A6D3600A399DD /* Imagepicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D524DAF72B5A6D3600A399DD /* Imagepicker.swift */; };
D524DAFA2B5A6F5F00A399DD /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D524DAF92B5A6F5F00A399DD /* CameraView.swift */; };
......@@ -98,7 +101,6 @@
D55135242B15C3BF007B66B1 /* DeleteEcaArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55135232B15C3BF007B66B1 /* DeleteEcaArea.swift */; };
D55186132E7E9158004CD8BD /* ImageQualityPreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55186122E7E914C004CD8BD /* ImageQualityPreset.swift */; };
D5598B782C435A5C00611AE0 /* ChatUrlImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5598B772C435A5C00611AE0 /* ChatUrlImageView.swift */; };
D5598B7A2C435C4500611AE0 /* ChatUrlRawImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5598B792C435C4500611AE0 /* ChatUrlRawImageView.swift */; };
D57405062E827C45001C74DF /* ChatUrlVideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57405052E827C35001C74DF /* ChatUrlVideoView.swift */; };
D57905FE2C1C069000AF797C /* SetNgaArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57905FD2C1C069000AF797C /* SetNgaArea.swift */; };
D57906002C1C06F600AF797C /* SessionNgaList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57905FF2C1C06F600AF797C /* SessionNgaList.swift */; };
......@@ -253,6 +255,9 @@
B422ACD189FD390D51F10007 /* Pods-SailAssistTests.qc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SailAssistTests.qc.xcconfig"; path = "Target Support Files/Pods-SailAssistTests/Pods-SailAssistTests.qc.xcconfig"; sourceTree = "<group>"; };
C0CBB553F04E0BB4ACC72BD1 /* Pods-Sailassist.qc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sailassist.qc.xcconfig"; path = "Target Support Files/Pods-Sailassist/Pods-Sailassist.qc.xcconfig"; sourceTree = "<group>"; };
CA31D32D54D7C200EF057679 /* Pods-SailAssistTests.canary.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SailAssistTests.canary.xcconfig"; path = "Target Support Files/Pods-SailAssistTests/Pods-SailAssistTests.canary.xcconfig"; sourceTree = "<group>"; };
D5056D3D2E8F4DD80076AC88 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = "<group>"; };
D5056D472E925FDF0076AC88 /* LayoutConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutConstants.swift; sourceTree = "<group>"; };
D5056D512E9343270076AC88 /* TaskTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskTitleView.swift; sourceTree = "<group>"; };
D51AA4062B099FCC00EBBDD4 /* AlertDB.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AlertDB.swift; path = Sailassist/DataSource/AlertDB.swift; sourceTree = SOURCE_ROOT; };
D524DAF72B5A6D3600A399DD /* Imagepicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Imagepicker.swift; path = Sailassist/Chat/Imagepicker.swift; sourceTree = SOURCE_ROOT; };
D524DAF92B5A6F5F00A399DD /* CameraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CameraView.swift; path = Sailassist/Chat/View/CameraView.swift; sourceTree = SOURCE_ROOT; };
......@@ -289,7 +294,6 @@
D55135232B15C3BF007B66B1 /* DeleteEcaArea.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DeleteEcaArea.swift; path = Sailassist/ECA/DeleteEcaArea.swift; sourceTree = SOURCE_ROOT; };
D55186122E7E914C004CD8BD /* ImageQualityPreset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageQualityPreset.swift; sourceTree = "<group>"; };
D5598B772C435A5C00611AE0 /* ChatUrlImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ChatUrlImageView.swift; path = Sailassist/Chat/View/ChatUrlImageView.swift; sourceTree = SOURCE_ROOT; };
D5598B792C435C4500611AE0 /* ChatUrlRawImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ChatUrlRawImageView.swift; path = Sailassist/Chat/View/ChatUrlRawImageView.swift; sourceTree = SOURCE_ROOT; };
D57405052E827C35001C74DF /* ChatUrlVideoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatUrlVideoView.swift; sourceTree = "<group>"; };
D57905FD2C1C069000AF797C /* SetNgaArea.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetNgaArea.swift; sourceTree = "<group>"; };
D57905FF2C1C06F600AF797C /* SessionNgaList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SessionNgaList.swift; path = Sailassist/ServerSession/SessionNgaList.swift; sourceTree = SOURCE_ROOT; };
......@@ -401,6 +405,7 @@
020B98122AD8C3140029DE4C /* SailAssist */ = {
isa = PBXGroup;
children = (
D5056D452E925FC50076AC88 /* Resources */,
D5C782452BFB55F0001EBB3A /* NGA */,
D5384AFF2B3121FA006228C6 /* html */,
D545FC722B09C6DA00F206D0 /* VoiceManager */,
......@@ -542,6 +547,7 @@
02A1DE2D2AFB497B005BCF55 /* View */,
D5AF8A4B2E88CDF600BECA22 /* ViewModel */,
D5258CA42B036F0700365276 /* GetMessage.swift */,
D5056D3D2E8F4DD80076AC88 /* SafariView.swift */,
D55186122E7E914C004CD8BD /* ImageQualityPreset.swift */,
D5F969BC2E8AAD3C005662B0 /* VideoQualityPreset.swift */,
D524DAF72B5A6D3600A399DD /* Imagepicker.swift */,
......@@ -599,8 +605,9 @@
022789102AE6028400A87787 /* View */ = {
isa = PBXGroup;
children = (
D5AF8A512E89251E00BECA22 /* MenuMainView.swift */,
D5056D512E9343270076AC88 /* TaskTitleView.swift */,
D5C7822E2BF88755001EBB3A /* MenuTaskView.swift */,
D5AF8A512E89251E00BECA22 /* MenuMainView.swift */,
D5AF8A4F2E89169000BECA22 /* NgaMenuView.swift */,
D5AF8A5B2E892FB800BECA22 /* NgaSettingMainView.swift */,
D5AF8A592E892F4600BECA22 /* NgaNotificationMainView.swift */,
......@@ -676,7 +683,6 @@
D524DAF92B5A6F5F00A399DD /* CameraView.swift */,
D5598B772C435A5C00611AE0 /* ChatUrlImageView.swift */,
D57405052E827C35001C74DF /* ChatUrlVideoView.swift */,
D5598B792C435C4500611AE0 /* ChatUrlRawImageView.swift */,
D5A4C2522E7AB46B00642D7D /* SpeechRecognizer.swift */,
);
path = View;
......@@ -738,6 +744,22 @@
path = Pods;
sourceTree = "<group>";
};
D5056D452E925FC50076AC88 /* Resources */ = {
isa = PBXGroup;
children = (
D5056D462E925FD20076AC88 /* Constants */,
);
path = Resources;
sourceTree = "<group>";
};
D5056D462E925FD20076AC88 /* Constants */ = {
isa = PBXGroup;
children = (
D5056D472E925FDF0076AC88 /* LayoutConstants.swift */,
);
path = Constants;
sourceTree = "<group>";
};
D51AA4052B099F6D00EBBDD4 /* DataSource */ = {
isa = PBXGroup;
children = (
......@@ -1074,6 +1096,7 @@
D5B803282B3B988E003B32AD /* AppVersionModel.swift in Sources */,
D52E91762E864E2100118E73 /* CustomTabBarViewModel.swift in Sources */,
D592D5232B0F14FE00B91A1C /* SessionUploadImage.swift in Sources */,
D5056D3E2E8F4DE20076AC88 /* SafariView.swift in Sources */,
D5FCEF552B478985009A81D0 /* ResChatMessage.swift in Sources */,
D5598B782C435A5C00611AE0 /* ChatUrlImageView.swift in Sources */,
022A98202AF8B8960079C55A /* LocationCalculation.swift in Sources */,
......@@ -1131,6 +1154,7 @@
D52E91742E86495C00118E73 /* NotificationBadge.swift in Sources */,
D545FC742B09C74300F206D0 /* AlertManager.swift in Sources */,
020B98692ADD221E0029DE4C /* Preferences.swift in Sources */,
D5056D522E9343300076AC88 /* TaskTitleView.swift in Sources */,
D52E916E2E860FBA00118E73 /* CustomTabBar.swift in Sources */,
D54A5FD72B8F10B500F3A9D6 /* StatusEnum.swift in Sources */,
D536F6712B678D8900A5BCF9 /* ReqUploadImage.swift in Sources */,
......@@ -1180,13 +1204,13 @@
D52C2C082B9195A8003B286C /* MenuInformationView.swift in Sources */,
D5258C992B0334BF00365276 /* SessionShipStatus.swift in Sources */,
D5AAB69D2E7A5E8F0027CD90 /* AlertModifiers.swift in Sources */,
D5056D482E925FE90076AC88 /* LayoutConstants.swift in Sources */,
02CE4D872ADF62A7002E79BC /* EcaListView.swift in Sources */,
D5A4C2532E7AB48700642D7D /* SpeechRecognizer.swift in Sources */,
D5E008762B2ADD5900C4070A /* MenuManualRADARView.swift in Sources */,
D59908C62B19EA70000E13DD /* ResPushHistory.swift in Sources */,
D58EF2472B9044C800FB784C /* ResInformation.swift in Sources */,
020B986C2ADD3E810029DE4C /* InTextLib.swift in Sources */,
D5598B7A2C435C4500611AE0 /* ChatUrlRawImageView.swift in Sources */,
02C3E5D12AFCC16800AF7837 /* ChatTitleView.swift in Sources */,
024EDE1D2B0C42F70013BAC8 /* MenuGpsSelectView.swift in Sources */,
020B98472AD8FEE30029DE4C /* ColorSet.swift in Sources */,
......
......@@ -71,10 +71,10 @@ struct NotificationView: View {
.disabled(true)
.frame(width: 48, height: 48)
}
.frame(height: 60)
.frame(height: LayoutConstants.menuTitleHeight)
Divider()
.background(ColorSet.LineColor04.color)
.background(ColorSet.LineColor03.color)
}
}
}
......
import SwiftUI
import SafariServices
struct SafariView: UIViewControllerRepresentable {
let url: URL
var onDismiss: (() -> Void)? = nil
func makeUIViewController(context: Context) -> SFSafariViewController {
let safariVC = SFSafariViewController(url: url)
safariVC.delegate = context.coordinator
return safariVC
}
func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(onDismiss: onDismiss)
}
class Coordinator: NSObject, SFSafariViewControllerDelegate {
var onDismiss: (() -> Void)?
init(onDismiss: (() -> Void)?) {
self.onDismiss = onDismiss
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
onDismiss?()
}
}
}
......@@ -78,9 +78,7 @@ struct ChatTitleView: View {
}
}
/**
* チャット名称をまとめる
*/
//MARK: - チャット名称をまとめる
func userName() -> String {
var usersName = ""
for user in message.users {
......@@ -92,9 +90,7 @@ struct ChatTitleView: View {
return usersName
}
/**
* チャット通知のON/OFF
*/
//MARK: - チャット通知のON/OFF
func chatNotification() -> Bool {
var isNotification = Preferences.ChatNotification
isNotification.toggle()
......
//
// ChatUrlRawImageView.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/07/14.
//
import SwiftUI
struct ChatUrlRawImageView: View {
var imageUrl: String
init(message: ChatMessage) {
var url_string : String = HttpRequestType.RawImage.rawValue
url_string = url_string.replacingOccurrences(of: "XXXXX", with: String(message.shipId))
url_string = url_string.replacingOccurrences(of: "YYYYY", with: String(message.messageId))
self.imageUrl = url_string
}
var body: some View {
VStack {
AsyncImage(url: URL(string: imageUrl)) { phase in
if let image = phase.image {
image
.resizable(resizingMode: .stretch)
.aspectRatio(contentMode: .fit)
.frame(width: 250)
} else if phase.error != nil {
Color.gray.opacity(0.2)
.overlay(Image(systemName: "rectangle.slash"))
} else {
Color.gray.opacity(0.2)
ProgressView()
}
}
.cornerRadius(16)
.aspectRatio(contentMode: .fit)
.frame(height: 250)
}
.navigationTitle("image")
}
}
#Preview {
ChatUrlRawImageView(message: ChatMessage(
shipId: 10000003,
messageId: "92c2dfb5-f5ed-4943-98a3-9848d7f9a962",
type: 0,
time: "2023-10-06T01:51:01.872Z",
location: 1,
from: "はだだ",
fromId: "487420489",
mode: 0,
message: "999",
stampId: 0,
viewer: [
Viewer(
time: "2023-10-06T01:51:12.973Z",
location: 1,
id: ""),
Viewer(
time: "2023-10-06T01:51:12.973Z",
location: 2,
id: "")
]
))
}
......@@ -4,7 +4,6 @@
//
// Created by Mamoru Sugita on 2023/10/16.
//
import SwiftUI
struct ChatView: View {
......@@ -17,6 +16,7 @@ struct ChatView: View {
@State private var totalMediaCount: Int = 0
@State private var isMediaLoading: Bool = false
@State private var isUploadingDialogPresented: Bool = false
var contentWidth: CGFloat
var body: some View {
ZStack {
......@@ -35,15 +35,15 @@ struct ChatView: View {
if msg.message != nil {
if msg.from == Preferences.UserName {
//MARK: - 自分のメッセージ
MyChatContentView(message: msg, onMediaLoaded: {handleMediaLoaded(proxy: proxy)})
MyChatContentView(message: msg, contentWidth: contentWidth, onMediaLoaded: {handleMediaLoaded(proxy: proxy)})
.padding(.bottom, 24)
}else{
//MARK: - 他人のメッセージ
OtherChatContentView(message: msg, onMediaLoaded: {handleMediaLoaded(proxy: proxy)})
OtherChatContentView(message: msg, contentWidth: contentWidth, onMediaLoaded: {handleMediaLoaded(proxy: proxy)})
.padding(.bottom, 24)
}
} else {
AlertChatMessage(message: msg)
AlertChatMessage(message: msg, onMediaLoaded: {handleMediaLoaded(proxy: proxy)})
.padding(.bottom, 24)
}
}
......@@ -54,9 +54,8 @@ struct ChatView: View {
let id = message.messages.last?.messageId else { return }
totalMediaCount = message.messages.reduce(0) { count, msg in
count + (msg.type >= 2 ? 1 : 0)
count + (msg.type >= 0 ? 1 : 0)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
proxy.scrollTo(id, anchor: .bottom)
}
......@@ -194,6 +193,7 @@ struct UpLoadingView: View {
struct AlertChatMessage: View {
@Environment(\.colorScheme) var colorScheme
var message : ChatMessage
var onMediaLoaded: (() -> Void)? = nil
var body: some View {
switch message.mode {
......@@ -208,6 +208,9 @@ struct AlertChatMessage: View {
Rectangle()
.fill(ColorSet.ChatDate.color)
.frame(width: 20, height: 1)
.onAppear {
onMediaLoaded?()
}
}
case ChatMode.normal.rawValue:
HStack() {
......@@ -220,14 +223,20 @@ struct AlertChatMessage: View {
Rectangle()
.fill(ColorSet.ChatDate.color)
.frame(width: 20, height: 1)
.onAppear {
onMediaLoaded?()
}
}
default:
EmptyView()
.onAppear {
onMediaLoaded?()
}
}
}
}
#Preview {
ChatView()
ChatView(contentWidth: CGFloat())
}
......@@ -8,7 +8,11 @@ import SwiftUI
import AVKit
struct MyChatContentView: View {
@EnvironmentObject private var selectedTabModel: SelectedTabModel
@State private var safariUrl: URL? = nil
@State private var isSafariPresented = false
var message : ChatMessage
var contentWidth: CGFloat
var onMediaLoaded: (() -> Void)? = nil
var body: some View {
......@@ -16,35 +20,57 @@ struct MyChatContentView: View {
Spacer()
VStack(alignment: .trailing, spacing: 6) {
Group {
if let msg = message.message {
if msg.contains(".jpg") || msg.contains(".png") {
ChatUrlImageView(imageUrl: msg, onLoad: onMediaLoaded)
.onTapGesture {
var urlString: String = HttpRequestType.RawImage.rawValue
urlString = urlString.replacingOccurrences(of: "XXXXX", with: String(message.shipId))
urlString = urlString.replacingOccurrences(of: "YYYYY", with: String(message.messageId))
if let url = URL(string: urlString) {
UIApplication.shared.open(url)
HStack(alignment: .top, spacing: 6) {
if message.Latitude != nil && message.Longitude != nil {
Image("map_pin")
.resizable()
.frame(width: 20, height: 20)
}
if let msg = message.message {
if msg.contains(".jpg") || msg.contains(".png") {
ChatUrlImageView(imageUrl: msg, onLoad: onMediaLoaded)
.onTapGesture {
isSafariPresented = true
}
}
} else {
Text(msg)
.font(FontStyle.DefaultText.font)
.foregroundColor(ColorSet.BodyChat.color)
.padding(15)
.background(ColorSet.ChatBaloon.color)
.border(Color.red.gradient.opacity(0.8), width: (message.mode == ChatMode.warningProgress.rawValue ? 2 : 0))
.clipShape(
.rect(
topLeadingRadius: 10,
bottomLeadingRadius: 0,
bottomTrailingRadius: 10,
topTrailingRadius: 10
))
} else {
Text(msg)
.font(FontStyle.DefaultText.font)
.foregroundColor(ColorSet.BodyChat.color)
.padding(15)
.background(ColorSet.ChatBaloon.color)
.border(Color.red.gradient.opacity(0.8), width: (message.mode == ChatMode.warningProgress.rawValue ? 2 : 0))
.clipShape(
.rect(
topLeadingRadius: 10,
bottomLeadingRadius: 10,
bottomTrailingRadius: 0,
topTrailingRadius: 10
))
.frame(maxWidth: contentWidth * 0.8, alignment: .trailing)
.multilineTextAlignment(.leading)
.onAppear {
onMediaLoaded?()
}
}
}
}
}
.onAppear {
if message.type >= 1 {
var urlString: String = HttpRequestType.RawImage.rawValue
urlString = urlString.replacingOccurrences(of: "XXXXX", with: String(message.shipId))
urlString = urlString.replacingOccurrences(of: "YYYYY", with: String(message.messageId))
if let url = URL(string: urlString) {
safariUrl = url
}
}
}
.onChange(of: selectedTabModel.activeTab) { newValue in
if newValue != Tab.chat {
isSafariPresented = false
}
}
HStack(spacing: 5){
//MARK: - 既読マーク
......@@ -74,10 +100,19 @@ struct MyChatContentView: View {
}
.padding(.trailing, 20)
}
.fullScreenCover(isPresented: $isSafariPresented) {
if let url = safariUrl {
SafariView(url: url) {
isSafariPresented = false
}
} else {
Text("URLが無効です")
}
}
}
func viewerCnt() -> (Int, Int) {
var shipViewer = 0
var shipViewer = -1
var companyViewr = 0
for viewer in message.viewer {
if viewer.location == 1 {
......@@ -86,31 +121,7 @@ struct MyChatContentView: View {
shipViewer += 1
}
}
if shipViewer == -1 { shipViewer = 0 }
return (shipViewer, companyViewr)
}
}
#Preview {
MyChatContentView(message: ChatMessage(
shipId: 10000003,
messageId: "92c2dfb5-f5ed-4943-98a3-9848d7f9a962",
type: 0,
time: "2023-10-06T01:51:01.872Z",
location: 1,
from: "はだだ",
fromId: "487420489",
mode: 0,
message: "999",
stampId: 0,
viewer: [
Viewer(
time: "2023-10-06T01:51:12.973Z",
location: 1,
id: ""),
Viewer(
time: "2023-10-06T01:51:12.973Z",
location: 2,
id: "")
]
))
}
......@@ -8,7 +8,11 @@ import SwiftUI
import AVKit
struct OtherChatContentView: View {
@EnvironmentObject private var selectedTabModel: SelectedTabModel
@State private var safariUrl: URL? = nil
@State private var isSafariPresented = false
var message : ChatMessage
var contentWidth: CGFloat
var onMediaLoaded: (() -> Void)? = nil
var body: some View {
......@@ -21,35 +25,57 @@ struct OtherChatContentView: View {
}
VStack(alignment: .leading, spacing: 10) {
Group {
if let msg = message.message {
if msg.contains(".jpg") || msg.contains(".png") {
ChatUrlImageView(imageUrl: msg, onLoad: onMediaLoaded)
.onTapGesture {
var urlString: String = HttpRequestType.RawImage.rawValue
urlString = urlString.replacingOccurrences(of: "XXXXX", with: String(message.shipId))
urlString = urlString.replacingOccurrences(of: "YYYYY", with: String(message.messageId))
if let url = URL(string: urlString) {
UIApplication.shared.open(url)
HStack(alignment: .top, spacing: 6) {
if let msg = message.message {
if msg.contains(".jpg") || msg.contains(".png") {
ChatUrlImageView(imageUrl: msg, onLoad: onMediaLoaded)
.onTapGesture {
isSafariPresented = true
}
} else {
Text(msg)
.font(FontStyle.DefaultText.font)
.foregroundColor(ColorSet.BodyChat.color)
.padding(15)
.background(ColorSet.ChatBaloon.color)
.border(Color.red.gradient.opacity(0.8), width: (message.mode == ChatMode.warningProgress.rawValue ? 2 : 0))
.clipShape(
.rect(
topLeadingRadius: 10,
bottomLeadingRadius: 0,
bottomTrailingRadius: 10,
topTrailingRadius: 10
))
.frame(maxWidth: contentWidth * 0.8, alignment: .leading)
.multilineTextAlignment(.leading)
.onAppear {
onMediaLoaded?()
}
}
} else {
Text(msg)
.font(FontStyle.DefaultText.font)
.foregroundColor(ColorSet.BodyChat.color)
.padding(15)
.background(ColorSet.ChatBaloon.color)
.border(Color.red.gradient.opacity(0.8), width: (message.mode == ChatMode.warningProgress.rawValue ? 2 : 0))
.clipShape(
.rect(
topLeadingRadius: 10,
bottomLeadingRadius: 10,
bottomTrailingRadius: 0,
topTrailingRadius: 10
))
}
}
if message.Latitude != nil && message.Longitude != nil {
Image("map_pin")
.resizable()
.frame(width: 20, height: 20)
}
}
}
.onAppear {
if message.type >= 1 {
var urlString: String = HttpRequestType.RawImage.rawValue
urlString = urlString.replacingOccurrences(of: "XXXXX", with: String(message.shipId))
urlString = urlString.replacingOccurrences(of: "YYYYY", with: String(message.messageId))
if let url = URL(string: urlString) {
safariUrl = url
}
}
}
.onChange(of: selectedTabModel.activeTab) { newValue in
if newValue != Tab.chat {
isSafariPresented = false
}
}
HStack(alignment: .top) {
Text(DateTextLib.ISO86012FormatText(message.time, format: "yyyy/MM/dd HH:mm", errFormat: ""))
......@@ -61,30 +87,15 @@ struct OtherChatContentView: View {
.padding(.leading, 20)
Spacer()
}
.fullScreenCover(isPresented: $isSafariPresented) {
if let url = safariUrl {
SafariView(url: url) {
isSafariPresented = false
}
} else {
Text("URLが無効です")
}
}
}
}
#Preview {
OtherChatContentView(message: ChatMessage(
shipId: 10000003,
messageId: "92c2dfb5-f5ed-4943-98a3-9848d7f9a962",
type: 0,
time: "2023-10-06T01:51:01.872Z",
location: 1,
from: "はだだ",
fromId: "487420489",
mode: 0,
message: "999",
stampId: 0,
viewer: [
Viewer(
time: "2023-10-06T01:51:12.973Z",
location: 1,
id: ""),
Viewer(
time: "2023-10-06T01:51:12.973Z",
location: 2,
id: "")
]
))
}
......@@ -4,32 +4,11 @@ struct EcaListMainView: View {
@ObservedObject var taskViewModel = TaskViewModel()
var body: some View {
HStack{
Button(action: {
taskViewModel.viewMode = .FuelSwitching
}, label: {
Image("ink_02")
})
.frame(width: 48, height: 48)
Spacer()
Text(TaskViewMode.EcaList.title)
.font(FontStyle.TitleL.font)
.frame(height: 20)
.padding(.vertical, 14)
Spacer()
Button(action: {
}, label: {
})
.frame(width: 48, height: 48)
}
.padding(EdgeInsets(top: 10, leading: 8, bottom: 13, trailing: 17))
Divider()
.background(ColorSet.LineColor03.color)
TaskTitleView(
taskViewModel: taskViewModel,
title: TaskViewMode.EcaList.title,
viewMode: TaskViewMode.FuelSwitching
)
ScrollViewReader { proxy in
ScrollView(.vertical){
......
......@@ -4,33 +4,11 @@ struct EcaSettingMainView: View {
@ObservedObject var taskViewModel = TaskViewModel()
var body: some View {
//タイトルエリア
HStack{
Button(action: {
taskViewModel.viewMode = .FuelSwitching
}, label: {
Image("ink_02")
})
.frame(width: 48, height: 48)
Spacer()
Text(TaskViewMode.EcaSetting.title)
.font(FontStyle.TitleL.font)
.frame(height: 20)
.padding(.vertical, 14)
Spacer()
Button(action: {
}, label: {
})
.frame(width: 48, height: 48)
}
.padding(EdgeInsets(top: 10, leading: 8, bottom: 13, trailing: 17))
Divider()
.background(ColorSet.LineColor03.color)
TaskTitleView(
taskViewModel: taskViewModel,
title: TaskViewMode.EcaSetting.title,
viewMode: TaskViewMode.FuelSwitching
)
ScrollViewReader { proxy in
ScrollView(.vertical){
......
......@@ -4,34 +4,13 @@ struct FuelSwitchingMainView: View {
@ObservedObject var taskViewModel = TaskViewModel()
var body: some View {
HStack{
Button(action: {
taskViewModel.viewMode = .MenuList
}, label: {
Image("ink_02")
})
.frame(width: 48, height: 48)
TaskTitleView(
taskViewModel: taskViewModel,
title: TaskViewMode.FuelSwitching.title,
viewMode: TaskViewMode.MenuList
)
Spacer()
Text(TaskViewMode.FuelSwitching.title)
.font(FontStyle.TitleL.font)
.frame(height: 20)
.padding(.vertical, 14)
Spacer()
Button(action: {
}, label: {
})
.frame(width: 48, height: 48)
}
.padding(EdgeInsets(top: 10, leading: 8, bottom: 13, trailing: 17))
Divider()
.background(ColorSet.LineColor03.color)
//ECAリスト
//燃料切り替え
ScrollViewReader { proxy in
ScrollView(.vertical){
FuelSwitchingView(taskViewModel: taskViewModel)
......
......@@ -5,10 +5,11 @@ struct MenuMainView: View {
var body: some View {
VStack(spacing: 0) {
headerView
Divider()
.background(ColorSet.LineColor03.color)
TaskTitleView(
taskViewModel: taskViewModel,
title: TaskViewMode.MenuList.title,
viewMode: nil
)
ScrollViewReader { proxy in
ScrollView(.vertical){
......@@ -36,18 +37,6 @@ struct MenuMainView: View {
}
}
Spacer().frame(height: 55)
}
.padding(EdgeInsets(top: 10, leading: 8, bottom: 13, trailing: 17))
}
private var headerView: some View {
HStack {
Spacer()
Text(TaskViewMode.MenuList.title)
.font(FontStyle.TitleL.font)
.frame(height: 20)
.padding(.vertical, 14)
Spacer()
}
}
......
......@@ -33,7 +33,7 @@ enum TaskViewMode {
}
struct MenuTaskView: View {
@ObservedObject var taskViewModel = TaskViewModel()
@StateObject var taskViewModel = TaskViewModel()
@ObservedObject var eca = SharingData.eca
@ObservedObject var nga = SharingData.nga
......
......@@ -4,33 +4,11 @@ struct NgaNotificationMainView: View {
@ObservedObject var taskViewModel = TaskViewModel()
var body: some View {
//タイトルエリア
HStack{
Button(action: {
taskViewModel.viewMode = .MenuList
}, label: {
Image("ink_02")
})
.frame(width: 48, height: 48)
Spacer()
Text(TaskViewMode.NgaNotification.title)
.font(FontStyle.TitleL.font)
.frame(height: 20)
.padding(.vertical, 14)
Spacer()
Button(action: {
}, label: {
})
.frame(width: 48, height: 48)
}
.padding(EdgeInsets(top: 10, leading: 8, bottom: 13, trailing: 17))
Divider()
.background(ColorSet.LineColor03.color)
TaskTitleView(
taskViewModel: taskViewModel,
title: TaskViewMode.NgaNotification.title,
viewMode: TaskViewMode.MenuList
)
ScrollViewReader { proxy in
ScrollView(.vertical){
......
......@@ -23,11 +23,11 @@ struct NgaSettingMainView: View {
.frame(width: 48, height: 48)
Spacer()
Text(TaskViewMode.NgaSetting.title)
.font(FontStyle.TitleL.font)
.frame(height: 20)
.padding(.vertical, 14)
HStack(spacing: 0) {
Text(TaskViewMode.NgaSetting.title)
.font(FontStyle.TitleL.font)
.foregroundColor(ColorSet.Body.color)
}
Spacer()
......@@ -36,7 +36,7 @@ struct NgaSettingMainView: View {
})
.frame(width: 48, height: 48)
}
.padding(EdgeInsets(top: 10, leading: 8, bottom: 13, trailing: 17))
.frame(height: LayoutConstants.menuTitleHeight)
Divider()
.background(ColorSet.LineColor03.color)
......
import SwiftUI
struct TaskTitleView: View {
@ObservedObject var taskViewModel: TaskViewModel
var title: String = "Menu"
var viewMode: TaskViewMode? = nil
var body: some View {
HStack {
Button(action: {
if let mode = viewMode {
taskViewModel.viewMode = mode
}
}, label: {
if viewMode != nil {
Image("ink_02")
}
})
.disabled(viewMode == nil)
.frame(width: 48, height: 48)
Spacer()
HStack(spacing: 0) {
Text(title)
.font(FontStyle.TitleL.font)
.foregroundColor(ColorSet.Body.color)
}
Spacer()
Button(action: {
print(debug: "called")
}, label: {
})
.frame(width: 48, height: 48)
}
.frame(height: LayoutConstants.menuTitleHeight)
Divider()
.background(ColorSet.LineColor03.color)
}
}
#Preview {
MenuMainView(taskViewModel: TaskViewModel())
}
......@@ -40,7 +40,7 @@ struct MenuTitleView: View {
.disabled(true)
.frame(width: 48, height: 48)
}
.frame(height: 60)
.frame(height: LayoutConstants.menuTitleHeight)
Divider()
.background(ColorSet.LineColor04.color)
......
import SwiftUI
struct LayoutConstants {
static let menuTitleHeight: CGFloat = 60 //メニュータイトルの高さ
static let menuViewWidth: CGFloat = 340 //iPadの地図上に表示されるメニューの幅
static let tabHeight: CGFloat = 50 //タブの高さ
static let menuMinimumHeight: CGFloat = menuTitleHeight + tabHeight
}
......@@ -57,7 +57,7 @@ struct CustomTabBar: View {
.contentShape(Rectangle())
}
}
.frame(height: 50)
.frame(height: LayoutConstants.tabHeight)
}
.background(ColorSet.BottomNav.color)
.modifier(ChangeModeAlertModifier(
......
......@@ -6,7 +6,6 @@ import Combine
class CustomTabBarViewModel: ObservableObject {
@Published var chatBadgeViewModel = NotificationBadgeViewModel()
@Published var alertBadgeViewModel = NotificationBadgeViewModel()
@Published var isMenuTaskViewVisible = false
@Published var isSignalrRestart = false
@Published var isModeAlert = false
......@@ -25,10 +24,6 @@ class CustomTabBarViewModel: ObservableObject {
case .map:
selectedTabModel.isPoppver.toggle()
location.focusOwnShip = true
if UIDevice.current.userInterfaceIdiom == .pad {
isMenuTaskViewVisible.toggle()
updateMapMenuVisibility()
}
case .chat:
messageService.start()
......@@ -51,30 +46,6 @@ class CustomTabBarViewModel: ObservableObject {
private func resetPopoverAndMenu(selectedTabModel: SelectedTabModel) {
selectedTabModel.isPoppver = false
if UIDevice.current.userInterfaceIdiom == .pad {
isMenuTaskViewVisible = false
updateMapMenuVisibility()
}
}
//MARK: - マップメニュー表示の切り替え
private func updateMapMenuVisibility() {
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
let menuWidth = min(400, screenWidth * 0.3)
let menuHeight = screenHeight * 0.8
if isMenuTaskViewVisible {
MenuWindowManager.shared.showMenuView(
MenuTaskView()
.frame(width: menuWidth, height: menuHeight)
.background(ColorSet.BackgroundSecondary.color)
.cornerRadius(15),
frame: CGRect(x: 5, y: screenHeight * 0.12, width: menuWidth, height: menuHeight)
)
} else {
MenuWindowManager.shared.hideMenuView()
}
}
}
......
......@@ -53,41 +53,106 @@ struct MainTabView: View {
}
private var phoneView: some View {
ZStack(alignment: .bottom) {
TabView(selection: $selectedTabModel.activeTab) {
mapTab
if SharingData.my.isCommunication {
ChatView().tag(Tab.chat)
GeometryReader { geometry in
ZStack(alignment: .bottom) {
TabView(selection: $selectedTabModel.activeTab) {
mapTab
if SharingData.my.isCommunication {
ChatView(contentWidth: UIScreen.main.bounds.width).tag(Tab.chat)
}
NotificationView().tag(Tab.alert)
MenuView(isSignout: $isSignout).tag(Tab.menu)
}
.sheet(isPresented: .constant(isTaskSel && isTabWindowActive)) {
MenuTaskView()
.zIndex(0)
.presentationDragIndicator(.hidden)
.presentationDetents([
.height(LayoutConstants.menuMinimumHeight + geometry.safeAreaInsets.bottom),
.medium,
.fraction(0.99)
])
.presentationCornerRadius(15)
.presentationBackgroundInteraction(.enabled(upThrough: .medium))
.presentationBackground(ColorSet.BackgroundSecondary.color)
.interactiveDismissDisabled()
}
NotificationView().tag(Tab.alert)
MenuView(isSignout: $isSignout).tag(Tab.menu)
}
.sheet(isPresented: .constant(isTaskSel && isTabWindowActive)) {
MenuTaskView()
.zIndex(0)
.presentationDragIndicator(.hidden)
.presentationDetents([.height(150), .medium, .fraction(0.99)])
.presentationCornerRadius(15)
.presentationBackgroundInteraction(.enabled(upThrough: .medium))
.presentationBackground(ColorSet.BackgroundSecondary.color)
.interactiveDismissDisabled()
}
}
enum OverlayHeightMode: CaseIterable {
case titleOnly
// case half
case full
var heightRatio: CGFloat {
switch self {
case .titleOnly: return 0.15
// case .half: return 0.5
case .full: return 1.0
}
}
}
@State private var overlayHeightMode: OverlayHeightMode = .full
private var padView: some View {
ZStack(alignment: .bottom) {
TabView(selection: $selectedTabModel.activeTab) {
GeometryReader { geometry in
mapTab.padding(.bottom, geometry.safeAreaInsets.bottom + 10)
}
if SharingData.my.isCommunication {
ChatView().padding(.bottom, 50).tag(Tab.chat)
GeometryReader { geometry in
let overlayWidth = LayoutConstants.menuViewWidth
let fullHeight = geometry.size.height - (LayoutConstants.menuTitleHeight + geometry.safeAreaInsets.top + 15)
let overlayHeight = fullHeight * overlayHeightMode.heightRatio
ZStack(alignment: .bottomLeading) {
MapRepresentable()
.ignoresSafeArea()
if selectedTabModel.activeTab == .menu {
MenuView(isSignout: $isSignout)
.frame(width: geometry.size.width, height: geometry.size.height)
.background(ColorSet.BackgroundPrimary.color)
.ignoresSafeArea()
} else {
VStack(spacing: 0) {
Rectangle()
.fill(Color.gray.opacity(0.3))
.frame(height: 20)
.overlay(
Image(systemName: "line.horizontal.3")
.foregroundColor(.gray)
)
.gesture(
DragGesture()
.onEnded { _ in
withAnimation {
let allModes = OverlayHeightMode.allCases
if let currentIndex = allModes.firstIndex(of: overlayHeightMode) {
let nextIndex = (currentIndex + 1) % allModes.count
overlayHeightMode = allModes[nextIndex]
}
}
}
)
TabView(selection: $selectedTabModel.activeTab) {
MenuTaskView()
.tag(Tab.map)
if SharingData.my.isCommunication {
ChatView(contentWidth: overlayWidth)
.tag(Tab.chat)
}
NotificationView()
.tag(Tab.alert)
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
.frame(width: overlayWidth, height: overlayHeight)
.background(ColorSet.BackgroundPrimary.color)
.cornerRadius(12)
.shadow(radius: 4)
.padding(.bottom, LayoutConstants.menuTitleHeight + 5)
.padding(.leading, 5)
}
NotificationView().padding(.bottom, 50).tag(Tab.alert)
MenuView(isSignout: $isSignout).padding(.bottom, 50).tag(Tab.menu)
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment