forked from AcaMate/AcaMate_iOS
[✨] 채팅 페이지 작업 중
This commit is contained in:
parent
c6f224a9d9
commit
875f92c81b
Binary file not shown.
|
@ -20,11 +20,6 @@ struct BoxBtnView<Content: View>: View {
|
|||
action()
|
||||
} label: {
|
||||
content
|
||||
// if let image = image {
|
||||
// image
|
||||
// .resizable()
|
||||
// .frame(width: width, height: height)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,10 +38,8 @@ struct CircleBtnView: View {
|
|||
if let title = state.text, let font = state.font {
|
||||
Text("\(title)")
|
||||
.font(font)
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
.truncationMode(.tail)
|
||||
.foregroundStyle(state.foreColor)
|
||||
.multilineStyle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,7 @@ struct SimpleBtnView: View {
|
|||
if let title = state.text, let font = state.font {
|
||||
Text("\(title)")
|
||||
.font(font)
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
.multilineTextAlignment(.center)
|
||||
.truncationMode(.tail)
|
||||
.multilineStyle(.center)
|
||||
.foregroundStyle(state.textColor)
|
||||
.frame(width: state.width, height: state.height)
|
||||
.onTapGesture {
|
||||
|
|
|
@ -50,20 +50,21 @@ struct AttCellView: View {
|
|||
.padding(.top,4)
|
||||
HStack(alignment: .center, spacing: 2) {
|
||||
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))
|
||||
.frame(width: 28,alignment: .center)
|
||||
Text("/").font(.nps(size: 12))
|
||||
Text("/")
|
||||
.font(.nps(size: 12))
|
||||
.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))
|
||||
.frame(width: 28,alignment: .center)
|
||||
Text("\(cellText.group)")
|
||||
.font(.nps(size: 16))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
.truncationMode(.tail)
|
||||
.multilineStyle()
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
|
|
@ -48,9 +48,7 @@ struct CalCellView: View {
|
|||
Text("\(summaryCalData.summary)")
|
||||
.font(.nps(size: 20))
|
||||
.foregroundStyle(Color(.Text.black))
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
.truncationMode(.tail)
|
||||
.multilineStyle()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ struct HomeView: View {
|
|||
@State private var topViewState: Bool = false
|
||||
|
||||
//MARK: - 변경 값
|
||||
// @State private var myType: UserType = .Student
|
||||
@Binding var myType: UserType
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,20 +48,17 @@ struct TopProfileView: View {
|
|||
.padding([.top, .bottom], 40)
|
||||
VStack(alignment: .center, spacing: 8) {
|
||||
Text("\(self.academyName)")
|
||||
.frame(alignment: .center)
|
||||
.font(.nps(font: .bold, size: 36))
|
||||
.foregroundStyle(Color(.Text.title))
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
.truncationMode(.tail)
|
||||
Text("\(self.myName)")
|
||||
.multilineTextAlignment(.center)
|
||||
.multilineStyle()
|
||||
.frame(alignment: .center)
|
||||
|
||||
Text("\(self.myName)")
|
||||
.font(.nps(size: 18))
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
.truncationMode(.tail)
|
||||
.multilineStyle()
|
||||
.frame(alignment: .center)
|
||||
|
||||
}
|
||||
} /// 위쪽 VStack
|
||||
.padding(EdgeInsets(top: 24, leading: 24, bottom: 12, trailing: 24))
|
||||
|
|
89
AcaMate/1. View/12. Main/123. Chatting/ChatListView.swift
Normal file
89
AcaMate/1. View/12. Main/123. Chatting/ChatListView.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,38 +9,111 @@ import SwiftUI
|
|||
|
||||
struct ChattingView: View {
|
||||
@StateObject private var topVM = TopViewModel()
|
||||
@StateObject private var btnVM = ButtonViewModel()
|
||||
|
||||
@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 {
|
||||
|
||||
VStack(spacing: 0) {
|
||||
TopView(topVM: topVM)
|
||||
|
||||
OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in
|
||||
VStack(spacing: 24) {
|
||||
Group {
|
||||
DashBoardView(image: Image(.Icon.group), title: "클래스") {
|
||||
|
||||
}
|
||||
DashBoardView(image: Image(.Icon.talk), title: "선생님과 1:1") {
|
||||
|
||||
if myType == .ETC || myType == .Employee {
|
||||
EmptyBoxView(title: "이용하실 수 없는 기능입니다.")
|
||||
.padding(24)
|
||||
Spacer(minLength: 1)
|
||||
} 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)
|
||||
}
|
||||
.padding(EdgeInsets(top: 12, leading: 24, bottom: 0, trailing: 24))
|
||||
}
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.foregroundStyle(Color(.Other.cell))
|
||||
|
||||
HStack {
|
||||
SelectChatMenu(chatMenu: $chatMenu, tag: .Class, image: Image(.Icon.group), title: "클래스")
|
||||
Spacer(minLength: 1)
|
||||
SelectChatMenu(chatMenu: $chatMenu, tag: .Student, image: Image(.Icon.talk), title: "학생")
|
||||
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 {
|
||||
topVM.titleName = ""
|
||||
topVM.setLeftBtn(size: CGPoint(x: 40, y: 40), action: leftAct)
|
||||
// MARK: TO-DO
|
||||
// 여기도 수정봐야 함
|
||||
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)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,7 @@ struct DevInfoView: View {
|
|||
|
||||
Text(attributeText)
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
.lineLimit(2)
|
||||
.multilineTextAlignment(.center)
|
||||
.multilineStyle(.center, limit: 2)
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
|
||||
|
||||
VStack(alignment: .leading, spacing: 12){
|
||||
|
|
|
@ -16,7 +16,7 @@ struct EtcView: View {
|
|||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
TopView(topVM: topVM)
|
||||
|
||||
|
||||
OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in
|
||||
VStack(spacing: 24) {
|
||||
UserInfoView(userData: SummaryUser(profile: Image(.Icon.face), name: "이름", userID: "abcdefg", email: "abcdefg@gmail.com"))
|
||||
|
@ -25,14 +25,16 @@ struct EtcView: View {
|
|||
TsCsView()
|
||||
AppInfoView()
|
||||
}
|
||||
// .frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(24)
|
||||
DevInfoView()
|
||||
|
||||
// Rectangle()
|
||||
// .foregroundStyle(Color(.Disable.normal))
|
||||
// .frame(height: 500)
|
||||
// .frame(maxWidth: .infinity)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
|
||||
.onAppear {
|
||||
topVM.titleName = ""
|
||||
topVM.setLeftBtn(size: CGPoint(x: 40, y: 40), action: leftAct)
|
||||
|
|
|
@ -46,10 +46,8 @@ struct UserInfoView: View {
|
|||
Spacer(minLength: 1)
|
||||
Text("\(userData.email)")
|
||||
.font(.nps(size: 16))
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
.truncationMode(.tail)
|
||||
.foregroundStyle(Color(.Text.detail))
|
||||
.multilineStyle()
|
||||
}
|
||||
}
|
||||
.padding(10)
|
||||
|
|
25
AcaMate/1. View/12. Main/EmptyBoxView.swift
Normal file
25
AcaMate/1. View/12. Main/EmptyBoxView.swift
Normal 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))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ struct MainView: View {
|
|||
@State var cancellables: Set<AnyCancellable> = []
|
||||
@Binding var naviState : NaviState
|
||||
|
||||
@State private var myType: UserType = .Student
|
||||
@State private var myType: UserType = .Admin
|
||||
|
||||
var body: some View {
|
||||
|
||||
|
@ -26,7 +26,7 @@ struct MainView: View {
|
|||
case .Management:
|
||||
ManagementView()
|
||||
case .Chatting:
|
||||
ChattingView()
|
||||
ChattingView(myType: $myType)
|
||||
case .Calendar:
|
||||
CalendarView()
|
||||
case .Etc:
|
||||
|
|
29
AcaMate/2. Model/Chat Data.swift
Normal file
29
AcaMate/2. Model/Chat Data.swift
Normal 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
|
||||
}
|
|
@ -9,5 +9,11 @@ import SwiftUI
|
|||
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user