added javascript bits, flask flashing, better routing, ux improvements

main
lza_menace 3 years ago
parent 8e3a6338c7
commit f2701abd82

@ -0,0 +1,2 @@
DATA_FOLDER=/home/yourname/git/github.com/lalanza808/suchwowx/data
SECRET_KEY=mycrazyrandomstring

@ -2,9 +2,10 @@ import ipfsApi
from os import path
from secrets import token_urlsafe
from json import loads, dumps
from requests.exceptions import HTTPError
from flask import Blueprint, render_template, request, current_app
from flask import send_from_directory, redirect
from flask import send_from_directory, redirect, flash, url_for
from suchwowx.models import Meme
from suchwowx.factory import db
@ -21,7 +22,20 @@ def index():
@bp.route('/new', methods=['GET', 'POST'])
def new():
meme = None
form_err = False
try:
client = ipfsApi.Client('127.0.0.1', 5001)
client.add_json({})
except Exception as e:
msg = f'[!] IPFS Error: {e}'
print(msg)
flash(msg, 'error')
if "file" in request.files:
return '<script>window.history.back()</script>'
return redirect(url_for('meta.index'))
if "file" in request.files:
if form_err:
return '<script>window.history.back()</script>'
title = request.form.get('title')
description = request.form.get('description')
creator = request.form.get('creator')
@ -65,7 +79,7 @@ def new():
db.session.commit()
return redirect('/')
except ConnectionError:
print('[!] Unable to connect to local ipfs')
flash('[!] Unable to connect to local ipfs', 'error')
except Exception as e:
print(e)
return render_template(

@ -0,0 +1,46 @@
.noty_theme__relax.noty_bar {
margin: 4px 0;
overflow: hidden;
border-radius: 2px;
position: relative; }
.noty_theme__relax.noty_bar .noty_body {
padding: 10px; }
.noty_theme__relax.noty_bar .noty_buttons {
border-top: 1px solid #e7e7e7;
padding: 5px 10px; }
.noty_theme__relax.noty_type__alert,
.noty_theme__relax.noty_type__notification {
background-color: #fff;
border: 1px solid #dedede;
color: #444; }
.noty_theme__relax.noty_type__warning {
background-color: #FFEAA8;
border: 1px solid #FFC237;
color: #826200; }
.noty_theme__relax.noty_type__warning .noty_buttons {
border-color: #dfaa30; }
.noty_theme__relax.noty_type__error {
background-color: #FF8181;
border: 1px solid #e25353;
color: #FFF; }
.noty_theme__relax.noty_type__error .noty_buttons {
border-color: darkred; }
.noty_theme__relax.noty_type__info,
.noty_theme__relax.noty_type__information {
background-color: #78C5E7;
border: 1px solid #3badd6;
color: #FFF; }
.noty_theme__relax.noty_type__info .noty_buttons,
.noty_theme__relax.noty_type__information .noty_buttons {
border-color: #0B90C4; }
.noty_theme__relax.noty_type__success {
background-color: #BCF5BC;
border: 1px solid #7cdd77;
color: darkgreen; }
.noty_theme__relax.noty_type__success .noty_buttons {
border-color: #50C24E; }

@ -0,0 +1,222 @@
.noty_layout_mixin, #noty_layout__top, #noty_layout__topLeft, #noty_layout__topCenter, #noty_layout__topRight, #noty_layout__bottom, #noty_layout__bottomLeft, #noty_layout__bottomCenter, #noty_layout__bottomRight, #noty_layout__center, #noty_layout__centerLeft, #noty_layout__centerRight {
position: fixed;
margin: 0;
padding: 0;
z-index: 9999999;
-webkit-transform: translateZ(0) scale(1, 1);
transform: translateZ(0) scale(1, 1);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
filter: blur(0);
-webkit-filter: blur(0);
max-width: 90%; }
#noty_layout__top {
top: 0;
left: 5%;
width: 90%; }
#noty_layout__topLeft {
top: 20px;
left: 20px;
width: 325px; }
#noty_layout__topCenter {
top: 5%;
left: 50%;
width: 325px;
-webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); }
#noty_layout__topRight {
top: 20px;
right: 20px;
width: 325px; }
#noty_layout__bottom {
bottom: 0;
left: 5%;
width: 90%; }
#noty_layout__bottomLeft {
bottom: 20px;
left: 20px;
width: 325px; }
#noty_layout__bottomCenter {
bottom: 5%;
left: 50%;
width: 325px;
-webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); }
#noty_layout__bottomRight {
bottom: 20px;
right: 20px;
width: 325px; }
#noty_layout__center {
top: 50%;
left: 50%;
width: 325px;
-webkit-transform: translate(-webkit-calc(-50% - .5px), -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
transform: translate(calc(-50% - .5px), calc(-50% - .5px)) translateZ(0) scale(1, 1); }
#noty_layout__centerLeft {
top: 50%;
left: 20px;
width: 325px;
-webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); }
#noty_layout__centerRight {
top: 50%;
right: 20px;
width: 325px;
-webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); }
.noty_progressbar {
display: none; }
.noty_has_timeout.noty_has_progressbar .noty_progressbar {
display: block;
position: absolute;
left: 0;
bottom: 0;
height: 3px;
width: 100%;
background-color: #646464;
opacity: 0.2;
filter: alpha(opacity=10); }
.noty_bar {
-webkit-backface-visibility: hidden;
-webkit-transform: translate(0, 0) translateZ(0) scale(1, 1);
-ms-transform: translate(0, 0) scale(1, 1);
transform: translate(0, 0) scale(1, 1);
-webkit-font-smoothing: subpixel-antialiased;
overflow: hidden; }
.noty_effects_open {
opacity: 0;
-webkit-transform: translate(50%);
-ms-transform: translate(50%);
transform: translate(50%);
-webkit-animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards; }
.noty_effects_close {
-webkit-animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards; }
.noty_fix_effects_height {
-webkit-animation: noty_anim_height 75ms ease-out;
animation: noty_anim_height 75ms ease-out; }
.noty_close_with_click {
cursor: pointer; }
.noty_close_button {
position: absolute;
top: 2px;
right: 2px;
font-weight: bold;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
background-color: rgba(0, 0, 0, 0.05);
border-radius: 2px;
cursor: pointer;
-webkit-transition: all .2s ease-out;
transition: all .2s ease-out; }
.noty_close_button:hover {
background-color: rgba(0, 0, 0, 0.1); }
.noty_modal {
position: fixed;
width: 100%;
height: 100%;
background-color: #000;
z-index: 10000;
opacity: .3;
left: 0;
top: 0; }
.noty_modal.noty_modal_open {
opacity: 0;
-webkit-animation: noty_modal_in .3s ease-out;
animation: noty_modal_in .3s ease-out; }
.noty_modal.noty_modal_close {
-webkit-animation: noty_modal_out .3s ease-out;
animation: noty_modal_out .3s ease-out;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards; }
@-webkit-keyframes noty_modal_in {
100% {
opacity: .3; } }
@keyframes noty_modal_in {
100% {
opacity: .3; } }
@-webkit-keyframes noty_modal_out {
100% {
opacity: 0; } }
@keyframes noty_modal_out {
100% {
opacity: 0; } }
@keyframes noty_modal_out {
100% {
opacity: 0; } }
@-webkit-keyframes noty_anim_in {
100% {
-webkit-transform: translate(0);
transform: translate(0);
opacity: 1; } }
@keyframes noty_anim_in {
100% {
-webkit-transform: translate(0);
transform: translate(0);
opacity: 1; } }
@-webkit-keyframes noty_anim_out {
100% {
-webkit-transform: translate(50%);
transform: translate(50%);
opacity: 0; } }
@keyframes noty_anim_out {
100% {
-webkit-transform: translate(50%);
transform: translate(50%);
opacity: 0; } }
@-webkit-keyframes noty_anim_height {
100% {
height: 0; } }
@keyframes noty_anim_height {
100% {
height: 0; } }
/*# sourceMappingURL=noty.css.map*/
/* Custom */
.noty_body {
text-align: center;
}

@ -0,0 +1,10 @@
up-wrapper{display:inline-block}
up-bounds{position:absolute}.up-focusable-content:focus,.up-focusable-content:focus-visible{outline:0}
.up-request-loader{display:none}up-progress-bar{position:fixed;top:0;left:0;z-index:999999999;height:3px;background-color:#007bff}
up-focus-trap{position:fixed;top:0;left:0;width:0;height:0}up-modal,up-drawer,up-cover,up-modal-backdrop,up-drawer-backdrop,up-modal-viewport,up-drawer-viewport,up-cover-viewport{top:0;left:0;bottom:0;right:0}up-modal-box,up-drawer-box{box-shadow:0 0 10px 1px rgba(0,0,0,0.3)}up-popup{box-shadow:0 0 4px rgba(0,0,0,0.3)}up-modal:focus,up-drawer:focus,up-cover:focus,up-modal-box:focus,up-drawer-box:focus,up-cover-box:focus,up-popup:focus,up-modal:focus-visible,up-drawer:focus-visible,up-cover:focus-visible,up-modal-box:focus-visible,up-drawer-box:focus-visible,up-cover-box:focus-visible,up-popup:focus-visible{outline:none}up-modal,up-drawer,up-cover{z-index:2000;position:fixed}up-modal-backdrop,up-drawer-backdrop{position:absolute;background:rgba(0,0,0,0.4)}up-modal-viewport,up-drawer-viewport,up-cover-viewport{position:absolute;overflow-y:scroll;overflow-x:hidden;overscroll-behavior:contain;text-align:center}up-modal-box,up-drawer-box,up-cover-box,up-popup{display:inline-block;text-align:left;position:relative;box-sizing:border-box;max-width:100%;background-color:#fff;padding:20px;overflow-x:hidden}up-modal-content,up-drawer-content,up-cover-content,up-popup-content{display:block}up-popup{z-index:1000}up-modal-dismiss,up-drawer-dismiss,up-cover-dismiss,up-popup-dismiss{color:#888;position:absolute;top:10px;right:10px;font-size:1.7rem;line-height:0.5}up-modal-viewport{justify-content:center}up-modal[nesting="0"] up-modal-viewport{padding:25px 15px}up-modal[nesting="1"] up-modal-viewport{padding:50px 30px}up-modal[nesting="2"] up-modal-viewport{padding:75px 45px}up-modal[nesting="3"] up-modal-viewport{padding:100px 60px}up-modal[nesting="4"] up-modal-viewport{padding:125px 75px}up-modal[size=small] up-modal-box{width:350px}up-modal[size=medium] up-modal-box{width:650px}up-modal[size=large] up-modal-box{width:1000px}up-modal[size=grow] up-modal-box{width:auto}up-modal[size=full] up-modal-box{width:100%}up-drawer-viewport{text-align:left}up-drawer[position=right] up-drawer-viewport{text-align:right}up-drawer-box{min-height:100vh}up-drawer[size=small] up-drawer-box{width:150px}up-drawer[size=medium] up-drawer-box{width:340px}up-drawer[size=large] up-drawer-box{width:600px}up-drawer[size=grow] up-drawer-box{width:auto}up-drawer[size=full] up-drawer-box{width:100%}up-cover-box{width:100%;min-height:100vh;padding:0}up-popup{padding:15px}up-popup[size=small]{width:180px}up-popup[size=medium]{width:300px}up-popup[size=large]{width:550px}up-popup[size=grow] up-popup{width:auto}up-popup[size=full] up-popup{width:100%}
[up-href],[up-clickable]{cursor:pointer}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,6 @@
<footer style="margin: 0 auto; width: 100%; text-align: center;">
<p>Made by @lza_menace</p>
</footer>
{% include 'includes/scripts.html' %}

@ -2,8 +2,11 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SuchWowX!</title>
<script src="https://unpkg.com/unpoly@2.5.0/unpoly.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/unpoly@2.5.0/unpoly.min.css">
<script src="/static/js/vendor/unpoly-2.5.0.min.js"></script>
<link rel="stylesheet" href="/static/css/vendor/unpoly-2.5.0.min.css">
<link rel="stylesheet" href="/static/css/bulma.min.css">
<link rel="stylesheet" href="/static/css/bulma.css.map">
<!-- <link rel="stylesheet" href="/static/css/bulma.css.map"> -->
<link rel="stylesheet" href="/static/css/vendor/noty-relax.css" />
<link rel="stylesheet" href="/static/css/vendor/noty.css" />
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
</head>

@ -0,0 +1,20 @@
<script src="/static/js/vendor/noty-3.2.0.js"></script>
<!-- <script src="/static/js/vendor/web3-1.3.6.min.js"></script> -->
<!-- <script src="/static/js/main.js"></script> -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<script type="text/javascript">
{% for category, message in messages %}
{% if category == None %}{% set category = 'info' %}{% endif %}
new Noty({
type: '{{ category }}',
theme: 'relax',
layout: 'topCenter',
text: '{{ message }}',
timeout: 4500
}).show();
{% endfor %}
</script>
{% endif %}
{% endwith %}

@ -10,19 +10,37 @@
<p class="subtitle">
Memes. <strong>Interplanetary</strong>!
</p>
<a class="button is-primary" href="{{ url_for('meta.new') }}" up-target=".container">New Meme</a>
<a class="button is-primary" href="{{ url_for('meta.new') }}">New Meme</a>
{% if get_flashed_messages(with_categories=true) %}
<p>
</br>
You can run your own local IPFS instance and maintain metadata and artwork,
</br>
try installing the software and running the following:
</p>
<code>$ ipfs daemon</code>
{% endif %}
{% if memes %}
<div id="memes">
{% for meme in memes %}
<div class="meme" style="padding-top:1em;">
<p>Meme: <a href="{{ url_for('meta.meme', meme_id=meme.id) }}" up-target=".container">{{ meme }}</a></p>
<p>Meme: <a href="{{ url_for('meta.meme', meme_id=meme.id) }}" up-preload up-follow=".container">{{ meme }}</a></p>
<p>Upload path: {{ meme.upload_path }}</p>
<p>Meta IPFS: {{ meme.meta_ipfs_hash }}</p>
<p>Meme IPFS: {{ meme.meme_ipfs_hash }}</p>
<p>Title: {{ meme.title }}</p>
<p>Description: {{ meme.description }}</p>
<p>Creator handle: {{ meme.creator_handle }}</p>
{% if meme.upload_path.endswith('mp4') %}
<video style="max-height: 60vh!important;max-width:80px;" {% if not request.MOBILE %}autoplay{% else %}controls{% endif %} muted loop>
<source src="{{ url_for('meta.uploaded_file', filename=meme.upload_path) }}" type="video/mp4">
Your browser does not support the video tag.
</video>
{% else %}
<img src="{{ url_for('meta.uploaded_file', filename=meme.upload_path) }}" width="200px" class="img-fluid" style="" />
{% endif %}
</div>
{% endfor %}
</div>
@ -30,5 +48,6 @@
</div>
</section>
{% include 'includes/footer.html' %}
</body>
</html>

@ -10,7 +10,7 @@
<p class="subtitle">
Memes. <strong>Interplanetary</strong>!
</p>
<a class="button" href="{{ url_for('meta.index') }}" up-target=".container">Go Home</a>
<a class="button" href="{{ url_for('meta.index') }}" up-preload up-follow=".container">Go Home</a>
{% if meme %}
<div id="meme">
@ -22,7 +22,14 @@
<p>Title: {{ meme.title }}</p>
<p>Description: {{ meme.description }}</p>
<p>Creator handle: {{ meme.creator_handle }}</p>
<img src="{{ url_for('meta.uploaded_file', filename=meme.upload_path) }}">
{% if meme.upload_path.endswith('mp4') %}
<video style="max-height: 60vh!important;max-width:100%;" {% if not request.MOBILE %}autoplay{% else %}controls{% endif %} muted loop>
<source src="{{ url_for('meta.uploaded_file', filename=meme.upload_path) }}" type="video/mp4">
Your browser does not support the video tag.
</video>
{% else %}
<img src="{{ url_for('meta.uploaded_file', filename=meme.upload_path) }}"class="img-fluid" style="" />
{% endif %}
</div>
</div>
{% endif %}

@ -10,7 +10,7 @@
<p class="subtitle">
Memes. <strong>Interplanetary</strong>!
</p>
<a class="button" href="{{ url_for('meta.index') }}" up-target=".container">Go Back</a>
<a class="button" href="{{ url_for('meta.index') }}" up-preload up-follow=".container">Go Back</a>
<form method="POST" enctype="multipart/form-data" class="site-form" id="memeUpload" action="{{ url_for('meta.new') }}" style="padding-top:1.5em;">
<div class="field">
@ -52,7 +52,7 @@
<div class="field is-grouped">
<div class="control">
<button class="button is-primary" up-target=".container">Submit</button>
<button class="button is-primary" up-follow=".container">Submit</button>
</div>
</div>
</form>

Loading…
Cancel
Save