✨ Implemented login dialog for PKCE login method. Fixes #22.

This commit is contained in:
Robert Honz
2024-02-01 07:38:01 +01:00
parent a994aa629e
commit c1bf278fd7
9 changed files with 464 additions and 12 deletions
+110
View File
@@ -0,0 +1,110 @@
################################################################################
## Form generated from reading UI file 'dialog_login.ui'
##
## Created by: Qt User Interface Compiler version 6.6.1
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import QCoreApplication, QMetaObject, QRect, QSize, Qt
from PySide6.QtGui import QFont
from PySide6.QtWidgets import QDialogButtonBox, QLabel, QSizePolicy, QTextEdit, QVBoxLayout, QWidget
class Ui_DialogLogin:
def setupUi(self, DialogLogin):
if not DialogLogin.objectName():
DialogLogin.setObjectName("DialogLogin")
DialogLogin.resize(451, 400)
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(DialogLogin.sizePolicy().hasHeightForWidth())
DialogLogin.setSizePolicy(sizePolicy)
self.bb_dialog = QDialogButtonBox(DialogLogin)
self.bb_dialog.setObjectName("bb_dialog")
self.bb_dialog.setGeometry(QRect(20, 350, 411, 32))
sizePolicy.setHeightForWidth(self.bb_dialog.sizePolicy().hasHeightForWidth())
self.bb_dialog.setSizePolicy(sizePolicy)
self.bb_dialog.setStyleSheet("")
self.bb_dialog.setOrientation(Qt.Horizontal)
self.bb_dialog.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
self.verticalLayoutWidget = QWidget(DialogLogin)
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayoutWidget.setGeometry(QRect(20, 20, 411, 321))
self.lv_main = QVBoxLayout(self.verticalLayoutWidget)
self.lv_main.setObjectName("lv_main")
self.lv_main.setContentsMargins(0, 0, 0, 0)
self.l_header = QLabel(self.verticalLayoutWidget)
self.l_header.setObjectName("l_header")
sizePolicy.setHeightForWidth(self.l_header.sizePolicy().hasHeightForWidth())
self.l_header.setSizePolicy(sizePolicy)
font = QFont()
font.setPointSize(23)
font.setBold(True)
self.l_header.setFont(font)
self.lv_main.addWidget(self.l_header)
self.l_description = QLabel(self.verticalLayoutWidget)
self.l_description.setObjectName("l_description")
sizePolicy.setHeightForWidth(self.l_description.sizePolicy().hasHeightForWidth())
self.l_description.setSizePolicy(sizePolicy)
font1 = QFont()
font1.setItalic(True)
self.l_description.setFont(font1)
self.l_description.setWordWrap(True)
self.lv_main.addWidget(self.l_description)
self.l_url_login = QLabel(self.verticalLayoutWidget)
self.l_url_login.setObjectName("l_url_login")
sizePolicy.setHeightForWidth(self.l_url_login.sizePolicy().hasHeightForWidth())
self.l_url_login.setSizePolicy(sizePolicy)
self.l_url_login.setMinimumSize(QSize(0, 50))
self.l_url_login.setBaseSize(QSize(0, 0))
self.l_url_login.setStyleSheet("border: 2px solid red; padding: 6px")
self.l_url_login.setWordWrap(True)
self.l_url_login.setOpenExternalLinks(True)
self.lv_main.addWidget(self.l_url_login)
self.te_url_redirect = QTextEdit(self.verticalLayoutWidget)
self.te_url_redirect.setObjectName("te_url_redirect")
self.lv_main.addWidget(self.te_url_redirect)
self.l_hint = QLabel(self.verticalLayoutWidget)
self.l_hint.setObjectName("l_hint")
sizePolicy.setHeightForWidth(self.l_hint.sizePolicy().hasHeightForWidth())
self.l_hint.setSizePolicy(sizePolicy)
self.l_hint.setFont(font1)
self.lv_main.addWidget(self.l_hint)
self.retranslateUi(DialogLogin)
self.bb_dialog.accepted.connect(DialogLogin.accept)
self.bb_dialog.rejected.connect(DialogLogin.reject)
QMetaObject.connectSlotsByName(DialogLogin)
# setupUi
def retranslateUi(self, DialogLogin):
DialogLogin.setWindowTitle(QCoreApplication.translate("DialogLogin", "Dialog", None))
self.l_header.setText(QCoreApplication.translate("DialogLogin", "TIDAL PKCE Login", None))
self.l_description.setText(
QCoreApplication.translate(
"DialogLogin",
'Click the link below and login with your TIDAL credentials. You will be redirected to an "Ooops" page'
' after a successful login. Copy the URL of this "Ooops" page and post it in the box below.',
None,
)
)
self.l_url_login.setText(QCoreApplication.translate("DialogLogin", "PLACEHOLDER URL...", None))
self.te_url_redirect.setPlaceholderText(
QCoreApplication.translate("DialogLogin", "Copy and paste the redirect URL after login here...", None)
)
self.l_hint.setText(QCoreApplication.translate("DialogLogin", "Waiting...", None))
# retranslateUi
+194
View File
@@ -0,0 +1,194 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DialogLogin</class>
<widget class="QDialog" name="DialogLogin">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>451</width>
<height>400</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="bb_dialog">
<property name="geometry">
<rect>
<x>20</x>
<y>350</y>
<width>411</width>
<height>32</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>411</width>
<height>321</height>
</rect>
</property>
<layout class="QVBoxLayout" name="lv_main">
<item>
<widget class="QLabel" name="l_header">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>23</pointsize>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>TIDAL PKCE Login</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="l_description">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Click the link below and login with your TIDAL credentials. You will be redirected to an &quot;Ooops&quot; page after a successful login. Copy the URL of this &quot;Ooops&quot; page and post it in the box below.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="l_url_login">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">border: 2px solid red; padding: 6px</string>
</property>
<property name="text">
<string>PLACEHOLDER URL...</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="te_url_redirect">
<property name="placeholderText">
<string>Copy and paste the redirect URL after login here...</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="l_hint">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Waiting...</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>bb_dialog</sender>
<signal>accepted()</signal>
<receiver>DialogLogin</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>bb_dialog</sender>
<signal>rejected()</signal>
<receiver>DialogLogin</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+33
View File
@@ -0,0 +1,33 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
from .dummy_wiggly import WigglyWidget
# Set PYSIDE_DESIGNER_PLUGINS to point to this directory and load the plugin
TOOLTIP = "A cool wiggly widget (Python)"
DOM_XML = """
<ui language='c++'>
<widget class='WigglyWidget' name='wigglyWidget'>
<property name='geometry'>
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>200</height>
</rect>
</property>
<property name='text'>
<string>Hello, world</string>
</property>
</widget>
</ui>
"""
if __name__ == "__main__":
QPyDesignerCustomWidgetCollection.registerCustomWidget(
WigglyWidget, module="wigglywidget", tool_tip=TOOLTIP, xml=DOM_XML
)
+68
View File
@@ -0,0 +1,68 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from PySide6.QtCore import Property, QBasicTimer
from PySide6.QtGui import QColor, QFontMetrics, QPainter, QPalette
from PySide6.QtWidgets import QWidget
class WigglyWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self._step = 0
self._text = ""
self.setBackgroundRole(QPalette.Midlight)
self.setAutoFillBackground(True)
new_font = self.font()
new_font.setPointSize(new_font.pointSize() + 20)
self.setFont(new_font)
self._timer = QBasicTimer()
def isRunning(self):
return self._timer.isActive()
def setRunning(self, r):
if r == self.isRunning():
return
if r:
self._timer.start(60, self)
else:
self._timer.stop()
def paintEvent(self, event):
if not self._text:
return
sineTable = [0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38]
metrics = QFontMetrics(self.font())
x = (self.width() - metrics.horizontalAdvance(self.text)) / 2
y = (self.height() + metrics.ascent() - metrics.descent()) / 2
color = QColor()
with QPainter(self) as painter:
for i in range(len(self.text)):
index = (self._step + i) % 16
color.setHsv((15 - index) * 16, 255, 191)
painter.setPen(color)
dy = (sineTable[index] * metrics.height()) / 400
c = self._text[i]
painter.drawText(x, y - dy, str(c))
x += metrics.horizontalAdvance(c)
def timerEvent(self, event):
if event.timerId() == self._timer.timerId():
self._step += 1
self.update()
else:
QWidget.timerEvent(event)
def text(self):
return self._text
def setText(self, text):
self._text = text
running = Property(bool, isRunning, setRunning)
text = Property(str, text, setText)