fix(@desktop/sugnup): Profile omage chosen during signup sould be saved for the user and squish test for the same
fixes #6861
This commit is contained in:
parent
b23414e999
commit
8eb328bae7
|
@ -241,10 +241,10 @@ method onNodeLogin*[T](self: Module[T], error: string) =
|
||||||
quit() # quit the app
|
quit() # quit the app
|
||||||
|
|
||||||
if error.len == 0:
|
if error.len == 0:
|
||||||
self.controller.cleanTmpData()
|
|
||||||
self.delegate.userLoggedIn()
|
self.delegate.userLoggedIn()
|
||||||
if currStateObj.flowType() != FlowType.AppLogin:
|
if currStateObj.flowType() != FlowType.AppLogin:
|
||||||
self.controller.storeIdentityImage()
|
self.controller.storeIdentityImage()
|
||||||
|
self.controller.cleanTmpData()
|
||||||
else:
|
else:
|
||||||
self.view.setAppState(AppState.StartupState)
|
self.view.setAppState(AppState.StartupState)
|
||||||
if currStateObj.flowType() == FlowType.AppLogin:
|
if currStateObj.flowType() == FlowType.AppLogin:
|
||||||
|
@ -300,4 +300,4 @@ method onSharedKeycarModuleFlowTerminated*[T](self: Module[T], lastStepInTheCurr
|
||||||
self.keycardSharedModule = nil
|
self.keycardSharedModule = nil
|
||||||
if lastStepInTheCurrentFlow:
|
if lastStepInTheCurrentFlow:
|
||||||
self.controller.cleanTmpData()
|
self.controller.cleanTmpData()
|
||||||
self.view.setCurrentStartupState(newWelcomeState(FlowType.General, nil))
|
self.view.setCurrentStartupState(newWelcomeState(FlowType.General, nil))
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
|
@ -28,6 +28,7 @@ _MAX_WAIT_OBJ_TIMEOUT = 5000
|
||||||
# The default minimum timeout to find ui object
|
# The default minimum timeout to find ui object
|
||||||
_MIN_WAIT_OBJ_TIMEOUT = 500
|
_MIN_WAIT_OBJ_TIMEOUT = 500
|
||||||
|
|
||||||
|
_SEARCH_IMAGES_PATH = "../shared/searchImages/"
|
||||||
|
|
||||||
# Waits for the given object is loaded, visible and enabled.
|
# Waits for the given object is loaded, visible and enabled.
|
||||||
# It returns a tuple: True in case it is found. Otherwise, false. And the object itself.
|
# It returns a tuple: True in case it is found. Otherwise, false. And the object itself.
|
||||||
|
@ -297,3 +298,7 @@ def verify_not_found(realNameVarName: str, message: str, timeoutMSec: int = 500)
|
||||||
test.fail(message, f'Unexpected: the object "{realNameVarName}" was found.')
|
test.fail(message, f'Unexpected: the object "{realNameVarName}" was found.')
|
||||||
except LookupError as err:
|
except LookupError as err:
|
||||||
test.passes(message, f'Expected: the object "{realNameVarName}" was not found. Exception: {str(err)}.')
|
test.passes(message, f'Expected: the object "{realNameVarName}" was not found. Exception: {str(err)}.')
|
||||||
|
|
||||||
|
def grabScreenshot_and_save(obj, imageName:str, delay:int = 0):
|
||||||
|
img = object.grabScreenshot(obj, {"delay": delay})
|
||||||
|
img.save(_SEARCH_IMAGES_PATH + imageName + ".png")
|
||||||
|
|
|
@ -100,3 +100,6 @@ def log(text: str):
|
||||||
|
|
||||||
def verify_screenshot(vp: str):
|
def verify_screenshot(vp: str):
|
||||||
test.vp(vp)
|
test.vp(vp)
|
||||||
|
|
||||||
|
def imagePresent(imageName: str, tolerant: bool = True, threshold: int = 99.5, minScale: int = 50, maxScale: int = 200, multiscale: bool = True):
|
||||||
|
test.imagePresent(imageName, {"tolerant": tolerant, "threshold": threshold, "minScale": minScale, "maxScale": maxScale, "multiscale": multiscale})
|
||||||
|
|
|
@ -16,12 +16,11 @@ from drivers.SquishDriverVerification import *
|
||||||
import time
|
import time
|
||||||
|
|
||||||
class MainScreenComponents(Enum):
|
class MainScreenComponents(Enum):
|
||||||
STATUS_ICON = "mainWindow_statusIcon_StatusIcon_2"
|
|
||||||
PUBLIC_CHAT_ICON = "mainWindow_public_chat_icon_StatusIcon"
|
PUBLIC_CHAT_ICON = "mainWindow_public_chat_icon_StatusIcon"
|
||||||
CHAT_NAVBAR_ICON = "navBarListView_Chat_navbar_StatusNavBarTabButton"
|
CHAT_NAVBAR_ICON = "navBarListView_Chat_navbar_StatusNavBarTabButton"
|
||||||
COMMUNITY_PORTAL_BUTTON = "navBarListView_Communities_Portal_navbar_StatusNavBarTabButton"
|
COMMUNITY_PORTAL_BUTTON = "navBarListView_Communities_Portal_navbar_StatusNavBarTabButton"
|
||||||
JOIN_PUBLIC_CHAT = "join_public_chat_StatusMenuItemDelegate"
|
JOIN_PUBLIC_CHAT = "join_public_chat_StatusMenuItemDelegate"
|
||||||
SETTINGS_BUTTON = "settings_navbar_settings_icon_StatusIcon"
|
SETTINGS_BUTTON = "navBarListView_Settings_navbar_StatusNavBarTabButton"
|
||||||
WALLET_BUTTON = "wallet_navbar_wallet_icon_StatusIcon"
|
WALLET_BUTTON = "wallet_navbar_wallet_icon_StatusIcon"
|
||||||
START_CHAT_BTN = "mainWindow_startChat"
|
START_CHAT_BTN = "mainWindow_startChat"
|
||||||
CHAT_LIST = "chatList_Repeater"
|
CHAT_LIST = "chatList_Repeater"
|
||||||
|
|
|
@ -14,6 +14,7 @@ import sys
|
||||||
from drivers.SquishDriver import *
|
from drivers.SquishDriver import *
|
||||||
from drivers.SquishDriverVerification import *
|
from drivers.SquishDriverVerification import *
|
||||||
from common.SeedUtils import *
|
from common.SeedUtils import *
|
||||||
|
from screens.StatusMainScreen import MainScreenComponents
|
||||||
|
|
||||||
|
|
||||||
class AgreementPopUp(Enum):
|
class AgreementPopUp(Enum):
|
||||||
|
@ -36,7 +37,9 @@ class SignUpComponents(Enum):
|
||||||
CONFIRM_PSW_AGAIN_INPUT: str = "onboarding_confirmPswAgain_Input"
|
CONFIRM_PSW_AGAIN_INPUT: str = "onboarding_confirmPswAgain_Input"
|
||||||
FINALIZE_PSW_BUTTON: str = "onboarding_finalise_password_button"
|
FINALIZE_PSW_BUTTON: str = "onboarding_finalise_password_button"
|
||||||
PASSWORD_PREFERENCE: str = "mainWindow_I_prefer_to_use_my_password_StatusBaseText"
|
PASSWORD_PREFERENCE: str = "mainWindow_I_prefer_to_use_my_password_StatusBaseText"
|
||||||
|
PROFILE_IMAGE_CROP_WORKFLOW_ITEM: str = "mainWindow_WelcomeScreen_Image_Crop_Workflow_Item"
|
||||||
|
PROFILE_IMAGE_CROPPER_ACCEPT_BUTTON: str = "mainWindow_WelcomeScreen_Image_Cropper_Accept_Button"
|
||||||
|
WELCOME_SCREEN_USER_PROFILE_IMAGE: str = "mainWindow_WelcomeScreen_User_Profile_Image"
|
||||||
|
|
||||||
class SeedPhraseComponents(Enum):
|
class SeedPhraseComponents(Enum):
|
||||||
IMPORT_A_SEED_TEXT: str = "import_a_seed_phrase_StatusBaseText"
|
IMPORT_A_SEED_TEXT: str = "import_a_seed_phrase_StatusBaseText"
|
||||||
|
@ -58,6 +61,20 @@ class PasswordStrengthPossibilities(Enum):
|
||||||
NUMBERS_SYMBOLS_LOWER_UPPER_GOOD = "numbers_symbols_lower_upper_good"
|
NUMBERS_SYMBOLS_LOWER_UPPER_GOOD = "numbers_symbols_lower_upper_good"
|
||||||
NUMBERS_SYMBOLS_LOWER_UPPER_GREAT = "numbers_symbols_lower_upper_great"
|
NUMBERS_SYMBOLS_LOWER_UPPER_GREAT = "numbers_symbols_lower_upper_great"
|
||||||
|
|
||||||
|
class MainScreen(Enum):
|
||||||
|
SETTINGS_BUTTON = "settings_navbar_settings_icon_StatusIcon"
|
||||||
|
|
||||||
|
class UserContextStatusMenu(Enum):
|
||||||
|
USER_CONTEXT_MENU_VIEW_MY_PROFILE_BUTTON: str = "userContextMenu_ViewMyProfile_Action"
|
||||||
|
|
||||||
|
class MyProfileModal(Enum):
|
||||||
|
MY_PROFILE_MODAL_USER_IMAGE: str = "myProfileModal_UserImage"
|
||||||
|
|
||||||
|
class LoginView(Enum):
|
||||||
|
LOGIN_VIEW_USER_IMAGE: str = "loginView_userImage"
|
||||||
|
PASSWORD_INPUT = "loginView_passwordInput"
|
||||||
|
SUBMIT_BTN = "loginView_submitBtn"
|
||||||
|
|
||||||
class StatusWelcomeScreen:
|
class StatusWelcomeScreen:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -99,6 +116,7 @@ class StatusWelcomeScreen:
|
||||||
def input_username(self, username: str):
|
def input_username(self, username: str):
|
||||||
type(SignUpComponents.USERNAME_INPUT.value, username)
|
type(SignUpComponents.USERNAME_INPUT.value, username)
|
||||||
click_obj_by_name(SignUpComponents.DETAILS_NEXT_BUTTON.value)
|
click_obj_by_name(SignUpComponents.DETAILS_NEXT_BUTTON.value)
|
||||||
|
|
||||||
# There is another page with the same Next button
|
# There is another page with the same Next button
|
||||||
click_obj_by_name(SignUpComponents.DETAILS_NEXT_BUTTON.value)
|
click_obj_by_name(SignUpComponents.DETAILS_NEXT_BUTTON.value)
|
||||||
|
|
||||||
|
@ -152,4 +170,60 @@ class StatusWelcomeScreen:
|
||||||
verify_screenshot("VP-PWStrength-numbers_symbols_lower_upper_great")
|
verify_screenshot("VP-PWStrength-numbers_symbols_lower_upper_great")
|
||||||
|
|
||||||
# TODO: Get screenshots in Linux
|
# TODO: Get screenshots in Linux
|
||||||
|
|
||||||
|
def input_profile_image(self, profileImageUrl: str):
|
||||||
|
workflow = get_obj(SignUpComponents.PROFILE_IMAGE_CROP_WORKFLOW_ITEM.value)
|
||||||
|
workflow.cropImage(profileImageUrl)
|
||||||
|
click_obj_by_name(SignUpComponents.PROFILE_IMAGE_CROPPER_ACCEPT_BUTTON.value)
|
||||||
|
|
||||||
|
def input_username_and_grab_profile_image_sreenshot(self, username: str):
|
||||||
|
type(SignUpComponents.USERNAME_INPUT.value, username)
|
||||||
|
click_obj_by_name(SignUpComponents.DETAILS_NEXT_BUTTON.value)
|
||||||
|
|
||||||
|
# take a screenshot of the profile image to compare it later with the main screen
|
||||||
|
profileIcon = wait_and_get_obj(SignUpComponents.WELCOME_SCREEN_USER_PROFILE_IMAGE.value)
|
||||||
|
grabScreenshot_and_save(profileIcon, "profiletestimage", 200)
|
||||||
|
|
||||||
|
# There is another page with the same Next button
|
||||||
|
click_obj_by_name(SignUpComponents.DETAILS_NEXT_BUTTON.value)
|
||||||
|
|
||||||
|
def input_username_profileImage_password_and_finalize_sign_up(self, profileImageUrl: str, username: str, password: str):
|
||||||
|
self.input_profile_image(profileImageUrl)
|
||||||
|
|
||||||
|
self.input_username_and_grab_profile_image_sreenshot(username)
|
||||||
|
|
||||||
|
self.input_password(password)
|
||||||
|
|
||||||
|
self.input_confirmation_password(password)
|
||||||
|
|
||||||
|
if sys.platform == "darwin":
|
||||||
|
click_obj_by_name(SignUpComponents.PASSWORD_PREFERENCE.value)
|
||||||
|
|
||||||
|
def profile_modal_image_is_updated(self):
|
||||||
|
click_obj_by_name(MainScreenComponents.PROFILE_NAVBAR_BUTTON.value)
|
||||||
|
click_obj_by_name(UserContextStatusMenu.USER_CONTEXT_MENU_VIEW_MY_PROFILE_BUTTON.value)
|
||||||
|
imagePresent("profiletestimage", True, 97, 95, 100, True)
|
||||||
|
|
||||||
|
def profile_settings_image_is_updated(self):
|
||||||
|
# first time clicking on settings button closes the my profile modal
|
||||||
|
click_obj_by_name(MainScreen.SETTINGS_BUTTON.value)
|
||||||
|
click_obj_by_name(MainScreen.SETTINGS_BUTTON.value)
|
||||||
|
imagePresent("profiletestimage", True, 97, 100, 183, True)
|
||||||
|
|
||||||
|
def grab_screenshot(self):
|
||||||
|
# take a screenshot of the profile image to compare it later with the main screen
|
||||||
|
loginUserName = wait_and_get_obj(LoginView.LOGIN_VIEW_USER_IMAGE.value)
|
||||||
|
grabScreenshot_and_save(loginUserName, "loginUserName", 200)
|
||||||
|
|
||||||
|
def profile_image_is_updated(self):
|
||||||
|
profileNavBarButton = wait_and_get_obj(MainScreenComponents.PROFILE_NAVBAR_BUTTON.value)
|
||||||
|
imagePresent("loginUserName", True, 98, 85, 100, True)
|
||||||
|
|
||||||
|
click_obj(profileNavBarButton)
|
||||||
|
imagePresent("loginUserName", True, 99, 95, 100, True)
|
||||||
|
|
||||||
|
def enter_password(self, password):
|
||||||
|
click_obj_by_name(LoginView.PASSWORD_INPUT.value)
|
||||||
|
type(LoginView.PASSWORD_INPUT.value, password)
|
||||||
|
click_obj_by_name(LoginView.SUBMIT_BTN.value)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
from remotesystem import RemoteSystem
|
||||||
|
from drivers.SquishDriverVerification import *
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path as path
|
import os.path as path
|
||||||
import shutil
|
import shutil
|
||||||
import distutils.dir_util
|
import distutils.dir_util
|
||||||
|
|
||||||
|
|
||||||
def erase_directory(dir: str):
|
def erase_directory(dir: str):
|
||||||
directory = path.abspath(path.join(__file__, dir))
|
directory = path.abspath(path.join(__file__, dir))
|
||||||
if (os.path.isdir(directory)):
|
if (os.path.isdir(directory)):
|
||||||
|
@ -27,3 +29,14 @@ def copy_directory(src: str, dst: str):
|
||||||
distutils.dir_util.copy_tree(src, dst)
|
distutils.dir_util.copy_tree(src, dst)
|
||||||
except OSError:
|
except OSError:
|
||||||
os.remove(dst)
|
os.remove(dst)
|
||||||
|
|
||||||
|
def delete_created_searchImage(fileName: str):
|
||||||
|
try:
|
||||||
|
remoteOS = RemoteSystem()
|
||||||
|
verify(remoteOS.deleteFile(fileName), "screenshot file was not deleted" + fileName)
|
||||||
|
verify(not remoteOS.exists(fileName), "screenshot file was not deleted" + fileName)
|
||||||
|
except Exception as e:
|
||||||
|
verify_failure("RemoteSystem error" + str(e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ def hook(context):
|
||||||
context.userData = {}
|
context.userData = {}
|
||||||
context.userData["aut_name"] = _status_desktop_app_name
|
context.userData["aut_name"] = _status_desktop_app_name
|
||||||
context.userData["status_data_folder_path"] = _status_data_folder_path
|
context.userData["status_data_folder_path"] = _status_data_folder_path
|
||||||
|
context.userData["fixtures_root"] = os.path.join(os.path.dirname(__file__), "../../../fixtures/")
|
||||||
|
context.userData["search_images"] = os.path.join(os.path.dirname(__file__), "../shared/searchImages/")
|
||||||
|
|
||||||
@OnScenarioEnd
|
@OnScenarioEnd
|
||||||
def hook(context):
|
def hook(context):
|
||||||
|
|
|
@ -9,6 +9,10 @@ statusDesktop_mainWindow_AppMain_EmojiPopup_SearchTextInput = {"container": stat
|
||||||
mainWindow_ScrollView = {"container": statusDesktop_mainWindow, "type": "StatusScrollView", "unnamed": 1, "visible": True}
|
mainWindow_ScrollView = {"container": statusDesktop_mainWindow, "type": "StatusScrollView", "unnamed": 1, "visible": True}
|
||||||
mainWindow_ScrollView_2 = {"container": statusDesktop_mainWindow, "occurrence": 2, "type": "StatusScrollView", "unnamed": 1, "visible": True}
|
mainWindow_ScrollView_2 = {"container": statusDesktop_mainWindow, "occurrence": 2, "type": "StatusScrollView", "unnamed": 1, "visible": True}
|
||||||
mainWindow_ProfileNavBarButton = {"container": statusDesktop_mainWindow, "objectName": "statusProfileNavBarTabButton", "type": "StatusNavBarTabButton", "visible": True}
|
mainWindow_ProfileNavBarButton = {"container": statusDesktop_mainWindow, "objectName": "statusProfileNavBarTabButton", "type": "StatusNavBarTabButton", "visible": True}
|
||||||
|
settings_navbar_settings_icon_StatusIcon = {"container": mainWindow_navBarListView_ListView, "objectName": "settings-icon", "type": "StatusIcon", "visible": True}
|
||||||
|
|
||||||
|
# User Status Profile Menu
|
||||||
|
userContextMenu_ViewMyProfile_Action = {"container": statusDesktop_mainWindow_overlay, "objectName": "userStatusViewMyProfileAction", "type": "StatusMenuItemDelegate", "visible": True}
|
||||||
|
|
||||||
# popups
|
# popups
|
||||||
close_popup_StatusFlatRoundButton = {"container": statusDesktop_mainWindow_overlay, "id": "closeButton", "type": "StatusFlatRoundButton", "unnamed": 1, "visible": True}
|
close_popup_StatusFlatRoundButton = {"container": statusDesktop_mainWindow_overlay, "id": "closeButton", "type": "StatusFlatRoundButton", "unnamed": 1, "visible": True}
|
||||||
|
@ -18,4 +22,3 @@ mainWindow_public_chat_icon_StatusIcon = {"container": statusDesktop_mainWindow,
|
||||||
chatList_Repeater = {"container": statusDesktop_mainWindow, "objectName": "chatListItems", "type": "Repeater"}
|
chatList_Repeater = {"container": statusDesktop_mainWindow, "objectName": "chatListItems", "type": "Repeater"}
|
||||||
mainWindow_startChat = {"checkable": True, "container": statusDesktop_mainWindow, "objectName": "startChatButton", "type": "StatusIconTabButton"}
|
mainWindow_startChat = {"checkable": True, "container": statusDesktop_mainWindow, "objectName": "startChatButton", "type": "StatusIconTabButton"}
|
||||||
join_public_chat_StatusMenuItemDelegate = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "text": "Join public chat", "type": "StatusMenuItemDelegate", "unnamed": 1, "visible": True}
|
join_public_chat_StatusMenuItemDelegate = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "enabled": True, "text": "Join public chat", "type": "StatusMenuItemDelegate", "unnamed": 1, "visible": True}
|
||||||
mainWindow_statusIcon_StatusIcon_2 = {"container": statusDesktop_mainWindow, "id": "statusIcon", "source": "qrc:/StatusQ/src/assets/img/icons/public-chat.svg", "type": "StatusIcon", "unnamed": 1, "visible": True}
|
|
|
@ -7,3 +7,4 @@ loginView_submitBtn = {"container": statusDesktop_mainWindow, "type": "StatusRou
|
||||||
loginView_main = {"container": statusDesktop_mainWindow, "type": "LoginView", "visible": True}
|
loginView_main = {"container": statusDesktop_mainWindow, "type": "LoginView", "visible": True}
|
||||||
loginView_errMsgLabel = {"container": statusDesktop_mainWindow, "objectName": "loginPassworkInputValidationErrorText", "type": "StatusBaseText", "visible": True}
|
loginView_errMsgLabel = {"container": statusDesktop_mainWindow, "objectName": "loginPassworkInputValidationErrorText", "type": "StatusBaseText", "visible": True}
|
||||||
accountsView_accountListPanel = {"container": statusDesktop_mainWindow, "type": "ListView", "visible": True} # This probably is missing an objectName
|
accountsView_accountListPanel = {"container": statusDesktop_mainWindow, "type": "ListView", "visible": True} # This probably is missing an objectName
|
||||||
|
loginView_userImage = {"container": statusDesktop_mainWindow, "objectName": "loginViewUserImage", "type": "UserImage", "visible": True}
|
|
@ -17,6 +17,9 @@ onboarding_DiplayName_Input = {"container": statusDesktop_mainWindow, "objectNam
|
||||||
onboarding_DetailsView_NextButton = {"container": statusDesktop_mainWindow, "objectName": "onboardingDetailsViewNextButton", "type": "StatusButton"}
|
onboarding_DetailsView_NextButton = {"container": statusDesktop_mainWindow, "objectName": "onboardingDetailsViewNextButton", "type": "StatusButton"}
|
||||||
mainWindow_I_prefer_to_use_my_password_StatusBaseText = {"container": statusDesktop_mainWindow, "objectName": "touchIdIPreferToUseMyPasswordText", "type": "StatusBaseText"}
|
mainWindow_I_prefer_to_use_my_password_StatusBaseText = {"container": statusDesktop_mainWindow, "objectName": "touchIdIPreferToUseMyPasswordText", "type": "StatusBaseText"}
|
||||||
mainWindow_Ok_got_it_StatusBaseText = {"container": statusDesktop_mainWindow, "type": "StatusButton", "objectName": "allowNotificationsOnboardingOkButton", "visible": True}
|
mainWindow_Ok_got_it_StatusBaseText = {"container": statusDesktop_mainWindow, "type": "StatusButton", "objectName": "allowNotificationsOnboardingOkButton", "visible": True}
|
||||||
|
mainWindow_WelcomeScreen_User_Profile_Image = {"container": statusDesktop_mainWindow, "type": "StatusSmartIdenticon", "objectName": "welcomeScreenUserProfileImage"}
|
||||||
|
mainWindow_WelcomeScreen_Image_Crop_Workflow_Item= {"container": statusDesktop_mainWindow, "type": "Item", "objectName": "imageCropWorkflow"}
|
||||||
|
mainWindow_WelcomeScreen_Image_Cropper_Accept_Button= {"container": statusDesktop_mainWindow, "type": "StatusButton", "objectName": "imageCropperAcceptButton"}
|
||||||
|
|
||||||
# Seed phrase form:
|
# Seed phrase form:
|
||||||
import_a_seed_phrase_StatusBaseText = {"container": statusDesktop_mainWindow, "text": "Import a seed phrase", "type": "StatusBaseText", "unnamed": 1, "visible": True}
|
import_a_seed_phrase_StatusBaseText = {"container": statusDesktop_mainWindow, "text": "Import a seed phrase", "type": "StatusBaseText", "unnamed": 1, "visible": True}
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
from objectmaphelper import *
|
from objectmaphelper import *
|
||||||
|
|
||||||
from scripts.onboarding_names import *
|
from scripts.onboarding_names import *
|
||||||
|
from scripts.login_names import *
|
||||||
|
|
|
@ -44,6 +44,33 @@ def step(context, seed_phrase):
|
||||||
def step(context):
|
def step(context):
|
||||||
_welcomeScreen.seed_phrase_visible()
|
_welcomeScreen.seed_phrase_visible()
|
||||||
|
|
||||||
|
@When("the user logs in with password |any|")
|
||||||
|
def step(context, password: str):
|
||||||
|
_welcomeScreen.enter_password(password)
|
||||||
|
|
||||||
@Then("the user is online")
|
@Then("the user is online")
|
||||||
def step(context):
|
def step(context):
|
||||||
_mainScreen.user_is_online()
|
_mainScreen.user_is_online()
|
||||||
|
|
||||||
|
@When("the user signs up with profileImage |any|, username |any| and password |any|")
|
||||||
|
def step(context, profileImageUrl, username, password):
|
||||||
|
_welcomeScreen.input_username_profileImage_password_and_finalize_sign_up("file:///"+context.userData["fixtures_root"]+"images/"+profileImageUrl, username, password)
|
||||||
|
|
||||||
|
@Then("my profile modal has the updated profile image")
|
||||||
|
def step(context):
|
||||||
|
_welcomeScreen.profile_modal_image_is_updated()
|
||||||
|
|
||||||
|
@Then("the profile setting has the updated profile image")
|
||||||
|
def step(context):
|
||||||
|
_welcomeScreen.profile_settings_image_is_updated()
|
||||||
|
|
||||||
|
@When("a screenshot of the profileImage is taken")
|
||||||
|
def step(context):
|
||||||
|
_welcomeScreen.grab_screenshot()
|
||||||
|
|
||||||
|
@Then("the profile navigation bar has the updated profile image")
|
||||||
|
def step(context):
|
||||||
|
_welcomeScreen.profile_image_is_updated()
|
||||||
|
delete_created_searchImage(context.userData["search_images"] +"profiletestimage.png")
|
||||||
|
delete_created_searchImage(context.userData["search_images"]+"loginUserName.png")
|
||||||
|
|
||||||
|
|
|
@ -134,4 +134,15 @@ Feature: Status Desktop Sign Up
|
||||||
Scenario: After Signing up the Profile state should be online
|
Scenario: After Signing up the Profile state should be online
|
||||||
Given A first time user lands on the status desktop and generates new key
|
Given A first time user lands on the status desktop and generates new key
|
||||||
When user signs up with username tester123 and password TesTEr16843/!@00
|
When user signs up with username tester123 and password TesTEr16843/!@00
|
||||||
Then the user is online
|
Then the user is online
|
||||||
|
|
||||||
|
Scenario: User signs up with a profile image
|
||||||
|
|
||||||
|
Given A first time user lands on the status desktop and generates new key
|
||||||
|
When the user signs up with profileImage doggo.jpeg, username tester123 and password TesTEr16843/!@00
|
||||||
|
Then my profile modal has the updated profile image
|
||||||
|
And the profile setting has the updated profile image
|
||||||
|
When the user restarts the app
|
||||||
|
And a screenshot of the profileImage is taken
|
||||||
|
And the user logs in with password TesTEr16843/!@00
|
||||||
|
Then the profile navigation bar has the updated profile image
|
||||||
|
|
|
@ -8,7 +8,7 @@ from scripts.onboarding_names import *
|
||||||
from sections.chat_names import *
|
from sections.chat_names import *
|
||||||
from sections.community_names import *
|
from sections.community_names import *
|
||||||
from sections.community_portal_names import *
|
from sections.community_portal_names import *
|
||||||
from sections.login_names import *
|
from scripts.login_names import *
|
||||||
from sections.search_names import *
|
from sections.search_names import *
|
||||||
from sections.settings_names import *
|
from sections.settings_names import *
|
||||||
from sections.wallet_names import *
|
from sections.wallet_names import *
|
||||||
|
|
|
@ -28,7 +28,6 @@ class SettingsSubsection(Enum):
|
||||||
|
|
||||||
# Main:
|
# Main:
|
||||||
navBarListView_Settings_navbar_StatusNavBarTabButton = {"checkable": True, "container": mainWindow_navBarListView_ListView, "objectName": "Settings-navbar", "type": "StatusNavBarTabButton", "visible": True}
|
navBarListView_Settings_navbar_StatusNavBarTabButton = {"checkable": True, "container": mainWindow_navBarListView_ListView, "objectName": "Settings-navbar", "type": "StatusNavBarTabButton", "visible": True}
|
||||||
settings_navbar_settings_icon_StatusIcon = {"container": navBarListView_Settings_navbar_StatusNavBarTabButton, "objectName": "settings-icon", "type": "StatusIcon", "visible": True}
|
|
||||||
settingsSave_StatusButton = {"container": statusDesktop_mainWindow, "objectName": "settingsDirtyToastMessageSaveButton", "type": "StatusButton", "visible": True}
|
settingsSave_StatusButton = {"container": statusDesktop_mainWindow, "objectName": "settingsDirtyToastMessageSaveButton", "type": "StatusButton", "visible": True}
|
||||||
settings_Sidebar_ENS_Item = {"container": mainWindow_ScrollView, "objectName": "ENS usernames-MainMenu", "type": "StatusNavigationListItem"}
|
settings_Sidebar_ENS_Item = {"container": mainWindow_ScrollView, "objectName": "ENS usernames-MainMenu", "type": "StatusNavigationListItem"}
|
||||||
|
|
||||||
|
@ -101,6 +100,9 @@ languageView_language_StatusPickerButton = {"container": languageView_language_S
|
||||||
languageView_language_ListView = {"container": languageView_language_StatusListPicker, "type": "ListView", "unnamed": 1}
|
languageView_language_ListView = {"container": languageView_language_StatusListPicker, "type": "ListView", "unnamed": 1}
|
||||||
languageView_language_StatusInput = {"container": languageView_language_ListView, "type": "StatusInput", "unnamed": 1}
|
languageView_language_StatusInput = {"container": languageView_language_ListView, "type": "StatusInput", "unnamed": 1}
|
||||||
|
|
||||||
|
# My Profile Modal
|
||||||
|
myProfileModal_UserImage = {"container": statusDesktop_mainWindow_overlay, "objectName": "myProfileModalUserImage", "type": "UserImage", "visible": True}
|
||||||
|
|
||||||
# Backup seed phrase:
|
# Backup seed phrase:
|
||||||
backup_seed_phrase_popup_Acknowledgements_havePen_checkbox = {"container": statusDesktop_mainWindow_overlay, "objectName": "Acknowledgements_havePen", "type": "StatusCheckBox", "checkable": True, "visible": True}
|
backup_seed_phrase_popup_Acknowledgements_havePen_checkbox = {"container": statusDesktop_mainWindow_overlay, "objectName": "Acknowledgements_havePen", "type": "StatusCheckBox", "checkable": True, "visible": True}
|
||||||
backup_seed_phrase_popup_Acknowledgements_writeDown_checkbox = {"container": statusDesktop_mainWindow_overlay, "objectName": "Acknowledgements_writeDown", "type": "StatusCheckBox", "checkable": True, "visible": True}
|
backup_seed_phrase_popup_Acknowledgements_writeDown_checkbox = {"container": statusDesktop_mainWindow_overlay, "objectName": "Acknowledgements_writeDown", "type": "StatusCheckBox", "checkable": True, "visible": True}
|
||||||
|
|
|
@ -88,6 +88,7 @@ Item {
|
||||||
StatusSmartIdenticon {
|
StatusSmartIdenticon {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
id: userImage
|
id: userImage
|
||||||
|
objectName: "welcomeScreenUserProfileImage"
|
||||||
image {
|
image {
|
||||||
width: 86
|
width: 86
|
||||||
height: 86
|
height: 86
|
||||||
|
|
|
@ -188,6 +188,7 @@ Item {
|
||||||
|
|
||||||
UserImage {
|
UserImage {
|
||||||
id: userImage
|
id: userImage
|
||||||
|
objectName: "loginViewUserImage"
|
||||||
image: root.startupStore.selectedLoginAccount.thumbnailImage
|
image: root.startupStore.selectedLoginAccount.thumbnailImage
|
||||||
name: root.startupStore.selectedLoginAccount.username
|
name: root.startupStore.selectedLoginAccount.username
|
||||||
colorId: root.startupStore.selectedLoginAccount.colorId
|
colorId: root.startupStore.selectedLoginAccount.colorId
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
import QtQuick 2.13
|
|
||||||
import QtQuick.Dialogs 1.3
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
|
|
||||||
import shared 1.0
|
|
||||||
import shared.panels 1.0
|
|
||||||
import shared.popups 1.0
|
|
||||||
|
|
||||||
// TODO: replace with StatusModal
|
|
||||||
ModalPopup {
|
|
||||||
id: popup
|
|
||||||
title: qsTr("Profile picture")
|
|
||||||
|
|
||||||
property var profileStore
|
|
||||||
|
|
||||||
property string selectedImage // selectedImage is for us to be able to analyze it before setting it as current
|
|
||||||
property string uploadError
|
|
||||||
property url largeImage: popup.profileStore.profileLargeImage
|
|
||||||
property bool hasIdentityImage: !!popup.profileStore.profileLargeImage
|
|
||||||
|
|
||||||
onClosed: {
|
|
||||||
destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelectedImageChanged: {
|
|
||||||
if (!selectedImage) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cropImageModal.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
RoundedImage {
|
|
||||||
id: profilePic
|
|
||||||
source: popup.largeImage
|
|
||||||
width: 160
|
|
||||||
height: 160
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
border.width: 1
|
|
||||||
border.color: Style.current.border
|
|
||||||
onClicked: imageDialog.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
visible: !!uploadError
|
|
||||||
text: uploadError
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: profilePic.bottom
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.pixelSize: 13
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
anchors.topMargin: 13
|
|
||||||
font.weight: Font.Thin
|
|
||||||
color: Style.current.danger
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageCropperModal {
|
|
||||||
id: cropImageModal
|
|
||||||
|
|
||||||
selectedImage: popup.selectedImage
|
|
||||||
ratio: "1:1"
|
|
||||||
onCropFinished: {
|
|
||||||
popup.uploadError = popup.profileStore.uploadImage(selectedImage, aX, aY, bX, bY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer: Item {
|
|
||||||
width: parent.width
|
|
||||||
height: uploadBtn.height
|
|
||||||
|
|
||||||
StatusFlatButton {
|
|
||||||
visible: popup.hasIdentityImage
|
|
||||||
type: StatusBaseButton.Type.Danger
|
|
||||||
text: qsTr("Remove")
|
|
||||||
anchors.right: uploadBtn.left
|
|
||||||
anchors.rightMargin: Style.current.padding
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
onClicked: {
|
|
||||||
popup.uploadError = popup.profileStore.removeImage()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
id: uploadBtn
|
|
||||||
text: qsTr("Upload")
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
onClicked: {
|
|
||||||
imageDialog.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
FileDialog {
|
|
||||||
id: imageDialog
|
|
||||||
title: qsTr("Please choose an image")
|
|
||||||
folder: shortcuts.pictures
|
|
||||||
nameFilters: [
|
|
||||||
qsTr("Image files (*.jpg *.jpeg *.png)")
|
|
||||||
]
|
|
||||||
onAccepted: {
|
|
||||||
selectedImage = imageDialog.fileUrls[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
ChangeProfilePicModal 1.0 ChangeProfilePicModal.qml
|
|
||||||
BackupSeedModal 1.0 BackupSeedModal.qml
|
BackupSeedModal 1.0 BackupSeedModal.qml
|
||||||
|
|
|
@ -1,213 +0,0 @@
|
||||||
import QtQuick 2.13
|
|
||||||
|
|
||||||
import "../panels"
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
property Image image
|
|
||||||
property alias selectorRectangle: selectorRectangle
|
|
||||||
property string ratio: ""
|
|
||||||
property var splitRatio: !!ratio ? ratio.split(":") : null
|
|
||||||
property int widthRatio: !!ratio ? parseInt(splitRatio[0]) : -1
|
|
||||||
property int heightRatio: !!ratio ? parseInt(splitRatio[1]) : -1
|
|
||||||
property bool settingCorners: false
|
|
||||||
property int draggedCorner: 0
|
|
||||||
property bool ready: false
|
|
||||||
|
|
||||||
readonly property int topLeft: 0
|
|
||||||
readonly property int topRight: 1
|
|
||||||
readonly property int bottomLeft: 2
|
|
||||||
readonly property int bottomRight: 3
|
|
||||||
|
|
||||||
width: image.width
|
|
||||||
height: image.height
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: selectorRectangle
|
|
||||||
visible: false
|
|
||||||
x: 0
|
|
||||||
y: 0
|
|
||||||
border.width: 2
|
|
||||||
border.color: Style.current.orange
|
|
||||||
color: Style.current.transparent
|
|
||||||
|
|
||||||
function fitRatio(makeBigger) {
|
|
||||||
if (!!ratio) {
|
|
||||||
if ((makeBigger && selectorRectangle.width < selectorRectangle.height) || (!makeBigger && selectorRectangle.width > selectorRectangle.height)) {
|
|
||||||
selectorRectangle.width = (selectorRectangle.height/heightRatio) * widthRatio
|
|
||||||
} else {
|
|
||||||
selectorRectangle.height = (selectorRectangle.width/widthRatio) * heightRatio
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initialSetup() {
|
|
||||||
selectorRectangle.width = image.width
|
|
||||||
selectorRectangle.height = image.height
|
|
||||||
|
|
||||||
fitRatio()
|
|
||||||
topLeftCorner.x = 0
|
|
||||||
topLeftCorner.y = 0
|
|
||||||
topRightCorner.x = selectorRectangle.width - topRightCorner.width
|
|
||||||
topRightCorner.y = 0
|
|
||||||
bottomLeftCorner.x = 0
|
|
||||||
bottomLeftCorner.y = selectorRectangle.height - topRightCorner.height
|
|
||||||
bottomRightCorner.x = selectorRectangle.width - topRightCorner.width
|
|
||||||
bottomRightCorner.y = selectorRectangle.height - topRightCorner.height
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function adjustRectangleSize() {
|
|
||||||
if (!selectorRectangle.visible) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
selectorRectangle.width = bottomRightCorner.x + bottomRightCorner.width - topLeftCorner.x
|
|
||||||
selectorRectangle.height = bottomRightCorner.y + bottomRightCorner.height - topLeftCorner.y
|
|
||||||
selectorRectangle.x = topLeftCorner.x
|
|
||||||
selectorRectangle.y = topLeftCorner.y
|
|
||||||
|
|
||||||
if (!!ratio) {
|
|
||||||
// FIXME with a ratio that is not 1:1, the rectangle can go out of bounds
|
|
||||||
fitRatio()
|
|
||||||
|
|
||||||
switch(draggedCorner) {
|
|
||||||
case topLeft:
|
|
||||||
selectorRectangle.x = topLeftCorner.x
|
|
||||||
selectorRectangle.y = topLeftCorner.y
|
|
||||||
break
|
|
||||||
case topRight:
|
|
||||||
selectorRectangle.x = topRightCorner.x - selectorRectangle.width + topRightCorner.width
|
|
||||||
selectorRectangle.y = topRightCorner.y
|
|
||||||
break
|
|
||||||
case bottomLeft:
|
|
||||||
selectorRectangle.x = bottomLeftCorner.x
|
|
||||||
selectorRectangle.y = bottomLeftCorner.y - selectorRectangle.height + bottomLeftCorner.height
|
|
||||||
break
|
|
||||||
case bottomRight:
|
|
||||||
selectorRectangle.x = bottomRightCorner.x - selectorRectangle.width + bottomRightCorner.width
|
|
||||||
selectorRectangle.y = bottomRightCorner.y - selectorRectangle.height + bottomRightCorner.height
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: image
|
|
||||||
onStatusChanged: {
|
|
||||||
if (image.status === Image.Ready) {
|
|
||||||
selectorRectangle.initialSetup()
|
|
||||||
selectorRectangle.visible = true
|
|
||||||
root.ready = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function putCorners() {
|
|
||||||
settingCorners = true
|
|
||||||
|
|
||||||
topLeftCorner.x = selectorRectangle.x
|
|
||||||
topLeftCorner.y = selectorRectangle.y
|
|
||||||
topRightCorner.x = selectorRectangle.x + selectorRectangle.width - topRightCorner.width
|
|
||||||
topRightCorner.y = selectorRectangle.y
|
|
||||||
bottomLeftCorner.x = selectorRectangle.x
|
|
||||||
bottomLeftCorner.y = selectorRectangle.y + selectorRectangle.height - topRightCorner.height
|
|
||||||
bottomRightCorner.x = selectorRectangle.x + selectorRectangle.width - topRightCorner.width
|
|
||||||
bottomRightCorner.y = selectorRectangle.y + selectorRectangle.height - topRightCorner.height
|
|
||||||
|
|
||||||
settingCorners = false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Size calculations are only done on top-left and bottom-right, because the other two corners follow them
|
|
||||||
CropCornerRectangle {
|
|
||||||
id: topLeftCorner
|
|
||||||
onXChanged: {
|
|
||||||
if (settingCorners) return
|
|
||||||
if (x < 0) x = 0
|
|
||||||
if (x > topRightCorner.x - width) x = topRightCorner.x - width
|
|
||||||
|
|
||||||
bottomLeftCorner.x = x
|
|
||||||
selectorRectangle.adjustRectangleSize()
|
|
||||||
}
|
|
||||||
onYChanged: {
|
|
||||||
if (settingCorners) return
|
|
||||||
if (y < 0) y = 0
|
|
||||||
if (y > bottomRightCorner.y - height) y = bottomRightCorner.y - height
|
|
||||||
|
|
||||||
topRightCorner.y = y
|
|
||||||
selectorRectangle.adjustRectangleSize()
|
|
||||||
}
|
|
||||||
onPressed: {
|
|
||||||
draggedCorner = topLeft
|
|
||||||
}
|
|
||||||
|
|
||||||
onReleased: {
|
|
||||||
putCorners()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CropCornerRectangle {
|
|
||||||
id: topRightCorner
|
|
||||||
onXChanged: {
|
|
||||||
if (settingCorners) return
|
|
||||||
bottomRightCorner.x = x
|
|
||||||
}
|
|
||||||
onYChanged: {
|
|
||||||
if (settingCorners) return
|
|
||||||
topLeftCorner.y = y
|
|
||||||
}
|
|
||||||
onPressed: {
|
|
||||||
draggedCorner = topRight
|
|
||||||
}
|
|
||||||
onReleased: {
|
|
||||||
putCorners()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CropCornerRectangle {
|
|
||||||
id: bottomLeftCorner
|
|
||||||
onXChanged: {
|
|
||||||
if (settingCorners) return
|
|
||||||
topLeftCorner.x = x
|
|
||||||
}
|
|
||||||
onYChanged: {
|
|
||||||
if (settingCorners) return
|
|
||||||
bottomRightCorner.y = y
|
|
||||||
}
|
|
||||||
onPressed: {
|
|
||||||
draggedCorner = bottomLeft
|
|
||||||
}
|
|
||||||
onReleased: {
|
|
||||||
putCorners()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CropCornerRectangle {
|
|
||||||
id: bottomRightCorner
|
|
||||||
onXChanged: {
|
|
||||||
if (settingCorners) return
|
|
||||||
if (x < topLeftCorner.x + topLeftCorner.width) x = topLeftCorner.x + topLeftCorner.width
|
|
||||||
if (x > image.width - width) x = image.width - width
|
|
||||||
topRightCorner.x = x
|
|
||||||
|
|
||||||
selectorRectangle.adjustRectangleSize()
|
|
||||||
}
|
|
||||||
onYChanged: {
|
|
||||||
if (settingCorners) return
|
|
||||||
if (y < topRightCorner.y + topRightCorner.height) y = topRightCorner.y + topRightCorner.height
|
|
||||||
if (y > image.height - height) y = image.height - height
|
|
||||||
bottomLeftCorner.y = y
|
|
||||||
|
|
||||||
selectorRectangle.adjustRectangleSize()
|
|
||||||
}
|
|
||||||
onPressed: {
|
|
||||||
draggedCorner = bottomRight
|
|
||||||
}
|
|
||||||
onReleased: {
|
|
||||||
putCorners()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -72,6 +72,7 @@ Item {
|
||||||
|
|
||||||
UserImage {
|
UserImage {
|
||||||
id: userImage
|
id: userImage
|
||||||
|
objectName: "myProfileModalUserImage"
|
||||||
name: root.displayName
|
name: root.displayName
|
||||||
pubkey: root.pubkey
|
pubkey: root.pubkey
|
||||||
image: root.icon
|
image: root.icon
|
||||||
|
|
|
@ -8,7 +8,6 @@ FormGroup 1.0 FormGroup.qml
|
||||||
GasSelector 1.0 GasSelector.qml
|
GasSelector 1.0 GasSelector.qml
|
||||||
GasSelectorButton 1.0 GasSelectorButton.qml
|
GasSelectorButton 1.0 GasSelectorButton.qml
|
||||||
GasValidator 1.0 GasValidator.qml
|
GasValidator 1.0 GasValidator.qml
|
||||||
ImageCropper 1.0 ImageCropper.qml
|
|
||||||
Input 1.0 Input.qml
|
Input 1.0 Input.qml
|
||||||
RadioButtonSelector 1.0 RadioButtonSelector.qml
|
RadioButtonSelector 1.0 RadioButtonSelector.qml
|
||||||
RecipientSelector 1.0 RecipientSelector.qml
|
RecipientSelector 1.0 RecipientSelector.qml
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
import QtQuick 2.13
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
signal released()
|
|
||||||
signal pressed()
|
|
||||||
|
|
||||||
id: root
|
|
||||||
width: 25
|
|
||||||
height: 25
|
|
||||||
border.width: 2
|
|
||||||
border.color: Style.current.orange
|
|
||||||
color: Utils.setColorAlpha(Style.current.orange, 0.5)
|
|
||||||
|
|
||||||
Drag.active: dragArea.drag.active
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: dragArea
|
|
||||||
property int oldX
|
|
||||||
property int oldY
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
drag.target: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onReleased: root.released()
|
|
||||||
onPressed: root.pressed()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,6 @@
|
||||||
Address 1.0 Address.qml
|
Address 1.0 Address.qml
|
||||||
AddressRequiredValidator 1.0 AddressRequiredValidator.qml
|
AddressRequiredValidator 1.0 AddressRequiredValidator.qml
|
||||||
BalanceValidator 1.0 BalanceValidator.qml
|
BalanceValidator 1.0 BalanceValidator.qml
|
||||||
CropCornerRectangle 1.0 CropCornerRectangle.qml
|
|
||||||
GlossaryEntry 1.0 GlossaryEntry.qml
|
GlossaryEntry 1.0 GlossaryEntry.qml
|
||||||
GlossaryLetter 1.0 GlossaryLetter.qml
|
GlossaryLetter 1.0 GlossaryLetter.qml
|
||||||
ImageLoader 1.0 ImageLoader.qml
|
ImageLoader 1.0 ImageLoader.qml
|
||||||
|
|
|
@ -12,6 +12,7 @@ import utils 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
objectName: "imageCropWorkflow"
|
||||||
|
|
||||||
property alias aspectRatio: imageCropper.aspectRatio
|
property alias aspectRatio: imageCropper.aspectRatio
|
||||||
property alias windowStyle: imageCropper.windowStyle
|
property alias windowStyle: imageCropper.windowStyle
|
||||||
|
@ -26,6 +27,11 @@ Item {
|
||||||
fileDialog.open()
|
fileDialog.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cropImage(imageUrl) {
|
||||||
|
imageCropper.source = imageUrl
|
||||||
|
imageCropperModal.open()
|
||||||
|
}
|
||||||
|
|
||||||
FileDialog {
|
FileDialog {
|
||||||
id: fileDialog
|
id: fileDialog
|
||||||
|
|
||||||
|
@ -34,8 +40,7 @@ Item {
|
||||||
nameFilters: [qsTr("Supported image formats (%1)").arg("*.jpg *.jpeg *.jfif *.webp *.png *.heif")]
|
nameFilters: [qsTr("Supported image formats (%1)").arg("*.jpg *.jpeg *.jfif *.webp *.png *.heif")]
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
if (fileDialog.fileUrls.length > 0) {
|
if (fileDialog.fileUrls.length > 0) {
|
||||||
imageCropper.source = fileDialog.fileUrls[0]
|
cropImage(fileDialog.fileUrls[0])
|
||||||
imageCropperModal.open()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // FileDialog
|
} // FileDialog
|
||||||
|
@ -51,15 +56,16 @@ Item {
|
||||||
|
|
||||||
StatusImageCropPanel {
|
StatusImageCropPanel {
|
||||||
id: imageCropper
|
id: imageCropper
|
||||||
|
objectName: "profileImageCropper"
|
||||||
|
|
||||||
implicitHeight: root.roundedImage ? 350 : 370
|
implicitHeight: root.roundedImage ? 350 : 370
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
fill: parent
|
||||||
leftMargin: Style.current.bigPadding + Style.current.halfPadding / 2
|
leftMargin: Style.current.bigPadding + Style.current.halfPadding / 2
|
||||||
rightMargin: Style.current.bigPadding + Style.current.halfPadding / 2
|
rightMargin: Style.current.bigPadding + Style.current.halfPadding / 2
|
||||||
topMargin: Style.current.bigPadding
|
topMargin: Style.current.bigPadding
|
||||||
bottomMargin: Style.current.bigPadding
|
bottomMargin: Style.current.bigPadding
|
||||||
}
|
}
|
||||||
|
|
||||||
margins: root.roundedImage ? 10 : 20
|
margins: root.roundedImage ? 10 : 20
|
||||||
|
@ -69,6 +75,7 @@ Item {
|
||||||
|
|
||||||
rightButtons: [
|
rightButtons: [
|
||||||
StatusButton {
|
StatusButton {
|
||||||
|
objectName: "imageCropperAcceptButton"
|
||||||
text: root.acceptButtonText
|
text: root.acceptButtonText
|
||||||
|
|
||||||
enabled: imageCropper.sourceSize.width > 0 && imageCropper.sourceSize.height > 0
|
enabled: imageCropper.sourceSize.width > 0 && imageCropper.sourceSize.height > 0
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
import QtQuick 2.13
|
|
||||||
import QtQuick.Controls 2.13
|
|
||||||
import QtQuick.Layouts 1.13
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
|
|
||||||
import "../controls"
|
|
||||||
import "."
|
|
||||||
|
|
||||||
// TODO: replace with StatusModal
|
|
||||||
ModalPopup {
|
|
||||||
property string selectedImage
|
|
||||||
property string ratio: "1:1"
|
|
||||||
property int aX: 0
|
|
||||||
property int aY: 0
|
|
||||||
property int bX: 0
|
|
||||||
property int bY: 0
|
|
||||||
signal cropFinished(aX: int, aY: int, bX: int, bY: int)
|
|
||||||
|
|
||||||
id: cropImageModal
|
|
||||||
width: image.width + 50
|
|
||||||
height: image.height + 170
|
|
||||||
title: qsTr("Crop your image (optional)")
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: image
|
|
||||||
width: 400
|
|
||||||
source: cropImageModal.selectedImage
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageCropper {
|
|
||||||
id: imageCropper
|
|
||||||
x: image.x
|
|
||||||
y: image.y
|
|
||||||
image: image
|
|
||||||
ratio: cropImageModal.ratio
|
|
||||||
onReadyChanged: {
|
|
||||||
if (ready) {
|
|
||||||
// cropImageModal.calculateCrop()
|
|
||||||
cropImageModal.aX = Qt.binding(function() {
|
|
||||||
const aXPercent = imageCropper.selectorRectangle.x / image.width
|
|
||||||
return Math.round(aXPercent * image.sourceSize.width)
|
|
||||||
})
|
|
||||||
cropImageModal.aY = Qt.binding(function() {
|
|
||||||
const aYPercent = imageCropper.selectorRectangle.y / image.height
|
|
||||||
return Math.round(aYPercent * image.sourceSize.height)
|
|
||||||
})
|
|
||||||
cropImageModal.bX = Qt.binding(function() {
|
|
||||||
const bXPercent = (imageCropper.selectorRectangle.x + imageCropper.selectorRectangle.width) / image.width
|
|
||||||
return Math.round(bXPercent * image.sourceSize.width)
|
|
||||||
})
|
|
||||||
cropImageModal.bY = Qt.binding(function() {
|
|
||||||
const bYPercent = (imageCropper.selectorRectangle.y + imageCropper.selectorRectangle.height) / image.height
|
|
||||||
return Math.round(bYPercent * image.sourceSize.height)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
footer: StatusButton {
|
|
||||||
id: doneBtn
|
|
||||||
text: qsTr("Finish")
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
onClicked: {
|
|
||||||
const aXPercent = imageCropper.selectorRectangle.x / image.width
|
|
||||||
const aYPercent = imageCropper.selectorRectangle.y / image.height
|
|
||||||
const bXPercent = (imageCropper.selectorRectangle.x + imageCropper.selectorRectangle.width) / image.width
|
|
||||||
const bYPercent = (imageCropper.selectorRectangle.y + imageCropper.selectorRectangle.height) / image.height
|
|
||||||
|
|
||||||
|
|
||||||
const aX = Math.round(aXPercent * image.sourceSize.width)
|
|
||||||
const aY = Math.round(aYPercent * image.sourceSize.height)
|
|
||||||
|
|
||||||
const bX = Math.round(bXPercent * image.sourceSize.width)
|
|
||||||
const bY = Math.round(bYPercent * image.sourceSize.height)
|
|
||||||
|
|
||||||
cropImageModal.cropFinished(aX, aY, bX, bY)
|
|
||||||
cropImageModal.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,6 +29,7 @@ StatusPopupMenu {
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
|
objectName: "userStatusViewMyProfileAction"
|
||||||
text: qsTr("View My Profile")
|
text: qsTr("View My Profile")
|
||||||
icon.name: "profile"
|
icon.name: "profile"
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
|
|
|
@ -6,7 +6,6 @@ CommunityIntroDialog 1.0 CommunityIntroDialog.qml
|
||||||
ContactVerificationRequestPopup 1.0 ContactVerificationRequestPopup.qml
|
ContactVerificationRequestPopup 1.0 ContactVerificationRequestPopup.qml
|
||||||
DownloadModal 1.0 DownloadModal.qml
|
DownloadModal 1.0 DownloadModal.qml
|
||||||
DownloadPage 1.0 DownloadPage.qml
|
DownloadPage 1.0 DownloadPage.qml
|
||||||
ImageCropperModal 1.0 ImageCropperModal.qml
|
|
||||||
InviteFriendsPopup 1.0 InviteFriendsPopup.qml
|
InviteFriendsPopup 1.0 InviteFriendsPopup.qml
|
||||||
NicknamePopup 1.0 NicknamePopup.qml
|
NicknamePopup 1.0 NicknamePopup.qml
|
||||||
ModalPopup 1.0 ModalPopup.qml
|
ModalPopup 1.0 ModalPopup.qml
|
||||||
|
|
Loading…
Reference in New Issue