non-working first part of htmx rewrite

This commit is contained in:
Chris 2023-11-08 19:24:48 +01:00
parent 2cc5156742
commit 5c6cb30910
16 changed files with 299 additions and 64 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
web/css/default.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
[ZoneTransfer]
ZoneId=3
ReferrerUrl=C:\Users\chris\Downloads\pico-1.5.10.zip

View file

@ -1,7 +1,19 @@
body {
padding-top: 5rem;
}
.starter-template {
padding: 3rem 1.5rem;
form {
margin: 0;
padding: 0;
display: inline;
}
tr.htmx-swapping td {
opacity: 0;
transition: opacity 1s ease-out;
}
.badge {
background-color: #999;
color: white;
padding: 4px 8px;
margin: 2px;
text-align: center;
}
border-radius: 5px;
}

5
web/css/pico.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -103,6 +103,11 @@ function listEmailAdresses()
return $o;
}
function attachmentExists($email,$id,$attachment)
{
return file_exists(getDirForEmail($email).DS.'attachments'.DS.$id.'-'.$attachment);
}
function listAttachmentsOfMailID($email,$id)
{
$o = array();
@ -134,3 +139,9 @@ function loadSettings()
return parse_ini_file(ROOT.DS.'..'.DS.'config.ini');
return false;
}
function escape($str)
{
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

View file

@ -1,48 +1,36 @@
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="shortcut icon" href="favicon.ico">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/css/pico.min.css">
<link rel="stylesheet" href="/css/opentrashmail.css">
<title>Hello, world!</title>
</head>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/opentrashmail.css">
<link rel="stylesheet" href="css/fontawesome.min.css">
<body>
<div class="container-fluid">
<nav>
<ul>
<li><img src="imgs/logo_300_light.png" width="50px" /> Open Trashmail</li>
<li><form id="emailform"><input name="email" type="email" placeholder="email address" aria-label="email address"></form></li>
<li><button hx-post="/api/address" hx-include="#emailform" hx-target="#main" ><i class="fas fa-arrow-left"></i><i class="fas fa-envelope"></i> Access account</button></li>
<li><button onClick="generateAccount()" id="btn-gen-random" class="btn btn-secondary my-2 my-sm-0"><i class="fas fa-random"></i> Generate random</button></li>
<li><button onClick="listAddresses(event)" id="btn-list-addresses" class="btn btn-secondary my-2 my-sm-0" style="display:none;"><i class="fas fa-list"></i> List accounts</button></li>
</ul>
</nav>
</div>
<title>Open Trashmail</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="?"><img src="imgs/logo_300_light.png" width="50px" /> Open Trashmail </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navi" aria-controls="navi" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navi">
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" id="email" type="email" placeholder="email address" aria-label="email address">
<button onClick="accessAccount()" class="btn btn-secondary my-2 my-sm-0"><i class="fas fa-arrow-left"></i><i class="fas fa-envelope"></i> Access account</button> &nbsp;
<button onClick="generateAccount()" id="btn-gen-random" class="btn btn-secondary my-2 my-sm-0"><i class="fas fa-random"></i> Generate random</button> &nbsp;
<button onClick="listAddresses(event)" id="btn-list-addresses" class="btn btn-secondary my-2 my-sm-0" style="display:none;"><i class="fas fa-list"></i> List accounts</button>
</form>
</div>
</nav>
<main id="main" class="container">
<h1>Welcome to Open Trashmail</h1>
<p>Access an email address or generate a new one.</p>
</main>
<main role="main" class="container" id="main">
<div class="starter-template">
<h1>Welcome to Open Trashmail</h1>
<p class="lead">Access an email address or generate a new one.</p>
</div>
<script src="/js/htmx.min.js"></script>
<script src="/js/namegenerator.js"></script>
<!-- <script src="/js/opentrashmail.js"></script> -->
<script src="/js/moment-with-locales.min.js"></script>
</body>
</main><!-- /.container -->
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/namegenerator.js"></script>
<script src="js/opentrashmail.js"></script>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/moment-with-locales.min.js"></script>
</body>
</html>

117
web/index.php Normal file
View file

@ -0,0 +1,117 @@
<?php
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__FILE__));
include_once(ROOT.DS.'inc'.DS.'core.php');
$url = array_filter(explode('/',ltrim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH),'/')));
if($_SERVER['HTTP_HX_REQUEST']!='true')
{
if(!file_exists(ROOT.DS.implode('/', $url)))
exit(file_get_contents(ROOT.DS.'index.html'));
else return false;
}
$api = new OpenTrashmailAPI($url);
$answer = $api->run();
if($answer === false)
return false;
else
echo $answer;
class OpenTrashmailAPI{
private $url;
private $settings;
public function __construct($url){
$this->url = $url;
$this->settings = loadSettings();
}
public function run(){
switch($this->url[0]){
case 'address':
return $this->listAccount($_REQUEST['email']?:$this->url[1]);
case 'read':
return $this->readMail($_REQUEST['email'],$_REQUEST['id']);
case 'attachment':
return $this->getAttachment($this->url[1],$this->url[2],$this->url[3]);
case 'delete':
return $this->deleteMail($_REQUEST['email'],$_REQUEST['id']);
default:
return false;
}
}
function getAttachment($email,$id,$attachment)
{
if(!filter_var($email, FILTER_VALIDATE_EMAIL))
return $this->error('Invalid email address');
else if(!ctype_digit($id))
return $this->error('Invalid id');
else if(!emailIDExists($email,$id))
return $this->error('Email not found');
else if(!attachmentExists($email,$id,$attachment))
return $this->error('Attachment not found');
$dir = getDirForEmail($email);
$file = $dir.DS.'attachments'.DS.$id.'-'.$attachment;
$mime = mime_content_type($file);
header('Content-Type: '.$mime);
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
function readMail($email,$id)
{
if(!filter_var($email, FILTER_VALIDATE_EMAIL))
return $this->error('Invalid email address');
else if(!ctype_digit($id))
return $this->error('Invalid id');
else if(!emailIDExists($email,$id))
return $this->error('Email not found');
$email = getEmail($email,$id);
//$email['raw'] = file_get_contents(getDirForEmail($email['email']).DS.$email['id'].'.json');
//$email['parsed'] = json_decode($email['raw'],true);
var_dump($email);
return $this->renderPartial('email',[
'email'=>$email,
'mailid'=>$id,
]);
}
public function listAccount($email)
{
if(!filter_var($email, FILTER_VALIDATE_EMAIL))
return $this->error('Invalid email address');
$emails = getEmailsOfEmail($email);
var_dump($emails);
return $this->renderPartial('email-table',[
'email'=>$email,
'emails'=>$emails,
'dateformat'=>$this->settings['DATEFORMAT']
]);
}
public function error($text)
{
return '<h1>'.$text.'</h1>';
}
public function renderPartial($partialname,$variables=[])
{
ob_start();
if(is_array($variables))
extract($variables);
if(file_exists(ROOT.DS.'partials'.DS.$partialname.'.html.php'))
include(ROOT.DS.'partials'.DS.$partialname.'.html.php');
$rendered = ob_get_contents();
ob_end_clean();
return $rendered;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
web/js/htmx.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

48
web/oldindex.html Normal file
View file

@ -0,0 +1,48 @@
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="shortcut icon" href="favicon.ico">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/opentrashmail.css">
<link rel="stylesheet" href="css/fontawesome.min.css">
<title>Open Trashmail</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="?"><img src="imgs/logo_300_light.png" width="50px" /> Open Trashmail </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navi" aria-controls="navi" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navi">
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" id="email" type="email" placeholder="email address" aria-label="email address">
<button onClick="accessAccount()" class="btn btn-secondary my-2 my-sm-0"><i class="fas fa-arrow-left"></i><i class="fas fa-envelope"></i> Access account</button> &nbsp;
<button onClick="generateAccount()" id="btn-gen-random" class="btn btn-secondary my-2 my-sm-0"><i class="fas fa-random"></i> Generate random</button> &nbsp;
<button onClick="listAddresses(event)" id="btn-list-addresses" class="btn btn-secondary my-2 my-sm-0" style="display:none;"><i class="fas fa-list"></i> List accounts</button>
</form>
</div>
</nav>
<main role="main" class="container" id="main">
<div class="starter-template">
<h1>Welcome to Open Trashmail</h1>
<p class="lead">Access an email address or generate a new one.</p>
</div>
</main><!-- /.container -->
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/namegenerator.js"></script>
<script src="js/opentrashmail.js"></script>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/moment-with-locales.min.js"></script>
</body>
</html>

View file

@ -0,0 +1,39 @@
<h3>Emails of <?= $email; ?></h3>
<table role="grid">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Date</th>
<th scope="col">From</th>
<th scope="col">Subject</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<?php if(count($emails)==0): ?>
<tr>
<td colspan="5"><center>No emails received on this address (yet..)</center></td>
</tr>
<?php endif; ?>
<?php foreach($emails as $unixtime => $ed): ?>
<tr>
<th scope="row"><?= ++$i; ?></th>
<td id="date-td-<?= $i ?>"><script>document.getElementById('date-td-<?= $i ?>').innerHTML = moment.unix(parseInt(<?=$unixtime?>/1000)).format('<?= $dateformat; ?>');</script></td>
<td><?= escape($ed['from']) ?></td>
<td><?= escape($ed['subject']) ?></td>
<td>
<form>
<input type="hidden" name="email" value="<?= $email ?>">
<input type="hidden" name="id" value="<?= $ed['id'] ?>">
<div class="grid">
<div><input type="submit" value="Read" hx-post="/api/read" hx-target="#main"></div>
<div><input type="submit" value="Delete" hx-post="/api/delete" hx-confirm="Are you sure?" hx-target="closest tr" hx-swap="outerHTML swap:1s"></div>
</div>
</form>
</td>
</tr>
<?php endforeach; ?>
</table>

View file

@ -0,0 +1,27 @@
<article>
<header>Subject: <?= escape($email['parsed']['subject']) ?></header>
<header>
Reciepients:
<div>
<?php foreach($email['rcpts'] as $to): ?>
<small class="badge"><?= escape($to) ?></small>
<?php endforeach; ?>
</div>
</header>
<?= nl2br(escape($email['parsed']['body'])) ?>
<footer>
Attachments
<div>
<?php if(count($email['parsed']['attachments'])==0): ?>
<small class="secondary">No attachments</small>
<?php endif; ?>
<ul>
<?php foreach($email['parsed']['attachments'] as $attachment): ?>
<li>
<a href="/api/attechment/<?= $mailid ?>/<?= $attachment ?>"><?= escape($attachment) ?></a>
</li>
<?php endforeach; ?>
</ul>
</div>
</footer>
</article>