Compare commits
13 Commits
1.1.0-beta
...
1.2.0-beta
Author | SHA1 | Date | |
---|---|---|---|
8bec30561e
|
|||
67d6717f53
|
|||
80f7f921ce
|
|||
72fb3ede13
|
|||
6c93583f32
|
|||
f8ea91a7d4
|
|||
f1ac269c48
|
|||
314e358ddc
|
|||
87c401e3a8
|
|||
d2b0637ccb
|
|||
2173f122f8
|
|||
f906d1dc00
|
|||
c4d4c6c86e
|
@ -5,8 +5,13 @@ require_once __DIR__ .'/bootstrap.php';
|
|||||||
|
|
||||||
if (isset($_GET['code'])) {
|
if (isset($_GET['code'])) {
|
||||||
$success = $api->authenticate($_GET['code']);
|
$success = $api->authenticate($_GET['code']);
|
||||||
|
$from = empty($_GET['from']) ? null : $_GET['from'];
|
||||||
|
$page = 'index.php';
|
||||||
|
if (!empty($_GET['from'])) {
|
||||||
|
$page = $_GET['from'];
|
||||||
|
}
|
||||||
if ($success) {
|
if ($success) {
|
||||||
redirect('index.php');
|
redirect($page);
|
||||||
} else {
|
} else {
|
||||||
quit(get_page_header().'Echo error authenticating');
|
quit(get_page_header().'Echo error authenticating');
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hutattedonmyarm/dragonpolls",
|
"name": "hutattedonmyarm/dragonpolls",
|
||||||
"version": "1.1.0-beta",
|
"version": "1.2.0-beta",
|
||||||
"description": "A polling client for pnut.io",
|
"description": "A polling client for pnut.io",
|
||||||
"require": {
|
"require": {
|
||||||
"hutattedonmyarm/apnuti": "@dev"
|
"hutattedonmyarm/apnuti": "@dev"
|
||||||
|
11
globals.php
11
globals.php
@ -20,11 +20,14 @@ function get_page_header(
|
|||||||
$newpoll_class = '';
|
$newpoll_class = '';
|
||||||
if ($api->isAuthenticated(false, true)) {
|
if ($api->isAuthenticated(false, true)) {
|
||||||
$u = $api->getAuthorizedUser();
|
$u = $api->getAuthorizedUser();
|
||||||
$greeting = 'Welcome, ' . ($u->name ?? '@'.$u->username);
|
$user_avatar_url = $u->getAvatarUrl(30);
|
||||||
|
$user_avatar_url_srcset = get_source_set($u, 30);
|
||||||
|
$avatar = '<img src="' . $user_avatar_url . '" class="avatar" srcset="' . $user_avatar_url_srcset . '"/>';
|
||||||
|
$greeting = $avatar . '<span class="greeting">Welcome, ' . ($u->name ?? '@'.$u->username) . '</span>';
|
||||||
$logout_link = '<a href="logout.php" class="logout">Logout</a>';
|
$logout_link = '<a href="logout.php" class="logout">Logout</a>';
|
||||||
} else {
|
} else {
|
||||||
$newpoll_class = 'disabled';
|
$newpoll_class = 'disabled';
|
||||||
$greeting = '<a href="' . $api->getAuthURL() . '">Login with pnut</a>';
|
$greeting = '<a href="' . $api->getAuthURL('?from=' . $_SERVER['REQUEST_URI']) . '">Login with pnut</a>';
|
||||||
}
|
}
|
||||||
$title = '';
|
$title = '';
|
||||||
if ($include_app_name) {
|
if ($include_app_name) {
|
||||||
@ -67,7 +70,7 @@ function get_page_header(
|
|||||||
. $favicons
|
. $favicons
|
||||||
. '<title>'.$title.'</title><link rel="stylesheet" href="styles/style.css">'
|
. '<title>'.$title.'</title><link rel="stylesheet" href="styles/style.css">'
|
||||||
. $script_str
|
. $script_str
|
||||||
. '<meta name="viewport" content="width=device-width,initial-scale=1">'
|
. '<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">'
|
||||||
. '</head><body><header>'
|
. '</head><body><header>'
|
||||||
. $home_link
|
. $home_link
|
||||||
. $new_poll_link
|
. $new_poll_link
|
||||||
@ -126,7 +129,7 @@ function get_source_set($user, int $base_size, int $max_scale = 3): string
|
|||||||
function make_banner(string $type, string $content, string $custom_symbol = null): string
|
function make_banner(string $type, string $content, string $custom_symbol = null): string
|
||||||
{
|
{
|
||||||
if (empty($custom_symbol)) {
|
if (empty($custom_symbol)) {
|
||||||
$custom_symbol = $type === 'success' ? '✓' : '𐄂';
|
$custom_symbol = $type === 'success' ? 'ઙ' : '×';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<div class="banner-wrapper">'
|
return '<div class="banner-wrapper">'
|
||||||
|
10
index.php
10
index.php
@ -58,10 +58,12 @@ foreach ($polls as $poll) {
|
|||||||
<div class="poll" onclick="location.href='view_poll.php?id=<?= $poll->id ?>'">
|
<div class="poll" onclick="location.href='view_poll.php?id=<?= $poll->id ?>'">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="user">
|
<div class="user">
|
||||||
<img src="<?= $user_avatar_url ?>" class="avatar" srcset="<?= $user_avatar_url_srcset ?>"/>
|
<div class="usernamewrapper">
|
||||||
<div class="usernames">
|
<img src="<?= $user_avatar_url ?>" class="avatar" srcset="<?= $user_avatar_url_srcset ?>"/>
|
||||||
<b><?= $user_name.'<br>' ?></b>
|
<div class="usernames">
|
||||||
<span class="username"><?= $username ?></span>
|
<b><?= $user_name.'<br>' ?></b>
|
||||||
|
<span class="username"><?= $username ?></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<div class="datewrapper">
|
<div class="datewrapper">
|
||||||
|
@ -32,7 +32,7 @@ if (!empty($_POST['submit'])) {
|
|||||||
$duration_total_minutes = $duration_days*60*24 + $duration_hours * 60 + $duration_minutes;
|
$duration_total_minutes = $duration_days*60*24 + $duration_hours * 60 + $duration_minutes;
|
||||||
try {
|
try {
|
||||||
$poll = Poll::create($api, $prompt, $options, $max_options, $duration_total_minutes, $is_anonymous, $is_public);
|
$poll = Poll::create($api, $prompt, $options, $max_options, $duration_total_minutes, $is_anonymous, $is_public);
|
||||||
redirect('post_poll.php?poll_token='.$poll->token.'&id='.$poll->id.'&prompt='.urlencode($prompt));
|
redirect('post_poll.php?poll_token='.$poll->token.'&id='.$poll->id);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
quit('Something went wrong creating the poll: "' . $e->getMessage() . '"');
|
quit('Something went wrong creating the poll: "' . $e->getMessage() . '"');
|
||||||
}
|
}
|
||||||
|
@ -68,22 +68,34 @@ if (empty($_GET['id']) || !is_numeric($_GET['id']) || $_GET['id'] <= 0) {
|
|||||||
quit('Invalid poll ID');
|
quit('Invalid poll ID');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($_GET['poll_token'])) {
|
$poll_token = empty($_GET['poll_token']) ? null : $_GET['poll_token'];
|
||||||
|
$prompt = empty($_GET['prompt']) ? null : $_GET['prompt'];
|
||||||
|
$poll_id = (int)$_GET['id'];
|
||||||
|
$poll = null;
|
||||||
|
$is_public = false;
|
||||||
|
try {
|
||||||
|
$poll = $api->getPoll($poll_id, $poll_token);
|
||||||
|
$poll_token = $poll->token;
|
||||||
|
$prompt = $poll->prompt;
|
||||||
|
$is_public = $poll->is_public;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// Do nothing, check for token and prompt later
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (empty($poll_token)) {
|
||||||
quit('Invalid poll token');
|
quit('Invalid poll token');
|
||||||
}
|
}
|
||||||
if (empty($_GET['prompt'])) {
|
if (empty($prompt)) {
|
||||||
quit('Invalid prompt');
|
quit('Invalid prompt');
|
||||||
}
|
}
|
||||||
|
|
||||||
$poll_id = (int)$_GET['id'];
|
$poll_id = (int)$_GET['id'];
|
||||||
$poll_token = $_GET['poll_token'];
|
|
||||||
$prompt = $_GET['prompt'];
|
|
||||||
$dir_name = dirname($_SERVER['SCRIPT_NAME']);
|
$dir_name = dirname($_SERVER['SCRIPT_NAME']);
|
||||||
if ($dir_name === '.' || $dir_name === '/') {
|
if ($dir_name === '.' || $dir_name === '/') {
|
||||||
$dir_name = '';
|
$dir_name = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$scheme = empty($_SERVER['REQUEST_SCHEME']) ? 'http' : $_SERVER['REQUEST_SCHEME'];
|
$scheme = empty($_SERVER['REQUEST_SCHEME']) ? 'http' : $_SERVER['REQUEST_SCHEME'];
|
||||||
$url = $scheme
|
$url = $scheme
|
||||||
. '://'
|
. '://'
|
||||||
@ -126,9 +138,11 @@ Do you want to post about your poll?
|
|||||||
<button type="submit" name="submit" value="submit">Post to pnut</button>
|
<button type="submit" name="submit" value="submit">Post to pnut</button>
|
||||||
</form>
|
</form>
|
||||||
<a href="/view_poll.php?id=<?= $poll_id ?>">Take me straight to the poll</a>
|
<a href="/view_poll.php?id=<?= $poll_id ?>">Take me straight to the poll</a>
|
||||||
<p>
|
<?php if (!$is_public) { ?>
|
||||||
Note, that if your poll is set to private, you will either need to share your poll with a post,
|
<p>
|
||||||
or give the poll's access token to everyone who should be able to vote in your poll. Your access token is:
|
Note, that your poll is set to private. You will either need to share your poll with a post,
|
||||||
<pre><?= $poll_token ?></pre>
|
or give the poll's access token to everyone who should be able to vote in your poll. Your access token is:
|
||||||
</p>
|
<pre><?= $poll_token ?></pre>
|
||||||
|
</p>
|
||||||
|
<?php } ?>
|
||||||
<?= get_page_footer() ?>
|
<?= get_page_footer() ?>
|
151
styles/style.css
151
styles/style.css
@ -1,13 +1,15 @@
|
|||||||
/* Globals */
|
/* Globals */
|
||||||
:root {
|
:root {
|
||||||
--main-bg-color: rgb(48, 48, 48);
|
--main-bg-color: rgb(223, 223, 223);
|
||||||
--secondary-bg-color: rgba(10, 10, 10, 0.7);
|
--secondary-bg-color: rgba(20, 20, 20, 0.7);
|
||||||
--main-fg-color: white;
|
--ternary-bg-color: rgba(175, 175, 175, 0.7);
|
||||||
|
--main-fg-color: black;
|
||||||
|
--secondary-fg-color: rgb(210, 210, 210);
|
||||||
--main-accent-color: rgb(253, 122, 0);
|
--main-accent-color: rgb(253, 122, 0);
|
||||||
--disabled-color: gray;
|
--disabled-color: gray;
|
||||||
--green: green;
|
--green: green;
|
||||||
--default-shadow: 3px 3px 10px 1px var(--secondary-bg-color);
|
--default-shadow: 3px 3px 10px 1px var(--secondary-bg-color);
|
||||||
--error-color-translucent: rgba(255, 0, 0, 0.3);
|
--error-color-translucent: rgba(193, 0, 0, 0.87);
|
||||||
--error-color: rgba(255, 0, 0);
|
--error-color: rgba(255, 0, 0);
|
||||||
}
|
}
|
||||||
@supports (color: color(display-p3 1 1 1)) {
|
@supports (color: color(display-p3 1 1 1)) {
|
||||||
@ -16,6 +18,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--main-bg-color: rgb(48, 48, 48);
|
||||||
|
--secondary-bg-color: rgba(10, 10, 10, 0.7);
|
||||||
|
--ternary-bg-color: rgba(10, 10, 10, 0.7);
|
||||||
|
--main-fg-color: white;
|
||||||
|
--secondary-fg-color: rgb(210, 210, 210);
|
||||||
|
--main-accent-color: rgb(253, 122, 0);
|
||||||
|
--disabled-color: gray;
|
||||||
|
--green: green;
|
||||||
|
--default-shadow: 3px 3px 10px 1px var(--secondary-bg-color);
|
||||||
|
--error-color-translucent: rgba(255, 0, 0, 0.3);
|
||||||
|
--error-color: rgba(255, 0, 0);
|
||||||
|
}
|
||||||
|
@supports (color: color(display-p3 1 1 1)) {
|
||||||
|
:root {
|
||||||
|
--main-accent-color: color(display-p3 0.927 0.506 0.028)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
::placeholder {
|
||||||
|
opacity: 1;
|
||||||
|
color: rgb(73, 73, 73);
|
||||||
|
}
|
||||||
|
:-ms-input-placeholder {
|
||||||
|
color: rgb(73, 73, 73);
|
||||||
|
}
|
||||||
|
::-ms-input-placeholder {
|
||||||
|
color: rgb(73, 73, 73);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a:visited, a {
|
a:visited, a {
|
||||||
color: var(--main-accent-color);
|
color: var(--main-accent-color);
|
||||||
}
|
}
|
||||||
@ -84,6 +120,7 @@ header {
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
background: var(--secondary-bg-color);
|
background: var(--secondary-bg-color);
|
||||||
box-shadow: var(--default-shadow);
|
box-shadow: var(--default-shadow);
|
||||||
|
color: var(--secondary-fg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.spacer {
|
.spacer {
|
||||||
@ -107,6 +144,23 @@ header .newpolllink svg {
|
|||||||
stroke-width: 1em;
|
stroke-width: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header .avatar {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 450px) {
|
||||||
|
.linklabel {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 380px) {
|
||||||
|
.greeting {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Polls */
|
/* Polls */
|
||||||
.poll {
|
.poll {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -127,6 +181,11 @@ header .newpolllink svg {
|
|||||||
box-shadow: var(--default-shadow);
|
box-shadow: var(--default-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.poll .user .usernamewrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.datewrapper {
|
.datewrapper {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-column-gap: 8px;
|
grid-column-gap: 8px;
|
||||||
@ -154,9 +213,28 @@ datewrapper time {
|
|||||||
}
|
}
|
||||||
.poll .header .user .avatar {
|
.poll .header .user .avatar {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
}
|
}
|
||||||
.option-responses .avatar {
|
.option-responses .avatar {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 450px) {
|
||||||
|
.poll-grid .poll .user {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
.datewrapper {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 380px) {
|
||||||
|
.poll .user {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Success banner */
|
/* Success banner */
|
||||||
@ -210,13 +288,13 @@ datewrapper time {
|
|||||||
}
|
}
|
||||||
.create-poll input[type=number] {
|
.create-poll input[type=number] {
|
||||||
max-width: 3em;
|
max-width: 3em;
|
||||||
background-color: var(--secondary-bg-color);
|
background-color: var(--ternary-bg-color);
|
||||||
color: var(--main-accent-color);
|
color: var(--main-accent-color);
|
||||||
}
|
}
|
||||||
.create-poll input[type=text] {
|
.create-poll input[type=text] {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: var(--secondary-bg-color);
|
background-color: var(--ternary-bg-color);
|
||||||
color: var(--main-accent-color);
|
color: var(--main-accent-color);
|
||||||
}
|
}
|
||||||
.create-poll input[type=text]:focus {
|
.create-poll input[type=text]:focus {
|
||||||
@ -262,6 +340,42 @@ datewrapper time {
|
|||||||
color: var(--main-text-color);
|
color: var(--main-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
#prompt {
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
label[for=prompt] {
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
.create-poll label[for=options] {
|
||||||
|
grid-row: 3;
|
||||||
|
}
|
||||||
|
.create-poll #options {
|
||||||
|
grid-row: 3;
|
||||||
|
}
|
||||||
|
.create-poll label[for=anonymous] {
|
||||||
|
grid-row: 4
|
||||||
|
}
|
||||||
|
.create-poll label[for=public] {
|
||||||
|
grid-row: 5
|
||||||
|
}
|
||||||
|
.create-poll label[for=max_options] {
|
||||||
|
grid-row: 6
|
||||||
|
}
|
||||||
|
.create-poll label[for=duration] {
|
||||||
|
grid-row: 7
|
||||||
|
}
|
||||||
|
#duration {
|
||||||
|
grid-row: 7;
|
||||||
|
}
|
||||||
|
.create-poll button[type=submit] {
|
||||||
|
grid-row: 8;
|
||||||
|
}
|
||||||
|
.create-poll .error {
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Footer */
|
/* Footer */
|
||||||
footer {
|
footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -276,10 +390,34 @@ footer .sourcecode svg {
|
|||||||
stroke-width: 1.5em;
|
stroke-width: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Deal with the pill on iOS */
|
||||||
|
@supports (padding: env(safe-area-inset-left)) {
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
header {
|
||||||
|
padding-left: max(env(safe-area-inset-left, 20px), 8px);
|
||||||
|
padding-right: env(safe-area-inset-right, 20px);
|
||||||
|
padding-top: calc(env(safe-area-inset-top, 20px) + 8px);
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
padding-left: calc(env(safe-area-inset-left, 20px) + 8px);
|
||||||
|
padding-right: env(safe-area-inset-right, 20px);
|
||||||
|
padding-bottom: max(env(safe-area-inset-bottom, 20px), 8px);
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
padding-left: max(env(safe-area-inset-left, 20px), 8px);
|
||||||
|
padding-right: max(env(safe-area-inset-right, 20px), 8px);
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Poll grid */
|
/* Poll grid */
|
||||||
.poll-grid {
|
.poll-grid {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.poll-grid .poll {
|
.poll-grid .poll {
|
||||||
@ -289,6 +427,7 @@ footer .sourcecode svg {
|
|||||||
margin: 8px;
|
margin: 8px;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.poll-grid .poll:hover {
|
.poll-grid .poll:hover {
|
||||||
|
@ -127,13 +127,11 @@ if (array_key_exists('poll_created', $_GET) && $_GET['poll_created'] == 1) { ?>
|
|||||||
<div class="option-responses" style="grid-row: <?= $row++ ?>;grid-column: 2;">
|
<div class="option-responses" style="grid-row: <?= $row++ ?>;grid-column: 2;">
|
||||||
<?php foreach ($option->respondent_ids as $res_id) {
|
<?php foreach ($option->respondent_ids as $res_id) {
|
||||||
$u = $api->getUser($res_id, $user_args); ?>
|
$u = $api->getUser($res_id, $user_args); ?>
|
||||||
<a href="https://pnut.io/@<?= $u->username ?>">
|
<a href="https://pnut.io/@<?= $u->username ?>"><img
|
||||||
<img
|
|
||||||
src="<?= $u->getAvatarUrl(20) ?>"
|
src="<?= $u->getAvatarUrl(20) ?>"
|
||||||
srcset="<?= get_source_set($u, 20) ?>"
|
srcset="<?= get_source_set($u, 20) ?>"
|
||||||
class="avatar"
|
class="avatar"
|
||||||
title="@<?= $u->username ?>">
|
title="@<?= $u->username ?>"></a>
|
||||||
</a>
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
Reference in New Issue
Block a user