added support for updating header, avatar and the 4 fields

This commit is contained in:
Abdulqadir Ahmad 2023-06-09 10:53:11 +01:00
parent 453630e655
commit 6d7f808196
2 changed files with 160 additions and 8 deletions

View File

@ -265,10 +265,19 @@ class Handler(object):
data = {
'display_name': profile.display_name,
'note': html_filter(profile.note),
'header': profile.header,
'avatar': profile.avatar,
'fields': [(field.name, html_filter(field.value)) for field in profile.fields],
}
log.debug(f"arafat {data['fields']}")
dialog = update_profile_dialogs.UpdateProfileDialog(**data)
if dialog.ShowModal() != wx.ID_OK: return
if dialog.ShowModal() != wx.ID_OK:
log.debug("User canceled dialog")
return
updated_data = dialog.data
if updated_data == data:
log.debug("No profile info was changed.")
return
# remove data that hasn't been updated
for key in data:
if data[key] == updated_data[key]:

View File

@ -1,6 +1,15 @@
import os
import requests
from io import BytesIO
import wx
from logging import getLogger;log = getLogger()
def return_true():
return True
class UpdateProfileDialog(wx.Dialog):
"""
A dialog for user to update his / her profile details.
@ -14,14 +23,20 @@ class UpdateProfileDialog(wx.Dialog):
```
"""
def __init__(self, display_name: str="", note: str=""):
def __init__(self, display_name: str="", note: str="", header: str="",
avatar: str="", fields: list=[]):
"""Initialize update profile dialog
Parameters:
- display_name: The user's display name to show in the display name field
- note: The users bio to show in the bio field
- header: the users header pic link
- avatar: The users avatar pic link
"""
super().__init__(parent=None)
self.SetTitle(_("Update Profile"))
self.header = header
self.avatar = avatar
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
@ -31,27 +46,155 @@ class UpdateProfileDialog(wx.Dialog):
wx.TE_PROCESS_ENTER)
bio_label = wx.StaticText(panel, label=_("Bio"))
self.bio = wx.TextCtrl(panel, value=note, style=wx.TE_PROCESS_ENTER)
# header
header_label = wx.StaticText(panel, label=_("Header"))
try:
response = requests.get(self.header)
except requests.exceptions.RequestException:
# Create empty image
self.header_image = wx.StaticBitmap()
else:
image_bytes = BytesIO(response.content)
image = wx.Image(image_bytes, wx.BITMAP_TYPE_ANY)
image.Rescale(300, 100, wx.IMAGE_QUALITY_HIGH)
self.header_image = wx.StaticBitmap(panel, bitmap=image.ConvertToBitmap())
self.header_image.AcceptsFocusFromKeyboard = return_true
self.change_header = wx.Button(panel, label=_("Change header"))
# avatar
avatar_label = wx.StaticText(panel, label=_("Avatar"))
try:
response = requests.get(self.avatar)
except requests.exceptions.RequestException:
# Create empty image
self.avatar_image = wx.StaticBitmap()
else:
image_bytes = BytesIO(response.content)
image = wx.Image(image_bytes, wx.BITMAP_TYPE_ANY)
image.Rescale(150, 150, wx.IMAGE_QUALITY_HIGH)
self.avatar_image = wx.StaticBitmap(panel, bitmap=image.ConvertToBitmap())
self.avatar_image.AcceptsFocusFromKeyboard = return_true
self.change_avatar = wx.Button(panel, label=_("Change avatar"))
self.fields = []
for i in range(1, 5):
field_sizer = wx.BoxSizer(wx.HORIZONTAL)
field_label = wx.StaticText(panel, label=_("Field {}: Label").format(i))
field_sizer.Add(field_label, wx.SizerFlags().Center().Border(wx.ALL, 5))
label_textctrl = wx.TextCtrl(panel, style=wx.TE_PROCESS_ENTER)
if i <= len(fields):
label_textctrl.SetValue(fields[i-1][0])
log.debug(f"Field {i}: label = {fields[i-1][0]}")
field_sizer.Add(label_textctrl, wx.SizerFlags().Expand().Border(wx.ALL, 5))
content_label = wx.StaticText(panel, label=_("Content"))
field_sizer.Add(content_label, wx.SizerFlags().Center().Border(wx.ALL, 5))
content_textctrl = wx.TextCtrl(panel, style=wx.TE_PROCESS_ENTER)
if i <= len(fields):
content_textctrl.SetValue(fields[i-1][1])
log.debug(f"content: {fields[i-1][1]}")
field_sizer.Add(content_textctrl, wx.SizerFlags().Expand().Border(wx.ALL, 5))
sizer.Add(field_sizer, 0, wx.CENTER)
self.fields.append((label_textctrl, content_textctrl))
ok = wx.Button(panel, wx.ID_OK, _(u"&OK"))
ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
self.SetEscapeId(cancel.GetId())
# manage sizers
sizer.Add(display_name_label, wx.SizerFlags().Center())
sizer.Add(self.display_name, wx.SizerFlags().Center())
sizer.Add(cancel, wx.SizerFlags().Center())
sizer.Add(ok, wx.SizerFlags().Center())
sizer.Add(self.bio, wx.SizerFlags().Center())
name_sizer = wx.BoxSizer(wx.HORIZONTAL)
name_sizer.Add(display_name_label, wx.SizerFlags().Center())
name_sizer.Add(self.display_name, wx.SizerFlags().Center())
sizer.Add(name_sizer, wx.CENTER)
bio_sizer = wx.BoxSizer(wx.HORIZONTAL)
bio_sizer.Add(bio_label, wx.SizerFlags().Center())
bio_sizer.Add(self.bio, wx.SizerFlags().Center())
sizer.Add(bio_sizer, wx.CENTER)
header_sizer = wx.BoxSizer(wx.HORIZONTAL)
header_sizer.Add(header_label, wx.SizerFlags().Center())
header_sizer.Add(self.header_image, wx.SizerFlags().Center())
header_sizer.Add(self.change_header, wx.SizerFlags().Center())
sizer.Add(header_sizer, wx.CENTER)
avatar_sizer = wx.BoxSizer(wx.HORIZONTAL)
avatar_sizer.Add(avatar_label, wx.SizerFlags().Center())
avatar_sizer.Add(self.avatar_image, wx.SizerFlags().Center())
avatar_sizer.Add(self.change_avatar, wx.SizerFlags().Center())
sizer.Add(avatar_sizer, wx.CENTER)
action_sizer = wx.BoxSizer(wx.HORIZONTAL)
action_sizer.Add(ok, wx.SizerFlags().Center())
action_sizer.Add(cancel, wx.SizerFlags().Center())
sizer.Add(action_sizer, wx.CENTER)
panel.SetSizer(sizer)
panel.Fit()
# manage events
ok.Bind(wx.EVT_BUTTON, self.on_ok)
self.change_header.Bind(wx.EVT_BUTTON, self.on_change_header)
self.change_avatar.Bind(wx.EVT_BUTTON, self.on_change_avatar)
self.AutoLayout = True
def on_ok(self, *args):
"""Method called when user clicks ok in dialog"""
self.data = {
'display_name': self.display_name.GetValue(),
'note': self.bio.GetValue()
'note': self.bio.GetValue(),
'header': self.header,
'avatar': self.avatar,
'fields': [(label.GetValue(), content.GetValue()) for label, content in self.fields if label.GetValue() and content.GetValue()]
}
self.EndModal(wx.ID_OK)
def on_change_header(self, *args):
"""Display a dialog for the user to choose a picture and update the
appropriate attribute"""
wildcard = "Images (*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif"
dlg = wx.FileDialog(self, _("Select header image - max 2MB"), wildcard=wildcard)
if dlg.ShowModal() == wx.CLOSE:
return
if os.path.getsize(dlg.GetPath()) > 2097152:
# File size exceeds the limit
message = _("The selected file is larger than 2MB. Do you want to select another file?")
caption = _("File more than 2MB")
style = wx.YES_NO | wx.ICON_WARNING
# Display the message box
result = wx.MessageBox(message, caption, style)
return self.on_change_header() if result == wx.YES else None
self.header = dlg.GetPath()
image = wx.Image(self.header, wx.BITMAP_TYPE_ANY)
image.Rescale(150, 150, wx.IMAGE_QUALITY_HIGH)
self.header_image.SetBitmap(image.ConvertToBitmap())
def on_change_avatar(self, *args):
"""Display a dialog for the user to choose a picture and update the
appropriate attribute"""
wildcard = "Images (*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif"
dlg = wx.FileDialog(self, _("Select avatar image - max 2MB"), wildcard=wildcard)
if dlg.ShowModal() == wx.CLOSE:
return
if os.path.getsize(dlg.GetPath()) > 2097152:
# File size exceeds the limit
message = _("The selected file is larger than 2MB. Do you want to select another file?")
caption = _("File more than 2MB")
style = wx.YES_NO | wx.ICON_WARNING
# Display the message box
result = wx.MessageBox(message, caption, style)
return self.on_change_avatar() if result == wx.YES else None
self.avatar = dlg.GetPath()
image = wx.Image(self.avatar, wx.BITMAP_TYPE_ANY)
image.Rescale(150, 150, wx.IMAGE_QUALITY_HIGH)
self.avatar_image.SetBitmap(image.ConvertToBitmap())