diff --git a/main.py b/main.py index 31432e3..c31a04a 100644 --- a/main.py +++ b/main.py @@ -6,7 +6,7 @@ import openai # Set API key for OpenAI -openai.api_key = "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" #API IRFAN +openai.api_key = "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" #API IRFAN # openai.api_key = "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" #API RIO # The styling properties for the main content area class/ for chat AI @@ -47,7 +47,7 @@ def prompt_style(): "content_padding": 10, "cursor_color": "white", } - +# inherintance #main content area class class MainContentArea(ft.Container): def __init__(self): @@ -59,11 +59,11 @@ def __init__(self): auto_scroll=True, ) self.content = self.chat - +#class maincontentarea warisan ft.container #Before pushing text to UI - create a class that generates the UI for the actual text prompts class CreateMessage(ft.Column): def __init__(self, name: str, message: str): - self.name = name #show's which prompt is whos + self.name = name #Menunjukkan pemilik prompt self.message = message self.text = ft.Text(self.message) super().__init__(spacing=4) @@ -79,7 +79,7 @@ def __init__(self, name: str, chat: ft.ListView): # output display is working - but let's add animation to text output... def animate_text_output(self, prompt: str): word_list = [] - msg = CreateMessage(self.name, "") + msg = CreateMessage(self.name, "") #objek self.chat.controls.append(msg) #list(prompt) => we deconstruct the prompt text into sepreate characters, and loop over them @@ -180,29 +180,73 @@ def build(self): animate_rotation=ft.animation.Animation(700, "easeInOut"), ) -# Classes for user input -class UserInputField(ft.UserControl): - def __init__(self, icon_name, text_hint, hide, function_emails: bool, function_check: bool): +# kelas baru inheritance +# InputField sebagai kelas induk dan membuat UserInputField sebagai kelas anak yang mewarisi darinya. +class InputField(ft.UserControl): + def __init__(self, icon_name, text_hint, hide): self.icon_name = icon_name self.text_hint = text_hint self.hide = hide + super().__init__() + + def build(self): + return ft.Container( + width=320, + height=40, + border=ft.border.only(bottom=ft.border.BorderSide(0.5, "white54")), + content=ft.Row( + spacing=20, + vertical_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + ft.Icon( + name=self.icon_name, + size=14, + opacity=0.85, + ), + ft.TextField( + border_color="transparent", + bgcolor="transparent", + height=20, + width=180, + text_size=12, + content_padding=3, + cursor_color="white", + hint_text=self.text_hint, + hint_style=ft.TextStyle(size=11), + password=self.hide, + ), + ], + ) + ) + +# Classes for user input +class UserInputField(InputField): + def __init__(self, icon_name, text_hint, hide, function_emails: bool, function_check: bool): + # Memanggil konstruktor kelas induk (InputField) + super().__init__(icon_name, text_hint, hide) + + # Menyimpan atribut khusus dari UserInputField self.function_emails = function_emails self.function_check = function_check - super().__init__() - - # Function to add email prefix + def return_email_prefix(self, e): + # Mendapatkan nilai email dari kontrol email = self.controls[0].content.controls[1].value - if e.control.data in email: - pass - else: + + # Menambahkan karakter ke email jika belum ada + if e.control.data not in email: self.controls[0].content.controls[1].value += e.control.data - self.controls[0].content.controls[2].offset = ft.transform.Offset(0.5, 0) - self.controls[0].content.controls[2].opacity = 0 - self.update() - - # Function for composing email prefix labels + # Memanggil fungsi untuk menyembunyikan label email prefix + self.hide_prefix_email_containers() + + def hide_prefix_email_containers(self): + # Menyembunyikan label email prefix dengan animasi + self.controls[0].content.controls[2].offset = ft.transform.Offset(0.5, 0) + self.controls[0].content.controls[2].opacity = 0 + self.update() + def prefix_email_containers(self): + # Membuat dan mengembalikan kontrol label email prefix email_labels = ["@gmail.com", "@hotmail.com"] label_title = ["GMAIL", "MAIL"] __ = ft.Row(spacing=1, alignment=ft.MainAxisAlignment.END) @@ -231,9 +275,9 @@ def prefix_email_containers(self): animate_offset=ft.animation.Animation(400, "decelerate"), controls=[__] ) - - # Function to display the off-focus checkbox + def off_focus_input_check(self): + # Membuat dan mengembalikan kontrol checkbox yang tampil saat input kehilangan fokus return ft.Container( opacity=0, offset=ft.transform.Offset(0, 0), @@ -248,12 +292,15 @@ def off_focus_input_check(self): disabled=True, ) ) - - # Function to get email prefix + def get_prefix_emails(self, e): + # Mendapatkan nilai email dari kontrol + email = self.controls[0].content.controls[1].value + + # Memproses perubahan pada kontrol terkait email prefix if self.function_emails: - email = self.controls[0].content.controls[1].value if e.data: + # Menampilkan atau menyembunyikan label email prefix berdasarkan kondisi email if "@gmail.com" in email or "@hotmail.com" in email: self.controls[0].content.controls[2].offset = ft.transform.Offset(0, 0) self.controls[0].content.controls[2].opacity = 0 @@ -266,16 +313,17 @@ def get_prefix_emails(self, e): self.controls[0].content.controls[2].offset = ft.transform.Offset(0.5, 0) self.controls[0].content.controls[2].opacity = 0 self.update() - else: - pass - - # Function to get a green check + def get_green_check(self, e): + # Mendapatkan nilai email dan password dari kontrol + email = self.controls[0].content.controls[1].value + password = self.controls[0].content.controls[1].password + + # Memproses perubahan pada kontrol terkait tanda centang hijau if self.function_check: - email = self.controls[0].content.controls[1].value - password = self.controls[0].content.controls[1].password if (email): if "@gmail.com" in email or "@hotmail.com" in email or password: + # Animasi perubahan dan penyesuaian nilai checkbox time.sleep(0.5) self.controls[0].content.controls[3].offset = ft.transform.Offset(-2, 0) self.controls[0].content.controls[3].opacity = 1 @@ -292,39 +340,16 @@ def get_green_check(self, e): pass def build(self): - return ft.Container( - width=320, - height=40, - border=ft.border.only(bottom=ft.border.BorderSide(0.5, "white54")), - content=ft.Row( - spacing=20, - vertical_alignment=ft.CrossAxisAlignment.CENTER, - controls=[ - ft.Icon( - name=self.icon_name, - size=14, - opacity=0.85, - ), - ft.TextField( - border_color="transparent", - bgcolor="transparent", - height=20, - width=180, - text_size=12, - content_padding=3, - cursor_color="white", - hint_text=self.text_hint, - hint_style=ft.TextStyle(size=11), - password=self.hide, - on_change=lambda e: self.get_prefix_emails(e), - on_blur=lambda e: self.get_green_check(e), - ), - self.prefix_email_containers(), - self.off_focus_input_check(), - ], - ) - ) + # Memanggil metode build dari kelas InputField untuk membuat container utama + input_field_container = super().build() + + # Menambahkan kontrol tambahan ke dalam input_field_container + input_field_container.content.controls.extend([ + self.prefix_email_containers(), + self.off_focus_input_check(), + ]) + return input_field_container # Function to display tab1 content def tab1_content(): @@ -376,10 +401,10 @@ def tab1_content(): # Function to display tab2 content def tab2_content(): - main_area = MainContentArea() + main_area = MainContentArea() #objek dari maincontentarea user_output = UserOutput(chat=main_area.chat) gpt_output = GptOutput(chat=main_area.chat) - prompt = Prompt(chat=main_area.chat, user_output=user_output, gpt_output=gpt_output) + prompt = Prompt(chat=main_area.chat, user_output=user_output, gpt_output=gpt_output) #objek return ft.Column([ main_area, ft.Divider(height=3, color="transparent"), @@ -439,4 +464,51 @@ def main(page: ft.Page): page.update() if __name__ == "__main__": - ft.app(target=main) \ No newline at end of file + ft.app(target=main) + +def tab1_content(): + return Card( + elevation=15, + content=ft.Container( + width=300, + height=612, + bgcolor="#ebeefa", + border_radius=6, + content=Column( + horizontal_alignment=CrossAxisAlignment.CENTER, + controls=[ + Divider(height=20, color='transparent'), + Stack( + controls=[ + AnimatedBox("#e9665a", None, 0), + AnimatedBox("#7df6dd", "#ebeefa", pi / 4), + ] + ), + Divider(height=20, color='transparent'), + Column( + alignment=MainAxisAlignment.CENTER, + spacing=5, + controls=[ + Text("Sign In Below", size=22, weight='bold'), + Text(" Agora-AI", size=13, weight='bold'), + ], + ), + Divider(height=20, color='transparent'), + UserInputField(icons.PERSON_ROUNDED, "Email", False, True, True), + Divider(height=2, color='transparent'), + UserInputField(icons.LOCK_OPEN_ROUNDED, "Password", True, False, True), + + Divider(height=20, color='transparent'), + Row( + width=320, + alignment=MainAxisAlignment.END, + controls=[Text("Forgot Password?", size=9)], + ), + Divider(height=20, color='transparent'), + SignInButton("Sign In"), + Divider(height=20, color='transparent'), + Text("Footer text goes in here.", size=10, color='black'), + ], + ), + ), + ) \ No newline at end of file