diff --git a/dudu-tweet/dudu-tweet.xcodeproj/project.pbxproj b/dudu-tweet/dudu-tweet.xcodeproj/project.pbxproj index 3e1a348..d073cc2 100644 --- a/dudu-tweet/dudu-tweet.xcodeproj/project.pbxproj +++ b/dudu-tweet/dudu-tweet.xcodeproj/project.pbxproj @@ -26,6 +26,11 @@ 24A59AD62A00CA82009C9E3E /* SideMenuOptionRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A59AD52A00CA82009C9E3E /* SideMenuOptionRowView.swift */; }; 24A59ADD2A00DB9F009C9E3E /* NewTweetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A59ADC2A00DB9F009C9E3E /* NewTweetView.swift */; }; 24A59ADF2A00DCC2009C9E3E /* TextArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A59ADE2A00DCC2009C9E3E /* TextArea.swift */; }; + 24A59AE42A00EF1F009C9E3E /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A59AE32A00EF1F009C9E3E /* LoginView.swift */; }; + 24A59AE62A00EF3A009C9E3E /* RegistrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A59AE52A00EF3A009C9E3E /* RegistrationView.swift */; }; + 24A59AE82A00F106009C9E3E /* RoundedShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A59AE72A00F106009C9E3E /* RoundedShape.swift */; }; + 24A59AEA2A00F672009C9E3E /* CustomInputField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A59AE92A00F672009C9E3E /* CustomInputField.swift */; }; + 24A59AED2A00F942009C9E3E /* AuthHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A59AEC2A00F942009C9E3E /* AuthHeaderView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -50,6 +55,11 @@ 24A59AD52A00CA82009C9E3E /* SideMenuOptionRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenuOptionRowView.swift; sourceTree = ""; }; 24A59ADC2A00DB9F009C9E3E /* NewTweetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTweetView.swift; sourceTree = ""; }; 24A59ADE2A00DCC2009C9E3E /* TextArea.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextArea.swift; sourceTree = ""; }; + 24A59AE32A00EF1F009C9E3E /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = ""; }; + 24A59AE52A00EF3A009C9E3E /* RegistrationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationView.swift; sourceTree = ""; }; + 24A59AE72A00F106009C9E3E /* RoundedShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedShape.swift; sourceTree = ""; }; + 24A59AE92A00F672009C9E3E /* CustomInputField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomInputField.swift; sourceTree = ""; }; + 24A59AEC2A00F942009C9E3E /* AuthHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthHeaderView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -106,6 +116,7 @@ 2492CC1B2A00228F0086C525 /* Core */ = { isa = PBXGroup; children = ( + 24A59AE02A00EEE8009C9E3E /* Authentication */, 24A59AD72A00DB49009C9E3E /* UploadTweet */, 24A59ACA2A00BDA1009C9E3E /* SideMenu */, 2492CC212A0022C30086C525 /* Components */, @@ -152,9 +163,12 @@ 2492CC212A0022C30086C525 /* Components */ = { isa = PBXGroup; children = ( + 24A59AEB2A00F92D009C9E3E /* Authentication */, 24A59AC72A00BA6A009C9E3E /* Users */, 2492CC262A0025A50086C525 /* Tweets */, 24A59ADE2A00DCC2009C9E3E /* TextArea.swift */, + 24A59AE72A00F106009C9E3E /* RoundedShape.swift */, + 24A59AE92A00F672009C9E3E /* CustomInputField.swift */, ); path = Components; sourceTree = ""; @@ -314,6 +328,39 @@ path = ViewModels; sourceTree = ""; }; + 24A59AE02A00EEE8009C9E3E /* Authentication */ = { + isa = PBXGroup; + children = ( + 24A59AE22A00EEF8009C9E3E /* ViewModels */, + 24A59AE12A00EEF0009C9E3E /* Views */, + ); + path = Authentication; + sourceTree = ""; + }; + 24A59AE12A00EEF0009C9E3E /* Views */ = { + isa = PBXGroup; + children = ( + 24A59AE32A00EF1F009C9E3E /* LoginView.swift */, + 24A59AE52A00EF3A009C9E3E /* RegistrationView.swift */, + ); + path = Views; + sourceTree = ""; + }; + 24A59AE22A00EEF8009C9E3E /* ViewModels */ = { + isa = PBXGroup; + children = ( + ); + path = ViewModels; + sourceTree = ""; + }; + 24A59AEB2A00F92D009C9E3E /* Authentication */ = { + isa = PBXGroup; + children = ( + 24A59AEC2A00F942009C9E3E /* AuthHeaderView.swift */, + ); + path = Authentication; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -388,6 +435,7 @@ 24A59AC22A003249009C9E3E /* ProfileView.swift in Sources */, 2492CC0F2A000EB00086C525 /* ContentView.swift in Sources */, 2492CC282A0025DD0086C525 /* TweetRowView.swift in Sources */, + 24A59AEA2A00F672009C9E3E /* CustomInputField.swift in Sources */, 24A59AC42A003A52009C9E3E /* TwewtFilterViewModel.swift in Sources */, 2492CC252A0023220086C525 /* FeedView.swift in Sources */, 24A59ACE2A00BDCB009C9E3E /* SideMenuView.swift in Sources */, @@ -396,7 +444,11 @@ 24A59AD22A00BE14009C9E3E /* SideMenuViewModel.swift in Sources */, 24A59ADF2A00DCC2009C9E3E /* TextArea.swift in Sources */, 24A59AD62A00CA82009C9E3E /* SideMenuOptionRowView.swift in Sources */, + 24A59AE42A00EF1F009C9E3E /* LoginView.swift in Sources */, + 24A59AE62A00EF3A009C9E3E /* RegistrationView.swift in Sources */, 24A59ADD2A00DB9F009C9E3E /* NewTweetView.swift in Sources */, + 24A59AED2A00F942009C9E3E /* AuthHeaderView.swift in Sources */, + 24A59AE82A00F106009C9E3E /* RoundedShape.swift in Sources */, 24A59AC92A00BA81009C9E3E /* UserRowView.swift in Sources */, 24A59AB42A002EB8009C9E3E /* MainTabView.swift in Sources */, 24A59ABC2A0030EC009C9E3E /* NotificationsView.swift in Sources */, diff --git a/dudu-tweet/dudu-tweet.xcodeproj/project.xcworkspace/xcuserdata/ching.xcuserdatad/UserInterfaceState.xcuserstate b/dudu-tweet/dudu-tweet.xcodeproj/project.xcworkspace/xcuserdata/ching.xcuserdatad/UserInterfaceState.xcuserstate index 5c21ca7..ee7529e 100644 Binary files a/dudu-tweet/dudu-tweet.xcodeproj/project.xcworkspace/xcuserdata/ching.xcuserdatad/UserInterfaceState.xcuserstate and b/dudu-tweet/dudu-tweet.xcodeproj/project.xcworkspace/xcuserdata/ching.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/dudu-tweet/dudu-tweet/ContentView.swift b/dudu-tweet/dudu-tweet/ContentView.swift index 3f35151..a3d4513 100644 --- a/dudu-tweet/dudu-tweet/ContentView.swift +++ b/dudu-tweet/dudu-tweet/ContentView.swift @@ -13,7 +13,8 @@ struct ContentView: View { var body: some View { ZStack(alignment: .topLeading) { MainTabView() - .navigationBarHidden(showMenu) +// .navigationBarHidden(showMenu) + .toolbar(showMenu ? .hidden : .visible) if showMenu { ZStack { diff --git a/dudu-tweet/dudu-tweet/Core/Authentication/Views/LoginView.swift b/dudu-tweet/dudu-tweet/Core/Authentication/Views/LoginView.swift new file mode 100644 index 0000000..74ccb19 --- /dev/null +++ b/dudu-tweet/dudu-tweet/Core/Authentication/Views/LoginView.swift @@ -0,0 +1,87 @@ +// +// LoginView.swift +// dudu-tweet +// +// Created by ching on 2023/5/2. +// + +import SwiftUI + +struct LoginView: View { + @State private var email = "" + @State private var password = "" + + + var body: some View { + VStack { + AuthHeaderView(title1: "Hello.", title2: "Welcome Back") + VStack(spacing: 40) { + CustomInputField(imageName: "envelope", + palceholderText: "Email", + text: $email) + + CustomInputField(imageName: "lock", + palceholderText: "Password", + text: $password) + } + .padding(.horizontal, 32) + .padding(.top, 44) + + HStack { + Spacer() + NavigationLink { + Text("Reset password view") + } label: { + Text("Forgot Password?") + .font(.caption) + .fontWeight(.bold) + .foregroundColor(Color(.systemBlue)) + .padding(.top) + .padding(.trailing, 24) + } + } + + Button { + print("Sign in here") + } label: { + Text("Sign In") + .font(.headline) + .foregroundColor(.white) + .frame(width: 340, height: 50) + .background(Color(.systemBlue)) + .clipShape(Capsule()) + .padding() + } + .shadow(color: .gray.opacity(0.5), radius: 10, x:0, y:0) + + Spacer() + + NavigationLink { + RegistrationView() +// .navigationBarHidden(true) + .toolbar(.hidden) + } label: { + HStack { + Text("Don't have an account?") + .font(.footnote) + + Text("Sign Up") + .font(.footnote) + .fontWeight(.semibold) + } + } + .padding(.bottom, 32) + .foregroundColor(Color(.systemBlue)) + } + .ignoresSafeArea() +// .navigationBarHidden(true) + .toolbar(.hidden) + + } +} + +struct LoginView_Previews: PreviewProvider { + static var previews: some View { + LoginView() + } +} diff --git a/dudu-tweet/dudu-tweet/Core/Authentication/Views/RegistrationView.swift b/dudu-tweet/dudu-tweet/Core/Authentication/Views/RegistrationView.swift new file mode 100644 index 0000000..ed80171 --- /dev/null +++ b/dudu-tweet/dudu-tweet/Core/Authentication/Views/RegistrationView.swift @@ -0,0 +1,80 @@ +// +// RegistrationView.swift +// dudu-tweet +// +// Created by ching on 2023/5/2. +// + +import SwiftUI + +struct RegistrationView: View { + @State private var email = "" + @State private var username = "" + @State private var fullname = "" + @State private var password = "" + +// @Environment(\.presentationMode) var presentationMode + @Environment(\.dismiss) private var dismiss + + var body: some View { + VStack { + AuthHeaderView(title1: "Get started.", + title2: "Create your account") + + VStack(spacing: 40) { + CustomInputField(imageName: "envelope", + palceholderText: "Email", + text: $email) + + CustomInputField(imageName: "person", + palceholderText: "Username", + text: $username) + + CustomInputField(imageName: "person", + palceholderText: "Full Name", + text: $fullname) + + CustomInputField(imageName: "lock", + palceholderText: "Password", + text: $password) + } + .padding(32) + + Button { + print("Sign up here") + } label: { + Text("Sign Up") + .font(.headline) + .foregroundColor(.white) + .frame(width: 340, height: 50) + .background(Color(.systemBlue)) + .clipShape(Capsule()) + .padding() + } + .shadow(color: .gray.opacity(0.5), radius: 10, x: 0, y: 0) + + Spacer() + + Button { + dismiss() + } label: { + HStack { + Text("Already have an account?") + .font(.footnote) + + Text("Sign In") + .font(.footnote) + .fontWeight(.semibold) + } + } + .padding(.bottom, 32) + } + .ignoresSafeArea() + } +} + +struct RegistrationView_Previews: PreviewProvider { + static var previews: some View { + RegistrationView() + } +} diff --git a/dudu-tweet/dudu-tweet/Core/Components/Authentication/AuthHeaderView.swift b/dudu-tweet/dudu-tweet/Core/Components/Authentication/AuthHeaderView.swift new file mode 100644 index 0000000..3f3a9d1 --- /dev/null +++ b/dudu-tweet/dudu-tweet/Core/Components/Authentication/AuthHeaderView.swift @@ -0,0 +1,40 @@ +// +// AuthHeaderView.swift +// dudu-tweet +// +// Created by ching on 2023/5/2. +// + +import SwiftUI + +struct AuthHeaderView: View { + let title1: String + let title2: String + + var body: some View { + VStack(alignment: .leading) { + HStack {Spacer()} + + Text(title1) + .font(.largeTitle) + .fontWeight(.semibold) + + Text(title2) + .font(.largeTitle) + .fontWeight(.semibold) + + } + .frame(height: 260) + .padding(.leading) + .background(Color(.systemBlue)) + .foregroundColor(.white) + .clipShape(RoundedShape(corners: [.bottomRight])) + + } +} + +struct AuthenticationHeader_Previews: PreviewProvider { + static var previews: some View { + AuthHeaderView(title1: "hello,", title2: "world") + } +} diff --git a/dudu-tweet/dudu-tweet/Core/Components/CustomInputField.swift b/dudu-tweet/dudu-tweet/Core/Components/CustomInputField.swift new file mode 100644 index 0000000..e4b07b5 --- /dev/null +++ b/dudu-tweet/dudu-tweet/Core/Components/CustomInputField.swift @@ -0,0 +1,38 @@ +// +// CustomInputField.swift +// dudu-tweet +// +// Created by ching on 2023/5/2. +// + +import SwiftUI + +struct CustomInputField: View { + let imageName: String + let palceholderText: String + @Binding var text: String + + + var body: some View { + VStack { + HStack { + Image(systemName: imageName) + .resizable() + .scaledToFit() + .frame(width: 20, height: 20) + .foregroundColor(Color(.darkGray)) + + TextField(palceholderText, text: $text) + } + + Divider() + .background(Color(.darkGray)) + } + } +} + +struct CustomInputField_Previews: PreviewProvider { + static var previews: some View { + CustomInputField(imageName: "envelope", palceholderText: "Email", text: .constant("")) + } +} diff --git a/dudu-tweet/dudu-tweet/Core/Components/RoundedShape.swift b/dudu-tweet/dudu-tweet/Core/Components/RoundedShape.swift new file mode 100644 index 0000000..38001b8 --- /dev/null +++ b/dudu-tweet/dudu-tweet/Core/Components/RoundedShape.swift @@ -0,0 +1,17 @@ +// +// RoundedShape.swift +// dudu-tweet +// +// Created by ching on 2023/5/2. +// + +import SwiftUI + +struct RoundedShape: Shape { + var corners: UIRectCorner + + func path(in rect: CGRect) -> Path { + let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: 80, height: 80)) + return Path(path.cgPath) + } +} diff --git a/dudu-tweet/dudu-tweet/Core/Profile/Views/ProfileView.swift b/dudu-tweet/dudu-tweet/Core/Profile/Views/ProfileView.swift index 0d2a171..3145491 100644 --- a/dudu-tweet/dudu-tweet/Core/Profile/Views/ProfileView.swift +++ b/dudu-tweet/dudu-tweet/Core/Profile/Views/ProfileView.swift @@ -9,7 +9,9 @@ import SwiftUI struct ProfileView: View { @State private var selectedFilter: TweetFilterViewModel = .tweets - @Environment(\.presentationMode) var mode // 用来从explore 页面跳转过来之后跳转回去 +// @Environment(\.presentationMode) var mode // 用来从explore 页面跳转过来之后跳转回去 + @Environment(\.dismiss) private var dismiss + @Namespace var animation var body: some View { @@ -42,7 +44,8 @@ extension ProfileView { .ignoresSafeArea() VStack { Button { - mode.wrappedValue.dismiss() +// mode.wrappedValue.dismiss() + dismiss() } label: { Image(systemName: "arrow.left") .resizable() diff --git a/dudu-tweet/dudu-tweet/Core/UploadTweet/Views/NewTweetView.swift b/dudu-tweet/dudu-tweet/Core/UploadTweet/Views/NewTweetView.swift index c949bdd..aab19ac 100644 --- a/dudu-tweet/dudu-tweet/Core/UploadTweet/Views/NewTweetView.swift +++ b/dudu-tweet/dudu-tweet/Core/UploadTweet/Views/NewTweetView.swift @@ -9,12 +9,15 @@ import SwiftUI struct NewTweetView: View { @State private var caption = "" - @Environment(\.presentationMode) var presentationMode +// @Environment(\.presentationMode) var presentationMode + @Environment(\.dismiss) private var dismiss + var body: some View { VStack { HStack { Button { - presentationMode.wrappedValue.dismiss() +// presentationMode.wrappedValue.dismiss() + dismiss() } label: { Text("Cancel") .foregroundColor(Color(.systemBlue)) diff --git a/dudu-tweet/dudu-tweet/dudu_tweetApp.swift b/dudu-tweet/dudu-tweet/dudu_tweetApp.swift index 71deafd..7899623 100644 --- a/dudu-tweet/dudu-tweet/dudu_tweetApp.swift +++ b/dudu-tweet/dudu-tweet/dudu_tweetApp.swift @@ -13,6 +13,7 @@ struct dudu_tweetApp: App { WindowGroup { NavigationView { ContentView() +// LoginView() } } }