Commit 5e4e2e3c authored by shigemi miura's avatar shigemi miura

Merge trial-chat2 into develop

parents 0b014901 9aeb57c1
......@@ -75,8 +75,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 */; };
D51AA4042B099DCD00EBBDD4 /* SignalRService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D51AA4032B099DCD00EBBDD4 /* SignalRService.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 */; };
D5258C992B0334BF00365276 /* SessionShipStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5258C982B0334BF00365276 /* SessionShipStatus.swift */; };
D5258C9B2B03401E00365276 /* MonitoringRoute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5258C9A2B03401E00365276 /* MonitoringRoute.swift */; };
D5258C9D2B03507A00365276 /* ResMonitoringRoute.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5258C9C2B03507A00365276 /* ResMonitoringRoute.swift */; };
......@@ -90,6 +91,9 @@
D52D213A2AEBAC0500324D58 /* HttpRequestType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52D21392AEBAC0500324D58 /* HttpRequestType.swift */; };
D52D213F2AEBB7D700324D58 /* RegisteredEca.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52D213E2AEBB7D700324D58 /* RegisteredEca.swift */; };
D52D21412AEDE18F00324D58 /* EcaCoordinatesTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52D21402AEDE18F00324D58 /* EcaCoordinatesTable.swift */; };
D536F6712B678D8900A5BCF9 /* ReqUploadImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D536F6702B678D8900A5BCF9 /* ReqUploadImage.swift */; };
D5384AFC2B306CEF006228C6 /* TermsView.html in Resources */ = {isa = PBXBuildFile; fileRef = D5384AFB2B306CEF006228C6 /* TermsView.html */; };
D5384AFE2B3121F2006228C6 /* PrivacyView.html in Resources */ = {isa = PBXBuildFile; fileRef = D5384AFD2B3121F2006228C6 /* PrivacyView.html */; };
D53B97262B341867000B3D29 /* AboutAppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D53B97252B341867000B3D29 /* AboutAppView.swift */; };
D545FC742B09C74300F206D0 /* AlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D545FC732B09C74300F206D0 /* AlertManager.swift */; };
D545FC762B09C81300F206D0 /* PushNotificationTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D545FC752B09C81300F206D0 /* PushNotificationTypes.swift */; };
......@@ -128,6 +132,9 @@
D5E008762B2ADD5900C4070A /* MenuManualRADARView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E008752B2ADD5900C4070A /* MenuManualRADARView.swift */; };
D5E008782B2B022200C4070A /* MenuAboutAppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E008772B2B022200C4070A /* MenuAboutAppView.swift */; };
D5E03A672B04484D00D65FCE /* SessionTaskList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E03A662B04484D00D65FCE /* SessionTaskList.swift */; };
D5FCEF552B478985009A81D0 /* ResChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FCEF542B478985009A81D0 /* ResChatMessage.swift */; };
D5FCEF572B4789A8009A81D0 /* ResAckMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FCEF562B4789A8009A81D0 /* ResAckMessage.swift */; };
D5FCEF592B4789D2009A81D0 /* ResChatMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FCEF582B4789D2009A81D0 /* ResChatMode.swift */; };
D6BEB5D3598C619546873CFC /* Pods_Sailassist.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C8118E85BA516EF0E884AA5 /* Pods_Sailassist.framework */; };
/* End PBXBuildFile section */
......@@ -241,8 +248,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>"; };
D51AA4032B099DCD00EBBDD4 /* SignalRService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SignalRService.swift; path = Sailassist/SignalR/SignalRService.swift; sourceTree = SOURCE_ROOT; };
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; };
D5258C982B0334BF00365276 /* SessionShipStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SessionShipStatus.swift; path = Sailassist/ServerSession/SessionShipStatus.swift; sourceTree = SOURCE_ROOT; };
D5258C9A2B03401E00365276 /* MonitoringRoute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MonitoringRoute.swift; path = Sailassist/Map/MonitoringRoute.swift; sourceTree = SOURCE_ROOT; };
D5258C9C2B03507A00365276 /* ResMonitoringRoute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ResMonitoringRoute.swift; path = Sailassist/Json/ResMonitoringRoute.swift; sourceTree = SOURCE_ROOT; };
......@@ -256,6 +264,9 @@
D52D21392AEBAC0500324D58 /* HttpRequestType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HttpRequestType.swift; path = Sailassist/Http/HttpRequestType.swift; sourceTree = SOURCE_ROOT; };
D52D213E2AEBB7D700324D58 /* RegisteredEca.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RegisteredEca.swift; path = Sailassist/ECA/RegisteredEca.swift; sourceTree = SOURCE_ROOT; };
D52D21402AEDE18F00324D58 /* EcaCoordinatesTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = EcaCoordinatesTable.swift; path = Sailassist/ECA/EcaCoordinatesTable.swift; sourceTree = SOURCE_ROOT; };
D536F6702B678D8900A5BCF9 /* ReqUploadImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ReqUploadImage.swift; path = Sailassist/Json/ReqUploadImage.swift; sourceTree = SOURCE_ROOT; };
D5384AFB2B306CEF006228C6 /* TermsView.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = TermsView.html; path = SailAssist/html/TermsView.html; sourceTree = SOURCE_ROOT; };
D5384AFD2B3121F2006228C6 /* PrivacyView.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = PrivacyView.html; path = SailAssist/html/PrivacyView.html; sourceTree = SOURCE_ROOT; };
D53ACA752B0AECF8008DCB18 /* Sailassist.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Sailassist.entitlements; path = Sailassist/Sailassist.entitlements; sourceTree = "<group>"; };
D53B97252B341867000B3D29 /* AboutAppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AboutAppView.swift; path = Sailassist/Login/AboutAppView.swift; sourceTree = SOURCE_ROOT; };
D545FC732B09C74300F206D0 /* AlertManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AlertManager.swift; path = Sailassist/VoiceManager/AlertManager.swift; sourceTree = SOURCE_ROOT; };
......@@ -295,6 +306,9 @@
D5E008752B2ADD5900C4070A /* MenuManualRADARView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MenuManualRADARView.swift; path = Sailassist/Menu/View/MenuManualRADARView.swift; sourceTree = SOURCE_ROOT; };
D5E008772B2B022200C4070A /* MenuAboutAppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MenuAboutAppView.swift; path = Sailassist/Menu/View/MenuAboutAppView.swift; sourceTree = SOURCE_ROOT; };
D5E03A662B04484D00D65FCE /* SessionTaskList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SessionTaskList.swift; path = Sailassist/ServerSession/SessionTaskList.swift; sourceTree = SOURCE_ROOT; };
D5FCEF542B478985009A81D0 /* ResChatMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ResChatMessage.swift; path = Sailassist/Json/ResChatMessage.swift; sourceTree = SOURCE_ROOT; };
D5FCEF562B4789A8009A81D0 /* ResAckMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ResAckMessage.swift; path = Sailassist/Json/ResAckMessage.swift; sourceTree = SOURCE_ROOT; };
D5FCEF582B4789D2009A81D0 /* ResChatMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ResChatMode.swift; path = Sailassist/Json/ResChatMode.swift; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -360,7 +374,6 @@
D5384AFF2B3121FA006228C6 /* html */,
D545FC722B09C6DA00F206D0 /* VoiceManager */,
D51AA4052B099F6D00EBBDD4 /* DataSource */,
D51AA4022B099DA600EBBDD4 /* SignalR */,
D5EA86482AF2139D0032E810 /* Location */,
D52D213B2AEBB78E00324D58 /* ECA */,
D52D21382AEBABE700324D58 /* Http */,
......@@ -495,6 +508,7 @@
020B98622ADD14E40029DE4C /* ChatView.swift */,
02A1DE2D2AFB497B005BCF55 /* View */,
D5258CA42B036F0700365276 /* GetMessage.swift */,
D524DAF72B5A6D3600A399DD /* Imagepicker.swift */,
);
path = Chat;
sourceTree = "<group>";
......@@ -611,6 +625,7 @@
02C3E5CD2AFCA04700AF7837 /* OtherChatContentView.swift */,
02A1DE322AFB654A005BCF55 /* CustomCornerRadius.swift */,
02C3E6082AFDF30000AF7837 /* ChatMemberView.swift */,
D524DAF92B5A6F5F00A399DD /* CameraView.swift */,
);
path = View;
sourceTree = "<group>";
......@@ -690,14 +705,6 @@
path = Pods;
sourceTree = "<group>";
};
D51AA4022B099DA600EBBDD4 /* SignalR */ = {
isa = PBXGroup;
children = (
D51AA4032B099DCD00EBBDD4 /* SignalRService.swift */,
);
path = SignalR;
sourceTree = "<group>";
};
D51AA4052B099F6D00EBBDD4 /* DataSource */ = {
isa = PBXGroup;
children = (
......@@ -763,6 +770,10 @@
D59908C52B19EA70000E13DD /* ResPushHistory.swift */,
025F99732B2C125900C9A18A /* ResGetManualUrl.swift */,
D58EF2462B9044C800FB784C /* ResInformation.swift */,
D5FCEF542B478985009A81D0 /* ResChatMessage.swift */,
D5FCEF562B4789A8009A81D0 /* ResAckMessage.swift */,
D5FCEF582B4789D2009A81D0 /* ResChatMode.swift */,
D536F6702B678D8900A5BCF9 /* ReqUploadImage.swift */,
);
path = Json;
sourceTree = "<group>";
......@@ -987,6 +998,7 @@
02CD06952AE895F5005F8D8F /* APIError.swift in Sources */,
D5B803282B3B988E003B32AD /* AppVersionModel.swift in Sources */,
D592D5232B0F14FE00B91A1C /* SessionUploadImage.swift in Sources */,
D5FCEF552B478985009A81D0 /* ResChatMessage.swift in Sources */,
022A98202AF8B8960079C55A /* LocationCalculation.swift in Sources */,
D5258CA72B03988600365276 /* ReqTaskList.swift in Sources */,
D5CB6F9B2B021C4F00EC2010 /* LocationViewModel.swift in Sources */,
......@@ -999,6 +1011,8 @@
D5AE351D2AEBA6FC00059889 /* SessionLogin.swift in Sources */,
D5258C9F2B03527400365276 /* ResGetMessages.swift in Sources */,
D55135242B15C3BF007B66B1 /* DeleteEcaArea.swift in Sources */,
D524DAFA2B5A6F5F00A399DD /* CameraView.swift in Sources */,
D5FCEF592B4789D2009A81D0 /* ResChatMode.swift in Sources */,
024EDE1B2B0C41E40013BAC8 /* MenuSettingView.swift in Sources */,
020B98552AD924930029DE4C /* QrCodeScannerView.swift in Sources */,
02CE4D7F2ADE42A9002E79BC /* MenuContentView.swift in Sources */,
......@@ -1028,6 +1042,7 @@
D545FC742B09C74300F206D0 /* AlertManager.swift in Sources */,
020B98692ADD221E0029DE4C /* Preferences.swift in Sources */,
D54A5FD72B8F10B500F3A9D6 /* StatusEnum.swift in Sources */,
D536F6712B678D8900A5BCF9 /* ReqUploadImage.swift in Sources */,
02CD06932AE88970005F8D8F /* ServerSession.swift in Sources */,
02A1DE312AFB61D8005BCF55 /* MyChatContentView.swift in Sources */,
D58E1F522B142A3F0092D8FE /* ResEcaArea.swift in Sources */,
......@@ -1035,6 +1050,7 @@
025C27FE2B0206D700BADC49 /* PDFDownloadManager.swift in Sources */,
D59908CA2B1AC381000E13DD /* GetPushHistory.swift in Sources */,
D54D174B2B35137A00A0EAA5 /* LocalWebView.swift in Sources */,
D5FCEF572B4789A8009A81D0 /* ResAckMessage.swift in Sources */,
025C27FC2AFE191A00BADC49 /* MenuManualView.swift in Sources */,
D58E1F502B142A260092D8FE /* EcaArea.swift in Sources */,
020B98592AD92A4C0029DE4C /* MainTabView.swift in Sources */,
......@@ -1058,7 +1074,6 @@
D55135202B15B030007B66B1 /* SetEcaArea.swift in Sources */,
D592D5272B0F182C00B91A1C /* ReqAckMessage.swift in Sources */,
D592D5292B0F198100B91A1C /* ReqChatModeMessage.swift in Sources */,
D51AA4042B099DCD00EBBDD4 /* SignalRService.swift in Sources */,
025C27FA2AFE119D00BADC49 /* MenuTitleView.swift in Sources */,
02CE4D892ADF62E1002E79BC /* EcaSettingView.swift in Sources */,
025F99722B2AE3AF00C9A18A /* TaskViewModel.swift in Sources */,
......@@ -1076,6 +1091,7 @@
020B98472AD8FEE30029DE4C /* ColorSet.swift in Sources */,
D58EF2452B901D3900FB784C /* SessionInformation.swift in Sources */,
D58EF2492B90562B00FB784C /* GetInformation.swift in Sources */,
D524DAF82B5A6D3600A399DD /* Imagepicker.swift in Sources */,
D51AA4072B099FCC00EBBDD4 /* AlertDB.swift in Sources */,
020B98652ADD14F60029DE4C /* NotificationView.swift in Sources */,
);
......
......@@ -11,9 +11,10 @@ struct ChatView: View {
@EnvironmentObject private var selectedTabModel: SelectedTabModel
@ObservedObject var message = SharingData.message
@State var isShowMember: Bool = false
var body: some View {
ZStack {
if message.mode == 1{
if message.mode == true{
LinearGradient(gradient: Gradient(colors: [.chatEmargencyColor1, .chatEmargencyColor2]), startPoint: .top, endPoint: .bottom)
.ignoresSafeArea()
}
......@@ -21,12 +22,14 @@ struct ChatView: View {
ChatTitleView(isShowMember: $isShowMember)
ZStack{
ScrollViewReader { proxy in
ScrollView(.vertical) {
VStack {
Spacer()
.frame(height: 20)
ForEach(message.messages, id: \.messageId) { msg in
if msg.fromId != String(SharingData.my.id){
if msg.from == Preferences.UserName {
//自分のメッセージ
MyChatContentView(message: msg)
.padding(.bottom, 24)
......@@ -37,6 +40,31 @@ struct ChatView: View {
}
}
}
.onAppear {
if let id = message.messages.last?.messageId {
print(debug: "ChatView:onAppear")
proxy.scrollTo(id, anchor: .center)
}
}
.onChange(of: message.messages.count) { newValue in
if let id = message.messages.last?.messageId {
withAnimation {
print(debug: "ChatView:onChange")
proxy.scrollTo(id, anchor: .center)
}
}
}
.onReceive(message.$messages) { (value) in
withAnimation {
guard !value.isEmpty else {return}
if let id = message.messages.last?.messageId {
print(debug: "ChatView:onReceive")
proxy.scrollTo(id, anchor: .center)
}
}
}
}
}
HStack {
Spacer()
VStack{
......@@ -56,10 +84,9 @@ struct ChatView: View {
ChatMemberView()
}
}
}
ChatInputView()
}
}
.background(ColorSet.BackgroundPrimary.color)
}
}
......
......@@ -12,26 +12,31 @@ class GetMessage {
func start() {
print(debug: "called")
sessionGetMessage.RequestGetMessage(responseGetMessage)
}
private func responseGetMessage(result: Result<Data, APIError>) {
print(debug: "called")
switch result {
sessionGetMessage.RequestGetMessage { response in
switch response {
case .success(let resultData):
let serverSession = ServerSession()
let resjson = serverSession.fromJSON(resultData: resultData, resltType: ResGetMessages.self)
if let res = resjson {
SharingData.message.mode = res.mode
if res.mode == 1 {
SharingData.message.mode = true
} else {
SharingData.message.mode = false
}
SharingData.message.messages = []
if let msg = res.messages {
SharingData.message.messages = msg
}
SharingData.message.users = []
if let users = res.users {
SharingData.message.users = users
}
}
case .failure(let errorCode):
print(debug: errorCode)
break
}
}
}
}
//
// Imagepicker.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/19.
//
import SwiftUI
struct Imagepicker : UIViewControllerRepresentable {
@Binding var show: Bool
@Binding var image: Data
var sourceType: UIImagePickerController.SourceType
func makeCoordinator() -> Imagepicker.Coodinator {
return Imagepicker.Coordinator(parent: self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<Imagepicker>) -> UIImagePickerController {
let controller = UIImagePickerController()
controller.sourceType = sourceType
controller.delegate = context.coordinator
return controller
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<Imagepicker>) {
}
class Coodinator: NSObject,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
var parent : Imagepicker
init(parent : Imagepicker){
self.parent = parent
}
//Cancel
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.parent.show.toggle()
}
//Use Photo
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[.originalImage] as! UIImage
let data = image.pngData()
self.parent.image = data!
self.parent.show.toggle()
}
}
}
//
// CameraView.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/19.
//
import SwiftUI
struct CameraView: View {
@Binding var imageData : Data
@Binding var source: UIImagePickerController.SourceType
@Binding var isActionSheet: Bool
@Binding var isImagePicker: Bool
var body: some View {
NavigationStack {
List {
}.navigationDestination(isPresented: $isImagePicker) {
Imagepicker(show: $isImagePicker, image: $imageData, sourceType: source)
}
}
.ignoresSafeArea(.all, edges: .top)
.background(Color.primary.opacity(0.06).ignoresSafeArea(.all, edges: .all))
}
}
......@@ -9,14 +9,69 @@ import SwiftUI
struct ChatInputView: View {
@EnvironmentObject private var sceneDelegate: SceneDelegate
@ObservedObject var sessionUploadImage: SessionUploadImage = SessionUploadImage()
@State var inputText = ""
@State private var selectionValue = 3
@State var isCamera: Bool = false
@State var isPhoto: Bool = false
@State var isImportFile: Bool = false
@State var imageData : Data = .init(capacity:0)
@State var source:UIImagePickerController.SourceType = .photoLibrary
@State var isActionSheet = false
@State var isImagePicker = false
@FocusState var isKeyboard : Bool
var body: some View {
VStack(spacing: 0){
Spacer()
Divider()
HStack(spacing: 10){
Button {
sceneDelegate.tabWindow?.isHidden = true
isCamera = true
source = .camera
isImagePicker.toggle()
} label: {
Image(systemName: "camera")
.resizable()
.frame(width: 24, height: 24)
.padding(10)
}
Menu {
Button(action: {
print("Photo Library")
sceneDelegate.tabWindow?.isHidden = true
isCamera = true
source = .photoLibrary
isImagePicker.toggle()
}) {
Label("Photo Library", systemImage: "photo.on.rectangle")
}
Button(action: {
print("Take Photo")
sceneDelegate.tabWindow?.isHidden = true
isImportFile = true
}) {
Label("Take Phot", systemImage: "camera")
}
Button(action: {
print("Choose File")
sceneDelegate.tabWindow?.isHidden = true
isCamera = true
source = .photoLibrary
isImagePicker.toggle()
}) {
Label("Choose File", systemImage: "folder")
}
} label: {
Image(systemName: "photo")
.resizable()
.frame(width: 24, height: 24)
.padding(10)
}
TextField("", text: $inputText, onEditingChanged: { isEdit in
sceneDelegate.tabWindow?.isHidden = isEdit
})
......@@ -31,7 +86,9 @@ struct ChatInputView: View {
Button{
isKeyboard = false
let signalRService = SignalR()
signalRService.chatMessage(message: inputText)
inputText = ""
} label: {
Image("send")
.resizable()
......@@ -42,8 +99,47 @@ struct ChatInputView: View {
.padding(.trailing, 11)
}
.background(ColorSet.BackgroundSecondary.color)
.fullScreenCover(isPresented: .constant(isImagePicker), onDismiss: {
//シートを閉じる時に実行する処理
sceneDelegate.tabWindow?.isHidden = false
if imageData.count != 0 {
let jpegData = UIImage(data: imageData)!.jpegData(compressionQuality: 1.0)
let uploadImage = ReqUploadImage(shipId: Preferences.shipId, messageId: UUID().uuidString, location: 2, from: Preferences.UserName, fromId: String(SharingData.my.id), files: jpegData!)
sessionUploadImage.RequestUploadImage(uploadImage, completion: responseUploadImage)
}
}, content: {
CameraView(imageData: $imageData, source: $source, isActionSheet: $isActionSheet, isImagePicker: $isImagePicker)
})
.fileImporter(isPresented: $isImportFile, allowedContentTypes: [.png, .jpeg, .pdf]) { result in
switch result {
case .success(let url):
guard let imageData = try? Data(contentsOf: url) else { return }
if imageData.count != 0 {
let jpegData = UIImage(data: imageData)!.jpegData(compressionQuality: 1.0)
let uploadImage = ReqUploadImage(shipId: Preferences.shipId, messageId: UUID().uuidString, location: 2, from: Preferences.UserName, fromId: String(SharingData.my.id), files: jpegData!)
sessionUploadImage.RequestUploadImage(uploadImage, completion: responseUploadImage)
}
case .failure:
print("failure")
}
}
}
.frame(maxHeight: 55)
}
func responseUploadImage(result: Result<Data, APIError>) {
print(debug: "calld")
switch result {
case .success(let resultData):
let serverSession = ServerSession()
let resjson = serverSession.fromJSON(resultData: resultData, resltType: ResLogin.self)
case .failure(let errorCode):
print(debug: errorCode)
break
}
}
}
......
......@@ -8,12 +8,13 @@
import SwiftUI
struct ChatMemberView: View {
var members = ["Yokoyama", "Nogami", "Arahira", "Enokido"]
@ObservedObject var message = SharingData.message
// var members = ["Yokoyama", "Nogami", "Arahira", "Enokido"]
var body: some View {
VStack {
List {
ForEach(members, id: \.self) { member in
Text(member)
ForEach(message.users, id: \.id) { user in
Text(user.name)
.foregroundColor(ColorSet.BodyChat.color)
.font(FontStyle.SupplementText.font)
}
......
......@@ -9,10 +9,10 @@ import SwiftUI
struct ChatTitleView: View {
@Binding var isShowMember: Bool
var body: some View {
@ObservedObject var message = SharingData.message
var body: some View {
VStack {
HStack {
Button{
......@@ -25,11 +25,15 @@ struct ChatTitleView: View {
Spacer()
HStack(spacing: 8) {
VStack{
Text("JMB-Demo(0518)")
Text(SharingData.my.shipName)
.font(FontStyle.TitleL.font)
Text("Yokoyama,Nogami,Arahira,Enokida")
.font(FontStyle.TitleSBold.font)
HStack {
ForEach(message.users, id: \.id) { user in
Text(user.name + ",")
.font(FontStyle.TitleS.font)
}
}
}
.foregroundColor(ColorSet.Body.color)
.frame(width: 162,height: 44)
......
......@@ -13,12 +13,59 @@ struct MyChatContentView: View {
HStack {
Spacer()
VStack(alignment: .trailing, spacing: 6) {
Group {
if message.message.contains("https://") { //TODO: stampIdが0
AsyncImage(url: URL(string: message.message)) { image in
image.resizable()
.frame(width: 200, height: 200)
.contextMenu {
Button(action: {
print("fight")
}) {
Text("Share...")
Image(systemName: "square.and.arrow.up")
}
Button(action: {
print("bag")
}) {
Text("Save to Photos")
Image(systemName: "square.and.arrow.down")
}
Button(action: {
print("pokemon")
}) {
Text("Copy")
Image(systemName: "doc.on.doc")
}
Button(action: {
print("run")
}) {
Text("Copy Subject")
Image(systemName: "circle.dashed.rectangle")
}
Button(action: {
print("run")
}) {
Text("Show Text")
Image(systemName: "text.viewfinder")
}
}
} placeholder: {
ProgressView()
}
} else {
Text(message.message)
.font(FontStyle.DefaultText.font)
.foregroundColor(ColorSet.BodyChat.color)
.padding(15)
.background(ColorSet.ChatBaloon.color)
.cornerRadius(10, corners: [.tl, .tr, .bl])
.cornerRadius(10, corners: [.tl, .tr, .br])
}
}
HStack(spacing: 0){
Text(DateTextLib.ISO86012FormatText(message.time, format: "yyyy/MM/dd hh:mm", errFormat: ""))
......
......@@ -16,12 +16,59 @@ struct OtherChatContentView: View {
.font(FontStyle.EmphasisText.font)
.foregroundColor(ColorSet.Body.color)
VStack(alignment: .leading, spacing: 10) {
Group {
if message.message.contains("https://") { //TODO: stampIdが0
AsyncImage(url: URL(string: message.message)) { image in
image.resizable()
.frame(width: 200, height: 200)
.contextMenu {
Button(action: {
print("fight")
}) {
Text("Share...")
Image(systemName: "square.and.arrow.up")
}
Button(action: {
print("bag")
}) {
Text("Save to Photos")
Image(systemName: "square.and.arrow.down")
}
Button(action: {
print("pokemon")
}) {
Text("Copy")
Image(systemName: "doc.on.doc")
}
Button(action: {
print("run")
}) {
Text("Copy Subject")
Image(systemName: "circle.dashed.rectangle")
}
Button(action: {
print("run")
}) {
Text("Show Text")
Image(systemName: "text.viewfinder")
}
}
} placeholder: {
ProgressView()
}
} else {
Text(message.message)
.font(FontStyle.DefaultText.font)
.foregroundColor(ColorSet.BodyChat.color)
.padding(15)
.background(ColorSet.ChatBaloon.color)
.cornerRadius(10, corners: [.tl, .tr, .br])
}
}
HStack(alignment: .top){
Text(DateTextLib.ISO86012FormatText(message.time, format: "yyyy/MM/dd hh:mm", errFormat: ""))
......@@ -30,6 +77,14 @@ struct OtherChatContentView: View {
}
}
}
.onAppear {
//既読確認
let result = message.viewer.first(where: {$0.id == String(SharingData.my.id)})
if result == nil {
let signalRService = SignalR()
signalRService.ackMessage(messageId: message.messageId)
}
}
.padding(.leading, 20)
Spacer()
}
......
//
// ReqUploadImage.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/29.
//
import Foundation
struct ReqUploadImage : Codable {
var shipId: Int
var messageId: String //UUID
var location: Int //1:Shore、2:Ship
var from: String //投稿者名
var fromId: String //ユーザーID
var files: Data
}
//
// ResAckMessage.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/05.
//
import Foundation
struct ResAckMessage: Codable {
var shipId: Int
var messageId: String //UUID
var time: String //投稿日時
var location: Int //1:Shore、2:Ship
var fromId: String //ユーザーID
}
//
// ResChatMessage.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/05.
//
import Foundation
struct ResChatMessage: Codable {
var shipId: Int
var messageId: String //UUID
var type: Int //0:テキスト、1:スタンプ
var time: String //投稿日時
var location: Int //1:Shore、2:Ship
var from: String //投稿者名
var fromId: String //ユーザーID
var message: String //テキスト
var stampId: Int //スタンプ番号
}
//
// ResChatMode.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/05.
//
import Foundation
struct ResChatMode: Codable {
var shipId: Int
var time: String //投稿日時
var location: Int //1:Shore、2:Ship
var fromId: String //ユーザーID
var mode: Int //0:通常、1:Warning中
}
......@@ -10,16 +10,17 @@ import Foundation
struct ResGetMessages: Codable {
var mode: Int // 0:通常 , 1:Warning中
var messages: [ChatMessage]?
var users: [ChatUser]?
}
struct ChatMessage: Codable {
var shipId: UInt
var shipId: Int
var messageId: String //各メッセージ固有ID
var type: Int //0:テキスト , 1:スタンプ , 2:画像
var time: String //投稿日時
var location: Int //1:Shore , 2:Ship
var from: String //投稿者名
var fromId: String //ユーザーID
var fromId: String? //ユーザーID
var message: String //テキスト時:テキスト , 画像時:サムネイルのUri
var stampId: Int //スタンプ番号 0:Fire~
var viewer: [Viewer] //閲覧者情報
......@@ -30,3 +31,10 @@ struct Viewer: Codable {
var location: Int //1:Shore , 2:Ship
var id: String //ユーザーID
}
struct ChatUser: Codable {
var time: String //最終アクセス日時
var location: Int //1:Shore , 2:Ship
var id: String //ログイン時のデバイスID
var name: String //ユーザー名
}
......@@ -17,10 +17,12 @@ struct MapRepresentable: UIViewControllerRepresentable{
@ObservedObject var pushHistory = SharingData.pushHistory
@State var mapVC = MapViewController()
//作成したいViewControllerを返すメソッド
func makeUIViewController(context: Context) -> some UIViewController {
mapVC
}
//Viewが更新された場合に必要な処理を実装
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
let ecaArea = ecaData.ecaArea.map{ $0.1 }.filter{ $0.isRunning }.first
if let ecaArea = ecaArea{
......@@ -29,6 +31,7 @@ struct MapRepresentable: UIViewControllerRepresentable{
mapVC.removeEcaLine()
}
//ECA領域を画面中央に表示
if let focusEcaAreaId = ecaData.focusEca, let focusEca = ecaData.ecaArea[focusEcaAreaId]{
mapVC.updateCamera(location: focusEca.centerPosition, zoomlevel: focusEca.zoomLevel)
mapVC.updateOneTimeEca(eca: focusEca.points)
......@@ -38,6 +41,7 @@ struct MapRepresentable: UIViewControllerRepresentable{
}
}
//通知場所を画面中央に表示
if let focusPushHistoryId = pushHistory.focusPushHistory, let focusPushHistory = pushHistory.pushHistoryData[focusPushHistoryId]{
if let position = focusPushHistory.position {
if let latitude = position.lat, let longitude = position.lon {
......
......@@ -13,7 +13,6 @@ class GetManualUrl {
func start() {
print(debug: "called")
sessionGetManualUrl.getManualUrl { response in
print(debug: "called")
switch response {
case .success(let resultData):
print(debug: String(data: resultData, encoding: .utf8) as Any)
......
......@@ -221,7 +221,7 @@ struct MenuView: View {
loginViewModel.isLogin = false
sceneDelegate.tabWindow?.isHidden = true
SharingData.message.mode = 0
SharingData.message.mode = false
SharingData.message.messages = []
SharingData.pushHistory.focusPushHistory = nil
......@@ -231,6 +231,8 @@ struct MenuView: View {
SharingData.map.legLine = []
SharingData.map.portLine = []
SharingData.map.starboardLine = []
connection!.stop()
}
Button("No") {}
} message: { Text("Are you sure?") }
......
......@@ -8,6 +8,7 @@
import SwiftUI
import UserNotifications
import WindowsAzureMessaging
import SwiftSignalRClient
@main
struct SailassistApp: App {
......@@ -16,7 +17,7 @@ struct SailassistApp: App {
@State private var isPrivAgree = Preferences.privacyPolicyAgreeDate != nil
let locationViewModel = LocationViewModel()
let signalRService = SignalRService()
var body: some Scene {
WindowGroup {
if !isTermsAgree{
......@@ -66,14 +67,17 @@ class NotificationTags: NSObject {
let bamTag = "bam-" + shipId
let taskAlertTag = "taskalert-" + shipId
let sailassistTag = "sailassist-" + shipId
let chatTag = "chat-" + shipId
let emergencyTag = "emergency-" + shipId
// let chatTag = "chat-" + shipId
MSNotificationHub.addTags([routeTag, bamTag, taskAlertTag, sailassistTag, emergencyTag])
MSNotificationHub.addTags([routeTag, bamTag, taskAlertTag, sailassistTag, emergencyTag, chatTag])
}
}
}
var connection: HubConnection?
class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, MSInstallationLifecycleDelegate {
private var hubConnectionDelegate: HubConnectionDelegate?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print(debug: "called")
......@@ -100,6 +104,34 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
Preferences.DeviceId = UUID().uuidString
}
//SignalR初期化
hubConnectionDelegate = ChatHubConnectionDelegate(app: self)
connection = HubConnectionBuilder(url: URL(string : HttpRequestType.SignalR.rawValue)!)
.withHubConnectionDelegate(delegate: hubConnectionDelegate!)
.withAutoReconnect()
// .withLogging(minLogLevel: .error)
.withLogging(minLogLevel: .debug)
// .withHubConnectionOptions(configureHubConnectionOptions: {options in options.keepAliveInterval = 20 })
.build()
if let r_connection = connection {
r_connection.stop()
r_connection.on(method: "chatMessage", callback: { (message: ResChatMessage) in
self.handleChatMessage(message: message)
})
r_connection.on(method: "ackMessage", callback: { (message: ResAckMessage) in
self.handleAckMessage(message: message)
})
r_connection.on(method: "chatMode", callback: { (message: ResChatMode) in
self.handleChatMessage(message: message)
})
r_connection.start()
}
return true
}
......@@ -122,8 +154,8 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
// Push通知を受信した時(サイレントプッシュ)
func notificationHub(_ notificationHub: MSNotificationHub, didReceivePushNotification notification: MSNotificationHubMessage) {
// let title = notification.title ?? ""
// let body = notification.body ?? ""
// let title = notification.title ?? ""
// let body = notification.body ?? ""
let userInfo = notification.userInfo
print(debug: "called \(String(describing: userInfo))")
......@@ -143,6 +175,115 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("APNs 登録に失敗しました : \(error.localizedDescription)")
}
private func handleChatMessage(message: ResChatMessage) {
print(debug: "called")
// print(debug: "called \(ResMessage)")
}
private func handleAckMessage(message: ResAckMessage) {
print(debug: "called")
// print(debug: "called \(ResAckMessage)")
}
private func handleChatMessage(message: ResChatMode) {
print(debug: "called")
// print(debug: "called \(ResChatMode)")
}
// func applicationWillTerminate(_ aNotification: Notification) {
// connection.stop()
// }
}
class SignalR: NSObject {
@ObservedObject var msg = SharingData.message
func chatMessage(message: String) {
var request = ReqMessage(shipId: Preferences.shipId, messageId: UUID().uuidString)
request.type = 0 //0:テキスト, 1:スタンプ
request.time = DateTextLib.Date2ISO8601Text(Date())
request.location = 2 //1:Shore , 2:Ship
request.from = Preferences.UserName //投稿者名
request.fromeId = String(SharingData.my.id) //ユーザーID
request.message = message //テキスト
request.stampId = 0 //スタンプ番号 0:Fire~
if message != "" {
connection!.invoke(method: "chatMessage", request) { error in
if let e = error {
print(debug: "Error:\(e)")
}
let viewer = Viewer(time: "", location: 0, id: "")
let ownMsg = ChatMessage(shipId: request.shipId, messageId: request.messageId, type: request.type, time: request.time, location: request.location, from: request.from, message: request.message, stampId: request.stampId, viewer: [viewer])
self.msg.messages.append(ownMsg)
}
}
}
func ackMessage(messageId: String) {
var request = ReqAckMessage(shipId: Preferences.shipId, messageId: messageId)
request.time = DateTextLib.Date2ISO8601Text(Date())
request.location = 2 //1:Shore , 2:Ship
request.fromeId = String(SharingData.my.id) //ユーザーID
if messageId != "" {
connection!.invoke(method: "ackMessage", request) { error in
if let e = error {
print(debug: "Error:\(e)")
}
}
}
}
func chatMode(mode: Bool) {
var request = ReqChatModeMessage(shipId: Preferences.shipId)
request.time = DateTextLib.Date2ISO8601Text(Date())
request.location = 2 //1:Shore , 2:Ship
request.fromeId = String(SharingData.my.id) //ユーザーID
if mode == true{
request.mode = 1
} else {
request.mode = 0
}
connection!.invoke(method: "chatMode", request) { error in
if let e = error {
print(debug: "Error:\(e)")
}
}
}
}
class ChatHubConnectionDelegate: HubConnectionDelegate {
weak var app: AppDelegate?
init(app: AppDelegate) {
self.app = app
}
func connectionDidOpen(hubConnection: HubConnection) {
print(debug: "connectionDidOpen")
// app?.connectionDidStart()
}
func connectionDidFailToOpen(error: Error) {
print(debug: "connectionDidFailToOpen")
// app?.connectionDidFailToOpen(error: error)
}
func connectionDidClose(error: Error?) {
print(debug: "connectionDidClose")
// app?.connectionDidClose(error: error)
}
func connectionWillReconnect(error: Error) {
print(debug: "connectionWillReconnect")
// app?.connectionWillReconnect(error: error)
}
func connectionDidReconnect() {
print(debug: "connectionDidReconnect")
// app?.connectionDidReconnect()
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
......@@ -157,19 +298,19 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
return
}
completionHandler([[.banner, .badge, .sound]])
let arrCategory = arrAPS["category"] as? String ?? ""
switch arrCategory {
// case "chat":
// guard let arrAlert = arrAPS["alert"] as? [String: Any] else {
// return
// }
// let subtitle = arrAlert["subtitle"] as? String ?? "" //送信先名称
// let strTitle = arrAlert["title"] as? String ?? "" //送信内容
// let strBody = arrAlert["body"] as? String ?? "" //船名
// let message = GetMessage()
// message.start()
case "chat":
guard let arrAlert = arrAPS["alert"] as? [String: Any] else {
completionHandler([[.banner, .badge, .sound]])
return
}
let subtitle = arrAlert["subtitle"] as? String ?? "" //送信先名称
let strTitle = arrAlert["title"] as? String ?? "" //船名
let strBody = arrAlert["body"] as? String ?? "" //送信内容
let message = GetMessage()
message.start()
case "sailassist":
print(debug: "sailassist")
let getPushHistory = GetPushHistory()
......@@ -204,19 +345,19 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
return
}
completionHandler()
let arrCategory = arrAPS["category"] as? String ?? ""
switch arrCategory {
// case "chat":
// guard let arrAlert = arrAPS["alert"] as? [String: Any] else {
// return
// }
// let subtitle = arrAlert["subtitle"] as? String ?? "" //送信先名称
// let strTitle = arrAlert["title"] as? String ?? "" //送信内容
// let strBody = arrAlert["body"] as? String ?? "" //船名
// let message = GetMessage()
// message.start()
case "chat":
guard let arrAlert = arrAPS["alert"] as? [String: Any] else {
completionHandler()
return
}
let subtitle = arrAlert["subtitle"] as? String ?? "" //送信先名称
let strTitle = arrAlert["title"] as? String ?? "" //船名
let strBody = arrAlert["body"] as? String ?? "" //送信内容
let message = GetMessage()
message.start()
case "sailassist":
print(debug: "sailassist")
let getPushHistory = GetPushHistory()
......@@ -269,7 +410,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, ObservableObject {
}
}
class PassThroughWindow: UIWindow{
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let view = super.hitTest(point, with: event) else { return nil}
......
......@@ -79,6 +79,50 @@ class ServerSession{
}).resume()
}
func postForm(boundary: String, _ req_url : URL, _ postdata : Data, completion: @escaping (SessionResponse) -> Void){
var req = URLRequest(url: req_url)
req.httpMethod = "POST"
req.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
req.setValue("\(postdata.count)", forHTTPHeaderField: "Content-Length")
req.httpBody = postdata
req.timeoutInterval = 20 // タイムアウト3秒 → Amedasでタイムアウトエラー20秒に変更
// サーバー送信
let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main)
session.dataTask(with: req, completionHandler: {(data, response, error) in
session.finishTasksAndInvalidate()
do{
if error != nil{
throw APIError.clientError
}
guard let indata = data, let inresponse = response as? HTTPURLResponse else {
throw APIError.responseError
}
if inresponse.statusCode != 200 {
throw APIError.serverError
}
//Cookieを保存
if let fields = inresponse.allHeaderFields as? [String: String], let url = inresponse.url {
for cookie in HTTPCookie.cookies(withResponseHeaderFields: fields, for: url) {
HTTPCookieStorage.shared.setCookie(cookie)
}
}
DispatchQueue.main.async {
completion(.success(indata))
}
}catch{
if error as? APIError != nil{
completion(.failure(error as! APIError))
}
else{
completion(.failure(.unknown))
}
}
}).resume()
}
func getJson(_ req_url : URL, completion: @escaping (SessionResponse) -> Void){
var req = URLRequest(url: req_url)
......@@ -164,4 +208,44 @@ class ServerSession{
}
return false
}
func httpBody(boundary: String, _ uploadImage : ReqUploadImage) -> Data! {
var httpBody1 = "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"shipId\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(uploadImage.shipId)\r\n"
httpBody1 += "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"messageId\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(uploadImage.messageId)\r\n"
httpBody1 += "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"location\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(uploadImage.location)\r\n"
httpBody1 += "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"from\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(uploadImage.from)\r\n"
httpBody1 += "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"fromId\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(uploadImage.fromId)\r\n"
httpBody1 += "--\(boundary)\r\n"
// httpBody1 += "Content-Disposition: form-data; name=\"files\"; filename=\"\(uploadImage.files)\"\r\n"
httpBody1 += "Content-Type: image/jpeg\r\n"
httpBody1 += "\r\n"
// var tmp = httpBody1.data(using: .utf8)!
var httpBody = Data()
httpBody.append(httpBody1.data(using: .utf8)!)
httpBody.append(uploadImage.files)
var httpBody2 = "\r\n"
httpBody2 += "--\(boundary)--\r\n"
httpBody.append(httpBody2.data(using: .utf8)!)
return httpBody
}
}
......@@ -19,7 +19,7 @@ class SessionUploadImage : ObservableObject {
/**
* メッセージ
*/
func RequestGetUploadImage(_ completion: @escaping ((Result<Data, APIError>)) -> Void) {
func RequestUploadImage(_ uploadImage : ReqUploadImage ,completion: @escaping ((Result<Data, APIError>)) -> Void) {
print(debug: "calld")
if Calling {
return
......@@ -27,19 +27,20 @@ class SessionUploadImage : ObservableObject {
Calling = true
// リクエストURLの組み立て
// リクエストURLの組み立て
// let url_string : String = HttpRequestType.UploadImage.rawValue
// guard let req_url = URL(string : url_string) else {
// Calling = false
// return
// }
let url_string : String = HttpRequestType.UploadImage.rawValue
guard let req_url = URL(string : url_string) else {
Calling = false
return
}
// if let postdata = serverSession.toJSON(login) {
// serverSession.postJson(req_url, postdata, completion: completion)
// }
// else {
// Calling = false
// return
// }
// let boundary = "----------" + UUID().uuidString
let boundary = "----WebKitFormBoundaryZLdHZy8HNaBmUX0d"
if let postdata = serverSession.httpBody(boundary: boundary, uploadImage) {
serverSession.postForm(boundary: boundary, req_url, postdata, completion: completion)
}
else {
Calling = false
return
}
}
}
......@@ -116,8 +116,13 @@ class SharingData{
static var message = Message()
class Message: ObservableObject {
@Published var mode: Int = 0 // 0:通常 , 1:Warning中
@Published var mode: Bool = false // false:通常 , true:Warning中
@Published var messages: [ChatMessage] = []
@Published var users: [ChatUser] = []
func changeMode(){
self.mode.toggle()
}
}
static var information = Information()
......
//
// SignalRService.swift
// Sailassist
//
// Created by 三浦薫巳 on 2023/11/17.
//
import Foundation
import SwiftSignalRClient
public class SignalRService {
private var connection: HubConnection
private var hubConnectionDelegate: HubConnectionDelegate?
public init() {
// hubConnectionDelegate = ChatHubConnectionDelegate(app: self)
hubConnectionDelegate = ChatHubConnectionDelegate()
connection = HubConnectionBuilder(url: URL(string : HttpRequestType.SignalR.rawValue)!)
.withHubConnectionDelegate(delegate: hubConnectionDelegate!)
.withAutoReconnect()
.withLogging(minLogLevel: .error).build()
connection.on(method: "chatMessage", callback: { (shipId: Int, messageId: Int, type: Int, time: String, location: Int, from: String, fromeId: Int, message: String) in
self.handleChatMessage(message, from: from)
})
connection.on(method: "ackMessage", callback: { (shipId: Int, time: String, location: Int, fromId: Int, mode: Int) in
self.handleAckMessage(time)
})
connection.on(method: "chatMode", callback: { (shipId: Int, time: String, location: Int, fromId: String, mode: Int) in
self.handleChatMessage(fromId)
})
connection.start()
}
private func handleChatMessage(_ message: String, from user: String) {
print(debug: "called")
}
private func handleAckMessage(_ time: String) {
print(debug: "called")
}
private func handleChatMessage(_ fromId: String) {
print(debug: "called")
}
func applicationWillTerminate(_ aNotification: Notification) {
connection.stop()
}
//呼び出す
func chatMessage(_ message: String) {
var request = ReqMessage(shipId: Preferences.shipId, messageId: "aaaa")
request.type = 0 //0:テキスト, 1:スタンプ
// request.time = DateTextLib.Date2ISO8601Text(date: Date())
request.location = 2 //1:Shore , 2:Ship
request.from = Preferences.UserName //投稿者名
// request.fromeId = SharingData.my.shipName //ユーザーID
request.message = message //テキスト
// request.stampId = //スタンプ番号 0:Fire~
if message != "" {
connection.invoke(method: "ChatMessage", message) { error in
if let e = error {
print(debug: "Error:\(e)")
}
}
}
}
func ackMessage(_ message: String) {
var request = ReqAckMessage(shipId: Preferences.shipId, messageId: "aaaa")
//request.time = DateTextLib.Date2ISO8601Text(date: Date())
request.location = 2 //1:Shore , 2:Ship
// request.fromeId = SharingData.my.shipName //ユーザーID
if message != "" {
connection.invoke(method: "AckMessage", request) { error in
if let e = error {
print(debug: "Error:\(e)")
}
}
}
}
func chatMode(_ message: String) {
var request = ReqChatModeMessage(shipId: Preferences.shipId)
// request.time = DateTextLib.Date2ISO8601Text(date: Date())
request.location = 2 //1:Shore , 2:Ship
// request.fromeId = SharingData.my.shipName //ユーザーID
request.mode = 0 //0:通常 / 1:Warning中
if message != "" {
connection.invoke(method: "ChatMode", message) { error in
if let e = error {
print(debug: "Error:\(e)")
}
}
}
}
// func chatMode2(_ message: String) {
// connection.send(method: "Broadcast", "Playground user", "Testing send") { error in
// if let error = error {
// print("Send failed: \(error)")
// }
// }
// }
}
class ChatHubConnectionDelegate: HubConnectionDelegate {
// weak var app: AppDelegate?
//
// init(app: AppDelegate) {
// self.app = app
// }
func connectionDidOpen(hubConnection: HubConnection) {
print("connectionDidOpen")
// After connection established call registerUserInServer method
DispatchQueue.main.async {
// self.registerUserInServer()
}
}
func connectionDidFailToOpen(error: Error) {
print("connectionDidFailToOpen")
}
func connectionDidClose(error: Error?) {
print("connectionDidClose")
}
func connectionWillReconnect(error: Error) {
print("connectionWillReconnect")
}
func connectionDidReconnect() {
print("connectionDidReconnect")
}
}
......@@ -122,12 +122,20 @@ struct CustomTabBar: View {
}
}, label: {
VStack{
ZStack(alignment: .bottomTrailing) {
Image(selectedTabModel.activeTab == tab ? tab.rawValue + "_selected" : tab.rawValue)
.font(.title2)
// if tab == Tab.chat {
// Rectangle()
// .foregroundColor(.red)
// .frame(width: 12, height: 12)
// .cornerRadius(60)
// }
}
Text(tab.title)
.font(.caption)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.contentShape(.rect)
......@@ -140,11 +148,9 @@ struct CustomTabBar: View {
.background(ColorSet.BottomNav.color)
.alert("", isPresented: $selectedTabModel.isShowChangeEmrMode) {
Button("Yes"){
if SharingData.message.mode == 0{
SharingData.message.mode = 1
}else{
SharingData.message.mode = 0
}
SharingData.message.changeMode()
let signalRService = SignalR()
signalRService.chatMode(mode: SharingData.message.mode)
}
Button("No"){
......
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