[] 채팅 페이지 작업 중

This commit is contained in:
Seonkyu_Kim 2025-02-14 17:51:08 +09:00
parent c6f224a9d9
commit 875f92c81b
18 changed files with 304 additions and 78 deletions

View File

@ -20,11 +20,6 @@ struct BoxBtnView<Content: View>: View {
action() action()
} label: { } label: {
content content
// if let image = image {
// image
// .resizable()
// .frame(width: width, height: height)
// }
} }
} }
} }

View File

@ -38,10 +38,8 @@ struct CircleBtnView: View {
if let title = state.text, let font = state.font { if let title = state.text, let font = state.font {
Text("\(title)") Text("\(title)")
.font(font) .font(font)
.lineLimit(1)
.minimumScaleFactor(0.5)
.truncationMode(.tail)
.foregroundStyle(state.foreColor) .foregroundStyle(state.foreColor)
.multilineStyle()
} }
} }
} }

View File

@ -18,10 +18,7 @@ struct SimpleBtnView: View {
if let title = state.text, let font = state.font { if let title = state.text, let font = state.font {
Text("\(title)") Text("\(title)")
.font(font) .font(font)
.lineLimit(1) .multilineStyle(.center)
.minimumScaleFactor(0.5)
.multilineTextAlignment(.center)
.truncationMode(.tail)
.foregroundStyle(state.textColor) .foregroundStyle(state.textColor)
.frame(width: state.width, height: state.height) .frame(width: state.width, height: state.height)
.onTapGesture { .onTapGesture {

View File

@ -50,20 +50,21 @@ struct AttCellView: View {
.padding(.top,4) .padding(.top,4)
HStack(alignment: .center, spacing: 2) { HStack(alignment: .center, spacing: 2) {
Spacer() Spacer()
Text("\(valueGroup.0)").font(.nps(font: .bold, size: 20)) Text("\(valueGroup.0)")
.font(.nps(font: .bold, size: 20))
.foregroundStyle(((Double(valueGroup.0)/Double(valueGroup.1)) < 0.7) ? Color(.Other.red) : Color(.Other.blue)) .foregroundStyle(((Double(valueGroup.0)/Double(valueGroup.1)) < 0.7) ? Color(.Other.red) : Color(.Other.blue))
.frame(width: 28,alignment: .center) .frame(width: 28,alignment: .center)
Text("/").font(.nps(size: 12)) Text("/")
.font(.nps(size: 12))
.foregroundStyle(Color(.Text.detail)) .foregroundStyle(Color(.Text.detail))
Text("\(valueGroup.1)").font(.nps(font: .bold, size: 20)) Text("\(valueGroup.1)")
.font(.nps(font: .bold, size: 20))
.foregroundStyle(Color(.Text.detail)) .foregroundStyle(Color(.Text.detail))
.frame(width: 28,alignment: .center) .frame(width: 28,alignment: .center)
Text("\(cellText.group)") Text("\(cellText.group)")
.font(.nps(size: 16)) .font(.nps(size: 16))
.foregroundStyle(Color(.Text.detail)) .foregroundStyle(Color(.Text.detail))
.lineLimit(1) .multilineStyle()
.minimumScaleFactor(0.5)
.truncationMode(.tail)
} }
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
} }

View File

@ -48,9 +48,7 @@ struct CalCellView: View {
Text("\(summaryCalData.summary)") Text("\(summaryCalData.summary)")
.font(.nps(size: 20)) .font(.nps(size: 20))
.foregroundStyle(Color(.Text.black)) .foregroundStyle(Color(.Text.black))
.lineLimit(1) .multilineStyle()
.minimumScaleFactor(0.5)
.truncationMode(.tail)
} }
} }

View File

@ -14,7 +14,6 @@ struct HomeView: View {
@State private var topViewState: Bool = false @State private var topViewState: Bool = false
//MARK: - //MARK: -
// @State private var myType: UserType = .Student
@Binding var myType: UserType @Binding var myType: UserType
var body: some View { var body: some View {
@ -116,21 +115,3 @@ struct HomeView: View {
} }
struct EmptyBoxView: View {
let title: String
var body: some View {
Text("\(title)")
.font(.nps(size: 20))
.foregroundStyle(Color(.Text.detail))
.lineLimit(1)
.minimumScaleFactor(0.5)
.truncationMode(.tail)
.frame(maxWidth: .infinity)
.padding([.top,.bottom],12)
.background {
RoundedRectangle(cornerRadius: 4)
.stroke(Color(.Second.normal), lineWidth: 2)
.fill(Color(.Second.light))
}
}
}

View File

@ -48,20 +48,17 @@ struct TopProfileView: View {
.padding([.top, .bottom], 40) .padding([.top, .bottom], 40)
VStack(alignment: .center, spacing: 8) { VStack(alignment: .center, spacing: 8) {
Text("\(self.academyName)") Text("\(self.academyName)")
.frame(alignment: .center)
.font(.nps(font: .bold, size: 36)) .font(.nps(font: .bold, size: 36))
.foregroundStyle(Color(.Text.title)) .foregroundStyle(Color(.Text.title))
.lineLimit(1) .multilineStyle()
.minimumScaleFactor(0.5)
.truncationMode(.tail)
Text("\(self.myName)")
.multilineTextAlignment(.center)
.frame(alignment: .center) .frame(alignment: .center)
Text("\(self.myName)")
.font(.nps(size: 18)) .font(.nps(size: 18))
.foregroundStyle(Color(.Text.detail)) .foregroundStyle(Color(.Text.detail))
.lineLimit(1) .multilineStyle()
.minimumScaleFactor(0.5) .frame(alignment: .center)
.truncationMode(.tail)
} }
} /// VStack } /// VStack
.padding(EdgeInsets(top: 24, leading: 24, bottom: 12, trailing: 24)) .padding(EdgeInsets(top: 24, leading: 24, bottom: 12, trailing: 24))

View File

@ -0,0 +1,89 @@
//
// ChatListView.swift
// AcaMate
//
// Created by TAnine on 2/14/25.
//
import SwiftUI
struct ChatListView: View {
var chatList: [SummaryChat]
var body: some View {
VStack(spacing: 10) {
ForEach(Array(chatList.enumerated()), id:\.offset) { index, chat in
ChatCellView(summaryChat: chat)
}
}
}
}
struct ChatCellView: View {
var summaryChat: SummaryChat
var body: some View {
VStack(spacing: 8) {
HStack(alignment: .bottom, spacing: 4) {
Image(.Icon.chatting).resizable()
.frame(width: 24, height: 24, alignment: .center)
Text("\(summaryChat.chatName)")
.font(.nps(size: 20))
.foregroundStyle(Color(.Text.detail))
.multilineStyle()
if summaryChat.groupNum > 0 {
HStack(alignment: .center, spacing: 0) {
Image(.Icon.person).resizable()
.frame(width: 12, height: 12, alignment: .center)
Text("\(summaryChat.groupNum)")
.font(.nps(size: 8))
.foregroundStyle(Color(.Text.detail))
}
// .frame(height: 24)
}
Spacer(minLength: 1)
HStack(alignment: .bottom, spacing: 4) {
Image(summaryChat.notiState ? .Icon.notificationON : .Icon.notificationOFF).resizable()
.frame(width: 12, height: 12, alignment: .center)
Text("\(summaryChat.teacherName)")
.font(.nps(font: .bold, size: 12))
.foregroundStyle(Color(.Text.detail))
Text("선생님")
.font(.nps(size: 8))
.foregroundStyle(Color(.Text.detail))
}
}
Text("\(summaryChat.lastMessage)")
.font(.nps(size: 10))
.foregroundStyle(Color(.Text.detail))
.multilineStyle(limit: 2, scale: 1)
.padding(.trailing, 8)
HStack(alignment: .bottom, spacing: 4) {
Spacer(minLength: 1)
Group {
Text("\(summaryChat.dayDate)")
.font(.nps(size: 8))
Text("\(summaryChat.timeDate)")
.font(.nps(font: .bold, size: 12))
}
.foregroundStyle(Color(.Text.detail))
}
}
.padding(EdgeInsets(top: 8, leading: 12, bottom: 8, trailing: 12))
.background {
RoundedRectangle(cornerRadius: 4)
.stroke(Color(.Second.normal), lineWidth: 2)
.fill(Color(.Second.light))
}
.onTapGesture {
printLog("채팅 내부 셀 클릭")
// MARK: TO-DO
}
}
}

View File

@ -9,38 +9,111 @@ import SwiftUI
struct ChattingView: View { struct ChattingView: View {
@StateObject private var topVM = TopViewModel() @StateObject private var topVM = TopViewModel()
@StateObject private var btnVM = ButtonViewModel()
@State private var scrollOffset: CGPoint = .zero @State private var scrollOffset: CGPoint = .zero
@State private var leftBtnID = UUID()
@State private var rightBtnID = UUID()
let classList = [
SummaryChat(id: "00", chatName: "Class 101", teacherName: "홍길동",
lastMessage: "여기에는 채팅이 나올 예정입니다. 2줄 정도로 나올 예정이며 끝자리는 잘려서 나올 것 입니다. 이정도의 채팅으로는 택도 없어서 조금 더 길게 길게 작성을 해봅니다.",
dayDate: "2025. 02. 14", timeDate: "PM 11:00", notiState: true, groupNum: 12),
SummaryChat(id: "01", chatName: "Class 101", teacherName: "홍길동",
lastMessage: "여기에는 채팅이 나올 예정입니다. 2줄 정도로 나올 예정이며 끝자리는 잘려서 나올 것 입니다. 이정도의 채팅으로는 택도 없어서 조금 더 길게 길게 작성을 해봅니다.",
dayDate: "2025. 02. 14", timeDate: "PM 11:00", notiState: false, groupNum: 12),
SummaryChat(id: "02", chatName: "Class 101", teacherName: "홍길동",
lastMessage: "여기에는 채팅이 나올 예정입니다. 2줄 정도로 나올 예정이며 끝자리는 잘려서 나올 것 입니다. 이정도의 채팅으로는 택도 없어서 조금 더 길게 길게 작성을 해봅니다.",
dayDate: "2025. 02. 14", timeDate: "PM 11:00", notiState: true, groupNum: 12)
]
//MARK: -
@Binding var myType: UserType
@State var chatMenu: chatType = .Class
var body: some View { var body: some View {
VStack(spacing: 0) { VStack(spacing: 0) {
TopView(topVM: topVM) TopView(topVM: topVM)
if myType == .ETC || myType == .Employee {
OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in EmptyBoxView(title: "이용하실 수 없는 기능입니다.")
VStack(spacing: 24) { .padding(24)
Group { Spacer(minLength: 1)
DashBoardView(image: Image(.Icon.group), title: "클래스") { } else {
if myType == .Teacher || myType == .Admin {
if myType == .Admin {
HStack {
SimpleBtnView(vm: btnVM, id: leftBtnID)
Spacer(minLength: 1)
Text("선생님 이름")
.font(.nps(font: .bold, size: 24))
.foregroundStyle(Color(.Text.detail))
Spacer(minLength: 1)
SimpleBtnView(vm: btnVM, id: rightBtnID)
} }
DashBoardView(image: Image(.Icon.talk), title: "선생님과 1:1") { .padding(EdgeInsets(top: 12, leading: 24, bottom: 0, trailing: 24))
}
} HStack {
} SelectChatMenu(chatMenu: $chatMenu, tag: .Class, image: Image(.Icon.group), title: "클래스")
.background { Spacer(minLength: 1)
RoundedRectangle(cornerRadius: 8) SelectChatMenu(chatMenu: $chatMenu, tag: .Student, image: Image(.Icon.talk), title: "학생")
.foregroundStyle(Color(.Other.cell)) Spacer(minLength: 1)
SelectChatMenu(chatMenu: $chatMenu, tag: .Parent, image: Image(.Icon.talk), title: "학부모")
} }
.padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
} }
.padding(24) OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in
VStack(spacing: 24) {
Group {
if myType != .Parent {
DashBoardView(image: Image(.Icon.group), title: "클래스") {
ChatListView(chatList: classList)
}
}
if myType != .Teacher || myType != .Admin {
DashBoardView(image: Image(.Icon.talk), title: "선생님과 1:1") {
}
}
if myType == .Teacher {
DashBoardView(image: Image(.Icon.talk), title: "부모님과 1:1") {
}
}
}
.background {
RoundedRectangle(cornerRadius: 8)
.foregroundStyle(Color(.Other.cell))
}
}
.padding(EdgeInsets(
top: (myType == .Student || myType == .Parent) ? 24 : 12, leading: 24, bottom: 24, trailing: 24))
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
} }
.frame(maxWidth: .infinity, maxHeight: .infinity)
} }
.onAppear { .onAppear {
topVM.titleName = "" // MARK: TO-DO
topVM.setLeftBtn(size: CGPoint(x: 40, y: 40), action: leftAct) //
topVM.titleName = "Name"
if myType == .Student {
topVM.setLeftBtn(Image(.Icon.face), size: CGPoint(x: 40, y: 40), action: leftAct)
} else {
topVM.setLeftBtn(text: "\(myType.rawValue)", font: .nps(font: .bold, size: 24),
size: CGPoint(x: 40, y: 40), action: leftAct)
}
topVM.setRightBtn(size: CGPoint(x: 40, y: 40), action: rightAct) topVM.setRightBtn(size: CGPoint(x: 40, y: 40), action: rightAct)
btnVM.setImage(for: leftBtnID, newImage: Image(.Icon.left))
btnVM.setImage(for: rightBtnID, newImage: Image(.Icon.right))
btnVM.setSize(for: leftBtnID, newWidth: 24, newHeight: 24)
btnVM.setSize(for: rightBtnID, newWidth: 24, newHeight: 24)
} }
} }
@ -52,3 +125,41 @@ struct ChattingView: View {
} }
} }
struct SelectChatMenu: View {
@Binding var chatMenu: chatType
let tag: chatType
let image: Image
let title: String
var body: some View {
HStack(alignment: .center, spacing: 4) {
if chatMenu == tag {
image.resizable()
.frame(width: 24, height: 24, alignment: .center)
Text("\(title)")
.font(.nps(font: .bold, size: 24))
.foregroundStyle(Color(.Text.detail))
} else {
image.resizable()
.renderingMode(.template)
.frame(width: 24, height: 24, alignment: .center)
.foregroundStyle(Color(.Disable.normal))
Text("\(title)")
.font(.nps(size: 20))
.foregroundStyle(Color(.Disable.normal))
}
}
.padding(2)
.background {
if chatMenu == tag {
RoundedRectangle(cornerRadius: 4)
.foregroundStyle(Color.Other.cell)
}
}
.onTapGesture {
chatMenu = tag
}
}
}

View File

@ -27,8 +27,7 @@ struct DevInfoView: View {
Text(attributeText) Text(attributeText)
.foregroundStyle(Color(.Text.detail)) .foregroundStyle(Color(.Text.detail))
.lineLimit(2) .multilineStyle(.center, limit: 2)
.multilineTextAlignment(.center)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
VStack(alignment: .leading, spacing: 12){ VStack(alignment: .leading, spacing: 12){

View File

@ -25,14 +25,16 @@ struct EtcView: View {
TsCsView() TsCsView()
AppInfoView() AppInfoView()
} }
// .frame(maxWidth: .infinity, alignment: .leading)
.padding(24) .padding(24)
DevInfoView() DevInfoView()
// Rectangle()
// .foregroundStyle(Color(.Disable.normal))
// .frame(height: 500)
// .frame(maxWidth: .infinity)
} }
.frame(maxWidth: .infinity, maxHeight: .infinity)
} }
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onAppear { .onAppear {
topVM.titleName = "" topVM.titleName = ""
topVM.setLeftBtn(size: CGPoint(x: 40, y: 40), action: leftAct) topVM.setLeftBtn(size: CGPoint(x: 40, y: 40), action: leftAct)

View File

@ -46,10 +46,8 @@ struct UserInfoView: View {
Spacer(minLength: 1) Spacer(minLength: 1)
Text("\(userData.email)") Text("\(userData.email)")
.font(.nps(size: 16)) .font(.nps(size: 16))
.lineLimit(1)
.minimumScaleFactor(0.5)
.truncationMode(.tail)
.foregroundStyle(Color(.Text.detail)) .foregroundStyle(Color(.Text.detail))
.multilineStyle()
} }
} }
.padding(10) .padding(10)

View File

@ -0,0 +1,25 @@
//
// EmptyBoxView.swift
// AcaMate
//
// Created by TAnine on 2/14/25.
//
import SwiftUI
struct EmptyBoxView: View {
let title: String
var body: some View {
Text("\(title)")
.font(.nps(size: 20))
.foregroundStyle(Color(.Text.detail))
.multilineStyle()
.frame(maxWidth: .infinity)
.padding([.top,.bottom],12)
.background {
RoundedRectangle(cornerRadius: 4)
.stroke(Color(.Second.normal), lineWidth: 2)
.fill(Color(.Second.light))
}
}
}

View File

@ -14,7 +14,7 @@ struct MainView: View {
@State var cancellables: Set<AnyCancellable> = [] @State var cancellables: Set<AnyCancellable> = []
@Binding var naviState : NaviState @Binding var naviState : NaviState
@State private var myType: UserType = .Student @State private var myType: UserType = .Admin
var body: some View { var body: some View {
@ -26,7 +26,7 @@ struct MainView: View {
case .Management: case .Management:
ManagementView() ManagementView()
case .Chatting: case .Chatting:
ChattingView() ChattingView(myType: $myType)
case .Calendar: case .Calendar:
CalendarView() CalendarView()
case .Etc: case .Etc:

View File

@ -0,0 +1,29 @@
//
// Chat Data.swift
// AcaMate
//
// Created by TAnine on 2/14/25.
//
import Foundation
struct SummaryChat {
var id: String
var chatName: String
var teacherName: String
var lastMessage: String
var dayDate: String
var timeDate: String
var notiState: Bool
var groupNum: Int
}
enum chatType {
case Class
case Student
case Parent
}

View File

@ -9,5 +9,11 @@ import SwiftUI
extension Text { extension Text {
func multilineStyle(_ alignment: TextAlignment = .leading, limit: Int = 1, scale: CGFloat = 0.5) -> some View {
return self
.lineLimit(limit)
.minimumScaleFactor(scale)
.multilineTextAlignment(alignment)
.truncationMode(.tail)
}
} }