diff --git a/src/bitmessagekivy/main.kv b/src/bitmessagekivy/main.kv index 93d12393..3afc794b 100644 --- a/src/bitmessagekivy/main.kv +++ b/src/bitmessagekivy/main.kv @@ -33,6 +33,9 @@ #:import MDTextButton kivymd.uix.button.MDTextButton #:import FadeTransition kivy.uix.screenmanager.FadeTransition #:import MDScrollViewRefreshLayout kivymd.uix.refreshlayout.MDScrollViewRefreshLayout +#:import MDTabsBase kivymd.uix.tab.MDTabsBase + + #:set color_button (0.784, 0.443, 0.216, 1) # brown #:set color_button_pressed (0.659, 0.522, 0.431, 1) # darker brown @@ -50,8 +53,7 @@ : drawer_logo: app.address_identicon() NavigationDrawerDivider: - - NavigationDrawerTwoLineListItem: + NavigationDrawerSubheader: text: "Accounts" NavigationDrawerIconButton: CustomSpinner: @@ -138,7 +140,7 @@ on_press: app.refreshScreen(self) NavigationDrawerIconButton: text: "Subscriptions/Payment" - icon:'wallet' + icon:'bell' on_release: app.root.ids.scr_mngr.current = 'payment' on_press: app.refreshScreen(self) NavigationDrawerIconButton: @@ -410,16 +412,6 @@ NavigationLayout: helper_text_mode: "on_error" BoxLayout: spacing:50 - AnchorLayout: - MDRaisedButton: - height: dp(40) - on_press: root.reset_composer() - MDLabel: - font_style: 'H4' - text: 'reset' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' : readonly: False @@ -465,19 +457,17 @@ NavigationLayout: padding: dp(10) BoxLayout: MDLabel: - font_style: 'Body1' + font_style: 'Subtitle2' theme_text_color: 'Primary' text: "You may generate addresses by using either random numbers or by using a passphrase If you use a passphrase, the address is called a deterministic; address The Random Number option is selected by default but deterministic addresses have several \n pros and cons:\n" halign: 'center' - bold: True color:app.theme_cls.primary_dark BoxLayout: MDLabel: - font_style: 'Caption' + font_style: 'Subtitle2' theme_text_color: 'Primary' text: "If talk about pros You can recreate your addresses on any computer from memory, You need-not worry about backing up your keys.dat file as long as you can remember your passphrase and aside talk about cons You must remember (or write down) your You must remember the address version number and the stream number along with your passphrase If you choose a weak passphrase and someone on the Internet can brute-force it, they can read your messages and send messages as you" halign: 'center' - bold: True color:app.theme_cls.primary_dark MDCheckbox: id: grp_chkbox_1 @@ -485,12 +475,11 @@ NavigationLayout: active: True allow_no_selection: False MDLabel: - font_style: 'Caption' + font_style: 'Body2' theme_text_color: 'Primary' text: "use a random number generator to make an address" halign: 'center' size_hint_y: None - bold: True height: self.texture_size[1] + dp(4) color: [0.941, 0, 0,1] MDCheckbox: @@ -498,12 +487,11 @@ NavigationLayout: group: 'test' allow_no_selection: False MDLabel: - font_style: 'Caption' + font_style: 'Body2' theme_text_color: 'Primary' text: "use a pseudo number generator to make an address" halign: 'center' size_hint_y: None - bold: True color: [0.941, 0, 0,1] height: self.texture_size[1] + dp(4) BoxLayout: @@ -512,7 +500,7 @@ NavigationLayout: height: dp(40) on_press: app.root.ids.scr_mngr.current = 'random' MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'proceed' font_size: '13sp' color: (1,1,1,1) @@ -528,19 +516,17 @@ NavigationLayout: padding: dp(20) spacing: 100 MDLabel: - font_style: 'Body1' + font_style: 'Subtitle2' theme_text_color: 'Primary' text: "Random Addresses" halign: 'center' - bold: True color:app.theme_cls.primary_dark MDLabel: - font_style: 'Body1' + font_style: 'Subtitle2' theme_text_color: 'Primary' text: "Here you may generate as many addresses as you like, Indeed creating and abandoning addresses is encouraged" halign: 'center' - bold: True color:app.theme_cls.primary_dark MDTextField: @@ -556,7 +542,7 @@ NavigationLayout: on_release: root.generateaddress(app) opposite_colors: True MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'next' font_size: '13sp' color: (1,1,1,1) @@ -581,9 +567,10 @@ NavigationLayout: BoxLayout: AnchorLayout: MDRaisedButton: + size_hint: .6, .55 height: dp(40) MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Server' font_size: '13sp' color: (1,1,1,1) @@ -593,9 +580,10 @@ NavigationLayout: BoxLayout: AnchorLayout: MDRaisedButton: + size_hint: .6, .55 height: dp(40) MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Import or export data' font_size: '13sp' color: (1,1,1,1) @@ -605,9 +593,10 @@ NavigationLayout: BoxLayout: AnchorLayout: MDRaisedButton: + size_hint: .6, .55 height: dp(40) MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Restart background service' font_size: '13sp' color: (1,1,1,1) @@ -619,12 +608,12 @@ NavigationLayout: theme_text_color: 'Primary' text: "bitmessage is 11 seconds behind the network" halign: 'center' - bold: True color: [0.941, 0, 0,1] BoxLayout: MDCheckbox: id: chkbox + size_hint: None, None size: dp(48), dp(64) active: True MDLabel: @@ -632,7 +621,6 @@ NavigationLayout: theme_text_color: 'Primary' text: "show settings (for advanced users only)" halign: 'left' - bold: True color: app.theme_cls.primary_dark : @@ -684,20 +672,20 @@ NavigationLayout: size: self.size MDLabel: size_hint_y: None - font_style: 'Subtitle1' + font_style: 'H5' theme_text_color: 'Primary' text: 'Platinum' halign: 'center' color: 1,1,1,1 MDLabel: - font_style: 'H4' + font_style: 'Subtitle1' theme_text_color: 'Primary' text: 'We provide subscriptions for proof of work calculation for first month. ' halign: 'center' color: 1,1,1,1 MDLabel: id: free_pak - font_style: 'Subtitle1' + font_style: 'H5' theme_text_color: 'Primary' text: '€ 50.0' halign: 'center' @@ -709,10 +697,11 @@ NavigationLayout: Rectangle: pos: self.pos size: self.size + size: dp(app.window_size[0]) - 2*dp(app.window_size[0]/16 if app.window_size[0] <= 720 else app.window_size[0]/4*1.1) - 10 , 1 height: dp(40) on_press: root.get_available_credits(self) MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Get Free Credits' font_size: '13sp' color: (0,0,0,1) @@ -729,19 +718,19 @@ NavigationLayout: size: self.size MDLabel: size_hint_y: None - font_style: 'Subtitle1' + font_style: 'H5' theme_text_color: 'Primary' text: 'Silver' halign: 'center' color: 1,1,1,1 MDLabel: - font_style: 'H4' + font_style: 'Subtitle1' theme_text_color: 'Primary' text: 'We provide for proof of work calculation for six month. ' halign: 'center' color: 1,1,1,1 MDLabel: - font_style: 'Subtitle1' + font_style: 'H5' theme_text_color: 'Primary' text: '€ 100.0' halign: 'center' @@ -753,9 +742,10 @@ NavigationLayout: Rectangle: pos: self.pos size: self.size + size: dp(app.window_size[0]) - 2*dp(app.window_size[0]/16 if app.window_size[0] <= 720 else app.window_size[0]/4*1.1) - 10 , 1 height: dp(40) MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Get Monthly Credits' font_size: '13sp' color: (0,0,0,1) @@ -772,19 +762,19 @@ NavigationLayout: size: self.size MDLabel: size_hint_y: None - font_style: 'Subtitle1' + font_style: 'H5' theme_text_color: 'Primary' text: 'Gold' halign: 'center' color: 1,1,1,1 MDLabel: - font_style: 'H4' + font_style: 'Subtitle1' theme_text_color: 'Primary' text: 'We provide for proof of work calculation for 1years. ' halign: 'center' color: 1,1,1,1 MDLabel: - font_style: 'Subtitle1' + font_style: 'H5' theme_text_color: 'Primary' text: '€ 500.0' halign: 'center' @@ -796,9 +786,10 @@ NavigationLayout: Rectangle: pos: self.pos size: self.size + size: dp(app.window_size[0]) - 2*dp(app.window_size[0]/16 if app.window_size[0] <= 720 else app.window_size[0]/4*1.1) - 10 , 1 height: dp(40) MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Get Yearly Credits' font_size: '13sp' color: (0,0,0,1) @@ -807,6 +798,7 @@ NavigationLayout: : id: popup + size_hint : (None,None) height: 2*(label.height + address.height) + 10 width :app.window_size[0] - app.window_size[0]/10 title: 'add contact\'s' @@ -839,29 +831,32 @@ NavigationLayout: orientation: 'horizontal' MDRaisedButton: id: save_addr + size_hint: 1.5, None height: dp(40) on_release: root.savecontact() MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Save' font_size: '13sp' color: (1,1,1,1) halign: 'center' MDRaisedButton: + size_hint: 1.5, None height: dp(40) on_press: root.dismiss() on_press: root.close_pop() MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Cancel' font_size: '13sp' color: (1,1,1,1) halign: 'center' MDRaisedButton: + size_hint: 2, None height: dp(40) MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Scan QR code' font_size: '13sp' color: (1,1,1,1) @@ -870,8 +865,91 @@ NavigationLayout: : name: 'networkstat' - Label: - text:"surbhi" + MDTabs: + id: tab_panel + tab_display_mode:'text' + + Tab: + text: "Total connections" + ScrollView: + do_scroll_x: False + MDList: + id: ml + size_hint_y: None + height: dp(200) + OneLineListItem: + text: "Total Connections" + BoxLayout: + AnchorLayout: + MDRaisedButton: + size_hint: .6, .3 + height: dp(40) + MDLabel: + font_style: 'H6' + text: root.text_variable_1 + font_size: '13sp' + color: (1,1,1,1) + halign: 'center' + Tab: + text: 'Processes' + ScrollView: + do_scroll_x: False + MDList: + id: ml + size_hint_y: None + height: dp(500) + OneLineListItem: + text: "person-to-person" + BoxLayout: + AnchorLayout: + MDRaisedButton: + size_hint: .7, .55 + height: dp(40) + MDLabel: + font_style: 'H6' + text: root.text_variable_2 + font_size: '13sp' + color: (1,1,1,1) + halign: 'center' + OneLineListItem: + text: "Brodcast" + BoxLayout: + AnchorLayout: + MDRaisedButton: + size_hint: .7, .55 + height: dp(40) + MDLabel: + font_style: 'H6' + text: root.text_variable_3 + font_size: '13sp' + color: (1,1,1,1) + halign: 'center' + OneLineListItem: + text: "publickeys" + BoxLayout: + AnchorLayout: + MDRaisedButton: + size_hint: .7, .55 + height: dp(40) + MDLabel: + font_style: 'H6' + text: root.text_variable_4 + font_size: '13sp' + color: (1,1,1,1) + halign: 'center' + OneLineListItem: + text: "objects" + BoxLayout: + AnchorLayout: + MDRaisedButton: + size_hint: .7, .55 + height: dp(40) + MDLabel: + font_style: 'H6' + text: root.text_variable_5 + font_size: '13sp' + color: (1,1,1,1) + halign: 'center' : name: 'mailDetail' @@ -949,6 +1027,7 @@ NavigationLayout: : id: myadd_popup + size_hint : (None,None) height: 4.5*(myaddr_label.height+ my_add_btn.children[0].height) width :app.window_size[0] - app.window_size[0]/10 background: './images/popup.jpeg' @@ -965,25 +1044,25 @@ NavigationLayout: spacing:dp(25) MDLabel: id: myaddr_label - font_style: 'H4' + font_style: 'Subtitle2' theme_text_color: 'Primary' text: "Label" font_size: '17sp' halign: 'left' MDLabel: - font_style: 'H4' + font_style: 'Body1' theme_text_color: 'Primary' text: root.address_label font_size: '15sp' halign: 'left' MDLabel: - font_style: 'H4' + font_style: 'Subtitle2' theme_text_color: 'Primary' text: "Address" font_size: '17sp' halign: 'left' MDLabel: - font_style: 'H4' + font_style: 'Body1' theme_text_color: 'Primary' text: root.address font_size: '15sp' @@ -993,31 +1072,34 @@ NavigationLayout: spacing:5 orientation: 'horizontal' MDRaisedButton: + size_hint: 2, None height: dp(40) on_press: root.send_message_from() MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Send message from' font_size: '13sp' color: (1,1,1,1) halign: 'center' MDRaisedButton: + size_hint: 1.5, None height: dp(40) on_press: root.dismiss() on_press: app.root.ids.scr_mngr.current = 'showqrcode' on_press: app.root.ids.sc15.qrdisplay() MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Show QR code' font_size: '13sp' color: (1,1,1,1) halign: 'center' MDRaisedButton: + size_hint: 1.5, None height: dp(40) on_press: root.dismiss() on_press: root.close_pop() MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Cancel' font_size: '13sp' color: (1,1,1,1) @@ -1025,6 +1107,7 @@ NavigationLayout: : id: addbook_popup + size_hint : (None,None) height: 4*(add_label.height) width :app.window_size[0] - app.window_size[0]/10 background: './images/popup.jpeg' @@ -1040,14 +1123,14 @@ NavigationLayout: orientation: 'vertical' spacing:dp(20) MDLabel: - font_style: 'H4' + font_style: 'Subtitle2' theme_text_color: 'Primary' text: "Label" font_size: '17sp' halign: 'left' MDTextField: id: add_label - font_style: 'H4' + font_style: 'Body1' font_size: '15sp' halign: 'left' text: root.address_label @@ -1055,13 +1138,13 @@ NavigationLayout: required: True helper_text_mode: "on_error" MDLabel: - font_style: 'H4' + font_style: 'Subtitle2' theme_text_color: 'Primary' text: "Address" font_size: '17sp' halign: 'left' MDLabel: - font_style: 'H4' + font_style: 'Body1' theme_text_color: 'Primary' text: root.address font_size: '15sp' @@ -1071,30 +1154,33 @@ NavigationLayout: spacing:5 orientation: 'horizontal' MDRaisedButton: + size_hint: 2, None height: dp(40) on_press: root.send_message_to() MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Send message to' font_size: '13sp' color: (1,1,1,1) halign: 'center' MDRaisedButton: + size_hint: 1.5, None height: dp(40) font_size: '10sp' on_press: root.update_addbook_label(root.address) MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Save' font_size: '13sp' color: (1,1,1,1) halign: 'center' MDRaisedButton: + size_hint: 1.5, None height: dp(40) on_press: root.dismiss() on_press: root.close_pop() MDLabel: - font_style: 'H4' + font_style: 'H6' text: 'Cancel' font_size: '13sp' color: (1,1,1,1) @@ -1125,4 +1211,4 @@ NavigationLayout: MDTextField: id: search_field hint_text: 'Search' - on_text: app.searchQuery(self) + on_text: app.searchQuery(self) \ No newline at end of file diff --git a/src/bitmessagekivy/mpybit.py b/src/bitmessagekivy/mpybit.py index aa55d35b..42b2532e 100644 --- a/src/bitmessagekivy/mpybit.py +++ b/src/bitmessagekivy/mpybit.py @@ -65,9 +65,8 @@ from kivy.core.clipboard import Clipboard def toast(text): """Method will display the toast message.""" - if platform == 'linux': - from kivymd.toast.kivytoast import toast # pylint: disable=redefined-outer-name - toast(text) + from kivymd.toast.kivytoast import toast # pylint: disable=redefined-outer-name + toast(text) return @@ -157,12 +156,11 @@ class Inbox(Screen): self.ids.ml.add_widget(carousel) else: content = MDLabel( - font_style='Body1', + font_style='Caption', theme_text_color='Primary', text="No message found!" if state.searcing_text else "yet no message for this account!!!!!!!!!!!!!", halign='center', - bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) @@ -276,12 +274,11 @@ class MyAddress(Screen): self.ids.ml.add_widget(meny) else: content = MDLabel( - font_style='Body1', + font_style='Caption', theme_text_color='Primary', text="No address found!" if state.searcing_text else "yet no address is created by user!!!!!!!!!!!!!", halign='center', - bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) @@ -371,12 +368,11 @@ class AddressBook(Screen): self.ids.ml.add_widget(carousel) else: content = MDLabel( - font_style='Body1', + font_style='Caption', theme_text_color='Primary', text="No contact found!" if state.searcing_text else "No contact found yet...... ", halign='center', - bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) @@ -384,8 +380,9 @@ class AddressBook(Screen): @staticmethod def refreshs(*args): """Refresh the Widget.""" - state.navinstance.ids.sc11.ids.ml.clear_widgets() - state.navinstance.ids.sc11.loadAddresslist(None, 'All', '') + # state.navinstance.ids.sc11.ids.ml.clear_widgets() + # state.navinstance.ids.sc11.loadAddresslist(None, 'All', '') + pass @staticmethod def addBook_detail(address, label, *args): @@ -563,6 +560,7 @@ class DropDownWidget(BoxLayout): self.ids.txt_input.text = '' self.ids.subject.text = '' self.ids.body.text = '' + toast("Reset message") def auto_fill_fromaddr(self): """Mehtod used to fill the text automatically From Address.""" @@ -699,6 +697,7 @@ class Random(Screen): self.parent.parent.parent.parent.ids.toolbar.opacity = 1 self.parent.parent.parent.parent.ids.toolbar.disabled = False self.parent.parent.parent.parent.ids.sc10.ids.ml.clear_widgets() + self.manager.current = 'myaddress' self.parent.parent.parent.parent.ids.sc10.init_ui() self.manager.current = 'myaddress' toast('New address created') @@ -791,12 +790,11 @@ class Sent(Screen): self.ids.ml.add_widget(carousel) else: content = MDLabel( - font_style='Body1', + font_style='Caption', theme_text_color='Primary', text="No message found!" if state.searcing_text else "yet no message for this account!!!!!!!!!!!!!", halign='center', - bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) @@ -917,11 +915,10 @@ class Trash(Screen): self.ids.ml.add_widget(carousel) else: content = MDLabel( - font_style='Body1', + font_style='Caption', theme_text_color='Primary', text="yet no trashed message for this account!!!!!!!!!!!!!", halign='center', - bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) @@ -1100,7 +1097,7 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods """Getting default image on address""" if BMConfigParser().addresses(): return './images/default_identicon/{}.png'.format(BMConfigParser().addresses()[0]) - return '' + return './images/no_identicons.png' @staticmethod def addressexist(): @@ -1164,6 +1161,7 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods self.root.ids.toolbar.left_action_items = [ ['arrow-left', lambda x: self.back_press()]] self.root.ids.toolbar.right_action_items = [ + ['refresh', lambda x: self.root.ids.sc3.children[0].reset_composer()], ['send', lambda x: self.root.ids.sc3.children[0].send(self)]] def back_press(self): @@ -1173,7 +1171,9 @@ class NavigateApp(App): # pylint: disable=too-many-public-methods self.root.ids.toolbar.left_action_items = \ [['menu', lambda x: self.root.toggle_nav_drawer()]] self.root.ids.scr_mngr.current = 'inbox' \ - if state.in_composer else 'allmails' if state.is_allmail else state.detailPageType + if state.in_composer else 'allmails'\ + if state.is_allmail else state.detailPageType\ + if state.detailPageType else 'inbox' self.root.ids.scr_mngr.transition.direction = 'right' self.root.ids.scr_mngr.transition.bind(on_complete=self.reset) if state.is_allmail or state.detailPageType == 'draft': @@ -1305,10 +1305,12 @@ class GrashofPopup(Popup): stored_address = [addr[1] for addr in kivy_helper_search.search_sql( folder="addressbook")] if label and address and address not in stored_address: - state.navinstance = self.parent.children[1] + # state.navinstance = self.parent.children[1] queues.UISignalQueue.put(('rerenderAddressBook', '')) self.dismiss() sqlExecute("INSERT INTO addressbook VALUES(?,?)", label, address) + state.kivyapp.root.ids.sc11.ids.ml.clear_widgets() + state.kivyapp.root.ids.sc11.loadAddresslist(None, 'All', '') self.parent.children[1].ids.scr_mngr.current = 'addressbook' toast('Saved') @@ -1469,6 +1471,8 @@ class MailDetail(Screen): sqlExecute( "UPDATE inbox SET folder = 'trash' WHERE \ msgid = ?;", str(state.mail_id)) + msg_count_objs.inbox_cnt.badge_text = str(int(state.inbox_count) - 1) + state.inbox_count = str(int(state.inbox_count) - 1) self.parent.screens[0].ids.ml.clear_widgets() self.parent.screens[0].loadMessagelist(state.association) elif state.detailPageType == 'draft': @@ -1597,7 +1601,7 @@ class AddbookDetailPopup(Popup): window_obj = self.parent.children[1].ids window_obj.sc3.children[0].ids.txt_input.text = self.address window_obj.sc3.children[0].ids.ti.text = '' - window_obj.sc3.children[0].ids.btn.text = '' + window_obj.sc3.children[0].ids.btn.text = 'Select' window_obj.sc3.children[0].ids.subject.text = '' window_obj.sc3.children[0].ids.body.text = '' window_obj.scr_mngr.current = 'create' @@ -1692,11 +1696,10 @@ class Draft(Screen): self.ids.ml.add_widget(carousel) else: content = MDLabel( - font_style='Body1', + font_style='Caption', theme_text_color='Primary', text="yet no message for this account!!!!!!!!!!!!!", halign='center', - bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) @@ -1815,16 +1818,11 @@ class Allmails(Screen): def loadMessagelist(self, account, where="", what=""): """Load Inbox, Sent anf Draft list of messages.""" - inbox = sqlQuery( - "SELECT toaddress, fromaddress, subject, message, folder, msgid from\ - inbox WHERE folder = 'inbox' and toaddress = '{}';".format( - account)) - sent_and_draft = sqlQuery( - "SELECT toaddress, fromaddress, subject, message, folder, ackdata from sent \ - WHERE folder = 'sent' and fromaddress = '{}';".format( - account)) - - all_mails = inbox + sent_and_draft + all_mails = sqlQuery( + "SELECT toaddress, fromaddress, subject, message, folder, ackdata As id, DATE(lastactiontime)" + " As actionTime FROM sent WHERE folder = 'sent' UNION" + " SELECT toaddress, fromaddress, subject, message, folder, msgid As id, DATE(received) As" + " actionTime FROM inbox WHERE folder = 'inbox' ORDER BY actionTime DESC") if all_mails: state.kivyapp.root.children[2].children[0].ids.allmail_cnt.badge_text = str(len(all_mails)) state.all_count = str(len(all_mails)) @@ -1858,11 +1856,10 @@ class Allmails(Screen): self.ids.ml.add_widget(carousel) else: content = MDLabel( - font_style='Body1', + font_style='Caption', theme_text_color='Primary', text="yet no message for this account!!!!!!!!!!!!!", halign='center', - bold=True, size_hint_y=None, valign='top') self.ids.ml.add_widget(content) @@ -1966,4 +1963,4 @@ class Archieve(Screen): class Spam(Screen): """Spam Screen show widgets of page.""" - pass + pass \ No newline at end of file