Commit 335528be authored by Mirko Vucicevich's avatar Mirko Vucicevich
Browse files

Merge branch 'p01'

parents 351e6eed d39fceb9
Pipeline #35804 canceled with stages
This diff is collapsed.
......@@ -13,7 +13,9 @@
"mithril": "^2.0.4",
"rollup": "^1.21.4",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-embed-css": "^1.0.7",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-postcss": "^2.0.3",
"rollup-plugin-terser": "^5.1.2"
},
"dependencies": {
......
......@@ -2,6 +2,7 @@ import fs from "fs";
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import pathmodify from "rollup-plugin-pathmodify";
import postcss from 'rollup-plugin-postcss';
import { terser } from "rollup-plugin-terser"
export const pkg = JSON.parse(fs.readFileSync("./package.json"));
......@@ -37,6 +38,11 @@ const plugins = [
commonjs({
include: "node_modules/**"
}),
postcss({
extensions: ['.css'],
minimize: env.BUILD ? true : false,
}),
]
// check if mithril is set to be external..
......
/* CLEARANCE STUFF */
.PJOVERLAY-contacts,.PJOVERLAY-help-ball,.PJOVERLAY-modal{
all: unset;
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
}
/* ANIMATIONS */
.PJOVERLAY-animated {
animation-duration: 0.25s;
animation-fill-mode: both;
}
@keyframes PJOVERLAY-fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.PJOVERLAY-fadeIn {
animation-name: PJOVERLAY-fadeIn;
}
@keyframes PJOVERLAY-fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.PJOVERLAY-fadeOut {
animation-name: PJOVERLAY-fadeOut;
}
@keyframes PJOVERLAY-fadeInUp {
from {
opacity: 0;
transform: translate3d(0, 100%, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
.PJOVERLAY-fadeInUp {
animation-name: PJOVERLAY-fadeInUp;
}
@keyframes PJOVERLAY-slideInUp {
from {
transform: translate3d(0, 100%, 0);
visibility: visible;
}
to {
transform: translate3d(0, 0, 0);
}
}
.PJOVERLAY-slideInUp {
animation-name: PJOVERLAY-slideInUp;
}
@keyframes PJOVERLAY-slideOutDown {
from {
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
transform: translate3d(0, 100%, 0);
}
}
.PJOVERLAY-slideOutDown {
animation-name: PJOVERLAY-slideOutDown;
}
/*modal*/
.PJOVERLAY-overlay{
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
overflow-y: scroll;
background-color: rgba(0,0,0,0.6);
animation-duration: 0.45s !important;
z-index: 10000;
}
.PJOVERLAY-modal{
position: relative;
width: 70%;
max-width: 600px;
min-width: 200px;
background-color: white;
padding: 20px;
border-radius: 4px;
animation-delay: 0.2s;
}
.PJOVERLAY-modal input, .PJOVERLAY-modal textarea{
border: 1px solid #AAA;
border-radius: 4px;
padding: 4px;
width: 100%;
margin-bottom: 12px;
}
.PJOVERLAY-closebutton{
position: absolute;
top: 4px;
right: 8px;
cursor: pointer;
font-size: 18px;
font-weight: 800;
color: #AAA;
}
/*CONTACT POPUP THING*/
.PJOVERLAY-contacts{
width: 280px;
background-color: white;
box-sizing: border-box;
padding-top: 8px;
padding-bottom: 24px;
position: fixed;
bottom: 0;
left: 8px;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.3);
}
.PJOVERLAY-contacts>h4{
padding: 0px 12px;
}
.PJOVERLAY-contact{
cursor: pointer;
background-color: white;
transition: background-color 0.2s ease-out;
padding: 8px 12px;
}
.PJOVERLAY-contact:hover{
background-color: #dae6f3;
}
/* HELP BALL */
.PJOVERLAY-help-ball{
position: fixed;
bottom: 10px;
left: 10px;
width: 40px;
max-height: 40px;
height: 40px;
background-color: #3F51B5;
border-color: #606fc7;
border-width: 0px;
border-radius: 4px;
border-style: solid;
color: white;
display: flex;
justify-content: center;
align-items: center;
font-size: 150%;
font-weight: 600;
cursor: pointer;
box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.3);
transition: all 0.5s ease-out;
}
.PJOVERLAY-help-ball:hover{
background-color: #606fc7;
box-shadow: 0 8px 15px 0 rgba(0, 0, 0, 0.3);
}
/*SPINNER*/
.PJOVERLAY-modal-cover{
display: flex;
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
z-index: 100001;
justify-content: center;
align-items: center;
border-radius: 4px;
background-color: rgba(255, 255, 255, 0.8);
}
.PJOVERLAY-dual-ring {
display: inline-block;
width: 80px;
height: 80px;
}
.PJOVERLAY-dual-ring:after {
content: " ";
display: block;
width: 64px;
height: 64px;
margin: 8px;
border-radius: 50%;
border: 6px solid #606fc7;
border-color: #606fc7 transparent #606fc7 transparent;
animation: PJOVERLAY-dual-ring 1.2s linear infinite;
}
@keyframes PJOVERLAY-dual-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/*NOTIFICATIONS*/
.PJOVERLAY-notification-list{
z-index: 10000;
position: fixed;
top: 12px;
width: 100%;
padding: 0 10%;
box-sizing: border-box;
}
.PJOVERLAY-notification{
position: relative;
background-color: white;
margin-bottom: 10px;
border-radius: 4px;
box-sizing: border-box;
padding: 8px 16px;
box-shadow: 0 0 1px 2px rgba(0, 0, 0, 0.2);
}
import m from 'mithril'
import {pj} from '../utils'
const Contact = {
view: vnode => {
const info = vnode.attrs.info
return m(pj('.contact'), {
onclick: e => {
vnode.attrs.onclick(info)
}
},
m('strong', info.fullname),
' (' + info.email + ')',
m(pj('.muted'), info.contact_for)
)
}
}
export default function ContactPopup(init){
var dom = null
const removeFn = init.attrs.removeFn
function clickOutside(e){
if (!dom.contains(e.target)) removeFn()
m.redraw()
}
return {
onbeforeremove: vnode => {
dom.classList.add('PJOVERLAY-slideOutDown')
return new Promise(r => {
dom.addEventListener('animationend', r)
})
},
view: (vnode)=>m(pj('.contacts.animated.slideInUp'), {
oncreate: vnode => {
dom = vnode.dom
document.addEventListener('click', clickOutside)
},
onremove: vnode => {
document.removeEventListener('click', clickOutside)
}
},
m('h4', 'Request Support'),
vnode.attrs.contacts.map(contact=>m(Contact, {
info: contact,
onclick: vnode.attrs.clickContact
}))
)
}
}
......@@ -13,7 +13,7 @@ const Overlay = function() {
children = v.children
// Append a container to the end of body
dom = document.createElement('div')
dom.className = 'overlay'
dom.className = 'pj-overlay'
dom.setAttribute('data-html2canvas-ignore', true)
document.body.appendChild(dom)
m.mount(dom, OverlayContainer)
......@@ -46,7 +46,6 @@ const Modal = function(v) {
m.redraw()
}
}
return {
view({attrs: {title, content, buttons, onClose}}) {
if (clickedId != null) {
......@@ -99,4 +98,4 @@ const Modal = function(v) {
}
}
export default Modal
\ No newline at end of file
export default Modal
import m from 'mithril'
export default function Modal(init){
const modal_class = init.attrs.class
const fade_out_class = init.attrs.fade_out_class
const overlay_class = init.attrs.overlay_class
const overlay_fade_out_class = init.attrs.overlay_fade_out_class
const removeFn = init.attrs.removeFn
var dom = null
var overlaydom = null
const clickOutside = e => {
console.log('b')
if(!dom.contains(e.target)) removeFn()
m.redraw()
}
return {
onbeforeremove: vnode => {
dom.classList.add(fade_out_class || 'n-')
overlaydom.classList.add(overlay_fade_out_class || 'n-')
return new Promise(r => {
overlaydom.addEventListener('animationend', r)
})
},
view: vnode => m('div', {
class: overlay_class,
oncreate: vnode => {
overlaydom = vnode.dom
}
},
m('div', {
class: modal_class,
oncreate: vnode => {
dom = vnode.dom
document.addEventListener('click', clickOutside)
},
onremove: vnode => {
document.removeEventListener('click', clickOutside)
}
}, vnode.children)
)
}
}
import m from 'mithril';
import {getCookie, setCookie} from './utils.js';
import {pj, getCookie, setCookie, getBrowser} from './utils.js';
import Modal from './components/modal'
import nModal from './components/newmodal'
import ContactList from './components/contactlist'
import html2canvas from 'html2canvas';
const baseURL = "http://pygmy.uwat.ca:8004"
import './base.css'
const context = JSON.parse("{{js_context|safe|escapejs}}")
const baseURL = context.base_url
function addCss(url){
var elm = document.createElement('link')
elm.setAttribute('rel', 'stylesheet')
elm.setAttribute('href', url)
document.head.appendChild(elm)
}
function getBrowser() {
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
var isFirefox = typeof InstallTrigger !== 'undefined';
var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));
var isIE = /*@cc_on!@*/false || !!document.documentMode;
var isEdge = !isIE && !!window.StyleMedia;
var isChrome = !!window.chrome;
var isBlink = (isChrome || isOpera) && !!window.CSS;
var output = isFirefox ? 'Firefox' :
isChrome ? 'Chrome' :
isSafari ? 'Safari' :
isOpera ? 'Opera' :
isIE ? 'IE' :
isEdge ? 'Edge' :
isBlink ? 'Blink' :
'Unknown';
return output
}
const State = {
data: null,
selected_contact: null,
contactlist: false,
// Delete
mail_modal: false,
selected_contact_name: null,
selected_contact_email: null,
......@@ -62,49 +40,23 @@ const Actions = {
State.data.notices = State.data.notices.filter(function(x){
return x.id != notice.id
})
},
selectContact: function(info){
State.contactlist = false
State.selected_contact = info
}
}
const HelpBall = function(init){
var is_open = false
return {
view: function(vnode){
return m('.pjoverlay-help-ball', {
class: is_open && 'is_open',
onclick: function(){
if (!is_open){
is_open = true
}
},
onmouseleave: function(){
if (is_open){
is_open = false
}
}
}, !is_open ? '?' : m('.pjoverlay-contents', [
m('.pjoverlay-hbhead', 'CONTACTS'),
State.data.contacts.map(function(info){
return m('.pjoverlay-hbcard', {
onclick: () => {
State.mail_modal = true,
State.selected_contact_name = info.fullname
State.selected_contact_email = info.email
}
},[
m('.pjoverlay-hbcontact_for', info.contact_for + ':'),
m('.pjoverlay-hbfullname', info.fullname),
m('.pjoverlay-hbemail', info.email),
])
})
]))
}
}
const HelpBall = {
view: vnode => m(pj('.help-ball'), {
onclick: e=>{State.contactlist = true}
}, '?')
}
const Notification = function(init){
var info = init.attrs.info
var timeout = null
var time = 1000 * (5 + (5 * init.attrs.index))
var time = 1000 * (15 + (5 * init.attrs.index))
return {
oncreate: function(vnode){
......@@ -115,14 +67,14 @@ const Notification = function(init){
}, time)
},
view: function(vnode){
return m('.pjoverlay-notifcontainer', [
m('button', {
return m(pj('.notification'), [
m(pj('.closebutton'), {
onclick: () => {
Actions.deleteNotification(info)
}
}, 'x'),
m('.pjoverlay-notiftitle', info.title),
m('.pjoverlay-notifcontent', info.content)
m('p', m('b[style="font-size:120%;"]', info.title)),
info.content.split('\n').map(x=>m('p', x))
])
}
}
......@@ -131,7 +83,7 @@ const Notification = function(init){
const Notifications = function(init){
return {
view: function(vnode){
return m('.pjoverlay-notification_list', [
return m(pj('.notification-list'), [
State.data.notices.map(function(info, i){
return m(
Notification, {info: info, key: info.id, index: i})
......@@ -144,38 +96,71 @@ const Notifications = function(init){
const Form = function(){
var form = null
var screenshot = null
var sending = false
return {
view: function(vnode){
return m('form', {
return [
sending && m(pj('.modal-cover'), m('div', m('h4', 'Sending...'), m(pj('.dual-ring')))),
m(pj('span.closebutton'), {onclick: ()=>{State.selected_contact=null}}, m.trust('×')),
m(pj('form.form'), {
oncreate: function(vnode){
form = vnode.dom
console.log(form)
}
}, [
m('div.name', [
m('span', 'Name:'),
m('h4', 'Request Support from ', State.selected_contact.fullname),
m('p', m('em',
'(You may also contact this person manually via ',
m('a', {href: 'mailto:'+State.selected_contact.email}, State.selected_contact.email),
')'
)),
m('p', 'This process will send an email to ',
State.selected_contact.fullname,
'. Please provide accurate information below to help resolve your issue quicker.'
),
m('div', [
m('span', 'Your Name:'),
m('br'),
m('input[type="text"][name="name"]'),
m('br'),
]),
m('div.email', [
m('span', 'Email:'),
m('div', [
m('span', 'Your Email Address:'),
m('br'),
m('input[type="text"][name="email"]'),
m('br'),
]),
m('div.comment', [
m('span', 'Comment:'),
m('div', [
m('span', 'Describe your Issue:'),
m('br'),
m('textarea#comment[rows="8"][name="comment"]',),
m('br'),
]),
m('hr'),
m('p', 'To assist in resolving your issue, the following information will ',
m('strong', 'automatically'), ' be added to the message:'),
m('ul',
m('li', 'Your IP address'),
m('li', 'You web browser + version'),
m('li', 'the current URL'),
m('li', 'A screen-capture of this page (only within your browser)'),
),
m('input[type="button"][value="Send"]', {
onclick: function(){
html2canvas(document.body).then(function(canvas) {
sending = true