More mobile development
This commit is contained in:
parent
77f8772be8
commit
485be935f3
@ -45,3 +45,5 @@ rochal:slimscroll
|
||||
meteorhacks:sikka
|
||||
mrt:jquery-ui
|
||||
rajit:bootstrap3-datepicker
|
||||
hammer:hammer@=2.0.4_1
|
||||
velocityjs:velocityjs
|
||||
|
||||
@ -48,6 +48,7 @@ fastclick@1.0.13
|
||||
fortawesome:fontawesome@4.7.0
|
||||
geojson-utils@1.0.10
|
||||
google@1.1.15
|
||||
hammer:hammer@2.0.4_1
|
||||
hot-code-push@1.0.4
|
||||
html-tools@1.0.11
|
||||
htmljs@1.0.11
|
||||
@ -127,6 +128,7 @@ tracker@1.1.1
|
||||
ui@1.0.12
|
||||
underscore@1.0.10
|
||||
url@1.0.11
|
||||
velocityjs:velocityjs@1.2.1
|
||||
webapp@1.3.12
|
||||
webapp-hashing@1.0.9
|
||||
yogiben:admin-edit@1.2.8
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<head>
|
||||
<title>Hourglass</title>
|
||||
<link rel="icon" href="/favicon.ico?v=2">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
|
||||
</head>
|
||||
|
||||
<template name="main">
|
||||
@ -68,7 +69,7 @@
|
||||
</div>
|
||||
|
||||
<div class="overlay">
|
||||
<div id="editWork" style="width:{{screen '.5'}};max-width:{{screen '.5'}}">
|
||||
<div id="editWork" style="width:40%;max-width:40%">
|
||||
<div id="editWorkCont" style="background-color:{{divColor 'mainColor'}};border-top:10px solid {{work 'typeColor'}};">
|
||||
<div id="workInfoContainer">
|
||||
{{#if inRole}}
|
||||
|
||||
@ -279,6 +279,7 @@ Template.main.helpers({
|
||||
},
|
||||
inRole() { // Checks correct permissions.
|
||||
if(Session.equals("currentWork",null)) return;
|
||||
try {
|
||||
var thisWork = work.findOne({
|
||||
_id: Session.get("currentWork")._id
|
||||
});
|
||||
@ -295,6 +296,7 @@ Template.main.helpers({
|
||||
currClass.banned.indexOf(Meteor.userId()) !== -1
|
||||
) return true;
|
||||
}
|
||||
} catch(err) {}
|
||||
},
|
||||
admin() {
|
||||
return Roles.userIsInRole(Meteor.userId(), ['admin', 'superadmin']);
|
||||
@ -615,7 +617,6 @@ Template.main.events({
|
||||
serverData = Session.get("currentWork");
|
||||
if(checkMissing()) return;
|
||||
sendData("createWork");
|
||||
Session.set("newWork",false);
|
||||
$(".overlay").fadeOut(150);
|
||||
},
|
||||
'click #workDelete' () {
|
||||
@ -780,6 +781,7 @@ function toDate(date) { // Turns formatted date back to Date constructor.
|
||||
}
|
||||
|
||||
function formReadable(input, val) { // Makes work information readable by users.
|
||||
try {
|
||||
switch (val) {
|
||||
case "typeColor":
|
||||
return input.typeColor = workColors[input.type];
|
||||
@ -862,6 +864,7 @@ function formReadable(input, val) { // Makes work information readable by users.
|
||||
_id: input.creator
|
||||
}).profile.name;
|
||||
}
|
||||
} catch(err){}
|
||||
}
|
||||
|
||||
checkComplete = function(required, inputs) {
|
||||
|
||||
@ -1,37 +1,204 @@
|
||||
#mobileHeader {
|
||||
box-shadow: -1px 2px 2px 1px #444;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#mobileHeader h2 {
|
||||
font-size: 3vh;
|
||||
font-weight: 200;
|
||||
|
||||
padding: 0;
|
||||
height: 6vh;
|
||||
height: 8vh;
|
||||
|
||||
display: inline;
|
||||
|
||||
line-height: 6vh;
|
||||
line-height: 8vh;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#mobileHeader .fa-bars {
|
||||
height: 6vh;
|
||||
margin-left: 1vh;
|
||||
height: 8vh;
|
||||
border: 0;
|
||||
line-height: 8vh;
|
||||
}
|
||||
|
||||
#mobileBody {
|
||||
width: 100%;
|
||||
height: 94vh;
|
||||
height: 92vh;
|
||||
margin-bottom: 10%;
|
||||
background-color: #111;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.mClassContainer {
|
||||
border-bottom: 1px solid #AAA;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mobileClass {
|
||||
width: 100%;
|
||||
height: 10vh;
|
||||
border-bottom: 1px solid #AAA;
|
||||
height: 20vw;
|
||||
z-index: 30;
|
||||
}
|
||||
|
||||
.mClassContainer:last-child {
|
||||
margin-bottom: 20vw;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.mobileType {
|
||||
width: 2vw;
|
||||
height: 100%;
|
||||
|
||||
display: inline-block;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mobileClassContent {
|
||||
padding: 2vh;
|
||||
width: 88vw;
|
||||
height: 12vw;
|
||||
padding: 4vw;
|
||||
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mobileClassContent h4 {
|
||||
font-size: 3vh;
|
||||
|
||||
font-size: 5vw;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.minorHeader {
|
||||
font-size: 4vw !important;
|
||||
width: 100%;
|
||||
padding: 2%;
|
||||
background-color: rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
.mContTop {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mName {
|
||||
font-size: 4.3vw !important;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.mDate {
|
||||
font-size: 3.4vw !important;
|
||||
width: 48%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mClass {
|
||||
font-size: 3.5vw !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mDesc {
|
||||
font-size: 3.4vw !important;
|
||||
color: #BBB;
|
||||
}
|
||||
|
||||
#mAddWork {
|
||||
width: 13vw;
|
||||
height: 13vw;
|
||||
position: absolute;
|
||||
bottom: 6vw;
|
||||
right: 6vw;
|
||||
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
|
||||
background-color: rgb(255, 26, 26);
|
||||
-webkit-filter: drop-shadow(3px 4px 4px #111);
|
||||
filter: drop-shadow(3px 4px 4px #111);
|
||||
}
|
||||
|
||||
#mAddWork .fa {
|
||||
font-size: 5vw;
|
||||
margin-left: 4.25vw;
|
||||
margin-top: 4vw;
|
||||
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.mUndo {
|
||||
font-size: 4vw;
|
||||
width: 13vw;
|
||||
height: 13vw;
|
||||
|
||||
background-color: rgb(17,17,17);
|
||||
|
||||
display: none;
|
||||
opacity: 0;
|
||||
|
||||
position: absolute;
|
||||
top: 3.75vw;
|
||||
right: 4vw;
|
||||
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mUndo .fa {
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
|
||||
text-align: center;
|
||||
line-height: 9vw;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mUndo p {
|
||||
font-size: 3vw;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
margin: 0;
|
||||
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mUndoText {
|
||||
font-size: 4vw !important;
|
||||
height: 13vw;
|
||||
|
||||
display: none;
|
||||
opacity: 0;
|
||||
|
||||
position: absolute;
|
||||
top: 3.75vw;
|
||||
left: 8vw;
|
||||
|
||||
line-height: 13vw;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#mOverlay {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#mSidebar {
|
||||
height: 100%;
|
||||
width: 85%;
|
||||
|
||||
background-color: #fff;
|
||||
box-shadow: 2px 0px 1px 1px #222;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
@ -4,15 +4,56 @@
|
||||
<i class="fa fa-bars" style="color:{{iconStatus}}" aria-hidden="true"></i>
|
||||
<h2>{{schoolName}}</h2>
|
||||
</header>
|
||||
<div id="mobileBody" style="background-color:{{divColor 'secondaryColor'}}">
|
||||
<div id="mobileBody">
|
||||
{{#if showMode 'main'}}
|
||||
<h4 class="minorHeader">Main</h4>
|
||||
{{#each myWork}}
|
||||
<div class="mobileClass">
|
||||
<div class="mobileType"></div>
|
||||
<div class="mobileClassContent">
|
||||
<h4>{{name}}</h4>
|
||||
</div>
|
||||
</div>
|
||||
{{> mobileClass}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
{{#if showMode 'done'}}
|
||||
<h4 class="minorHeader">Done</h4>
|
||||
{{#each myWork "done"}}
|
||||
{{> mobileClass}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
{{#if showMode 'addWork'}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div id="mAddWork">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div id="mOverlay">
|
||||
<div id="mSidebar">
|
||||
<div class="mSectionTitle">
|
||||
<div class="mStatus" style="background-color:{{modeStatus 'main'}}"></div>
|
||||
<i class="fa fa-list-ul" aria-hidden="true"></i>
|
||||
<h4>Create Classes</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="mobileClass">
|
||||
<div class="mClassContainer" workid="{{_id}}">
|
||||
{{#if isDone}}
|
||||
<h4 class="mUndoText" workid="{{_id}}">Unmarked as done!</h4>
|
||||
{{else}}
|
||||
<h4 class="mUndoText" workid="{{_id}}">Marked as done!</h4>
|
||||
{{/if}}
|
||||
<div class="mUndo" workid="{{_id}}">
|
||||
<i class="fa fa-undo" aria-hidden="true"></i>
|
||||
<p>Undo</p>
|
||||
</div>
|
||||
<div class="mobileClass" style="background-color:{{divColor 'secondaryColor'}}" workid="{{_id}}">
|
||||
<div class="mobileType" style="background-color:{{typeColor}}"></div>
|
||||
<div class="mobileClassContent">
|
||||
<h4 class="mName">{{name}}</h4>
|
||||
<h4 class="mDate">{{dueDate}}</h4>
|
||||
<h4 class="mClass">{{class}}</h4>
|
||||
<h4 class="mDesc">{{shortdesc}}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -1,7 +1,23 @@
|
||||
Session.set("mobileWork", []);
|
||||
Session.set("mobileMode", "main");
|
||||
|
||||
Template.mobile.rendered = function() {
|
||||
document.getElementsByTagName("body")[0].style.color = Session.get("user").preferences.theme.textColor;
|
||||
|
||||
addListeners();
|
||||
|
||||
addMobileButton($("#mAddWork")[0], 50, function() {
|
||||
$("#mAddWork").velocity("fadeOut", 200);
|
||||
$("#mobileBody").velocity("fadeOut", {
|
||||
duration: 200,
|
||||
complete: function() {
|
||||
Session.set("mobileMode", "addWork");
|
||||
$("#mobileBody").velocity("fadeIn", 200);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Template.mobile.helpers({
|
||||
@ -12,15 +28,147 @@ Template.mobile.helpers({
|
||||
iconStatus() {
|
||||
return (Session.get("sidebarMode") === "mobile") ? Session.get("user").preferences.theme.iconHighlight : "";
|
||||
},
|
||||
myWork() {
|
||||
myWork(done) {
|
||||
var array = myClasses();
|
||||
var allWork = [];
|
||||
var notDoneWork = [];
|
||||
var doneWork = [];
|
||||
for(var i = 0; i < array.length; i++) {
|
||||
for(var j = 0; j < array[i].thisClassWork.length; j++) {
|
||||
allWork.push(array[i].thisClassWork[j]);
|
||||
var classid = array[i].thisClassWork[j].classid;
|
||||
var desc = array[i].thisClassWork[j].description;
|
||||
if(desc) {
|
||||
array[i].thisClassWork[j].shortdesc = (desc.length <= 40 ) ? desc : desc.substring(0,40) +"...";
|
||||
}
|
||||
array[i].thisClassWork[j]["class"] = (classid === Meteor.userId()) ? "Personal" : classes.findOne({_id:classid}).name;
|
||||
if(_.contains(array[i].thisClassWork[j].done, Meteor.userId())) {
|
||||
array[i].thisClassWork[j].isDone = true;
|
||||
doneWork.push(array[i].thisClassWork[j]);
|
||||
} else {
|
||||
notDoneWork.push(array[i].thisClassWork[j]);
|
||||
}
|
||||
}
|
||||
Session.set("mobileWork", allWork);
|
||||
return allWork;
|
||||
}
|
||||
doneWork = doneWork.sort(function(a,b) {
|
||||
return Date.parse(a.realDate) - Date.parse(b.realDate);
|
||||
});
|
||||
notDoneWork = notDoneWork.sort(function(a,b) {
|
||||
return Date.parse(a.realDate) - Date.parse(b.realDate);
|
||||
});
|
||||
|
||||
Session.set("mobileWork", [notDoneWork, doneWork]);
|
||||
return (done === "done") ? Session.get("mobileWork")[1] : Session.get("mobileWork")[0];
|
||||
},
|
||||
showMode(mode) {
|
||||
return Session.equals("mobileMode", mode);
|
||||
},
|
||||
modeStatus(mode) {
|
||||
return (Session.equals("mobileMode", mode)) ? Session.get("user").preferences.theme.modeHighlight : "rgba(0,0,0,0)";
|
||||
}
|
||||
});
|
||||
|
||||
function addListeners() {
|
||||
var deltaX = 0;
|
||||
var clearTile;
|
||||
for(var i = 0; i < $(".mClassContainer").length; i++) {
|
||||
let id = $(".mClassContainer")[i].getAttribute("workid");
|
||||
new Hammer($(".mobileClass")[i], {
|
||||
domEvents: true
|
||||
});
|
||||
|
||||
$(".mobileClass[workid="+id+"]").on('panmove', function(e) {
|
||||
var dX = deltaX + (e.originalEvent.gesture.deltaX);
|
||||
if(dX < 0) {
|
||||
$.Velocity.hook(jQuery(e.target), 'translateX', dX/45 + 'px');
|
||||
} else {
|
||||
$.Velocity.hook(jQuery(e.target), 'translateX', dX + 'px');
|
||||
}
|
||||
|
||||
});
|
||||
$(".mobileClass[workid="+id+"]").on('panend', function(e) {
|
||||
if(e.target === document.getElementById("mobileBody")) return;
|
||||
deltaX = deltaX + (e.originalEvent.gesture.deltaX);
|
||||
if(deltaX >= window.innerWidth * 0.5) {
|
||||
deltaX = 0;
|
||||
jQuery(e.target).velocity(
|
||||
{
|
||||
translateX: window.innerWidth*1.2+"px"
|
||||
},
|
||||
{
|
||||
duration: 150,
|
||||
complete: function() {
|
||||
$(".mUndoText[workid="+id+"]").velocity("fadeIn", {duration: 300});
|
||||
$(".mUndo[workid="+id+"]").velocity("fadeIn", {duration: 300});
|
||||
var container = $(".mClassContainer[workid="+id+"]");
|
||||
clearTile = setTimeout(function() {
|
||||
container.velocity(
|
||||
{
|
||||
height: 0
|
||||
},
|
||||
{
|
||||
duration: 200,
|
||||
complete: function() {
|
||||
serverData = [container[0].getAttribute("workid"), "done"];
|
||||
sendData("toggleWork");
|
||||
container.remove();
|
||||
}
|
||||
});
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
deltaX = 0;
|
||||
jQuery(e.target).velocity({translateX: "0px"},300);
|
||||
}
|
||||
});
|
||||
|
||||
addMobileButton($(".mUndo[workid="+id+"]")[0], 30, function() {
|
||||
clearTimeout(clearTile);
|
||||
$(".mobileClass[workid="+id+"]").velocity({translateX: "0px"},300);
|
||||
$(".mUndoText[workid="+id+"]").velocity("fadeOut", {duration: 300});
|
||||
$(".mUndo[workid="+id+"]").velocity("fadeOut", {duration: 300});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addMobileButton(element, lighten, thisFunction) {
|
||||
let button = new Hammer.Manager(element);
|
||||
let add = lighten;
|
||||
let ele = jQuery(element);
|
||||
let execute = thisFunction;
|
||||
let colors = [
|
||||
parseFloat($.Velocity.hook(ele, "backgroundColorRed")),
|
||||
parseFloat($.Velocity.hook(ele, "backgroundColorGreen")),
|
||||
parseFloat($.Velocity.hook(ele, "backgroundColorBlue"))
|
||||
];
|
||||
var press = new Hammer.Press({
|
||||
event: 'press',
|
||||
pointers: 1,
|
||||
time: 0.01,
|
||||
threshold: 3000
|
||||
});
|
||||
|
||||
button.add(press);
|
||||
|
||||
button.on('press', function(e) {
|
||||
ele.velocity(
|
||||
{
|
||||
backgroundColorRed: colors[0] + add,
|
||||
backgroundColorGreen: colors[1] + add,
|
||||
backgroundColorBlue: colors[2] + add,
|
||||
},100);
|
||||
});
|
||||
button.on('pressup', function(e) {
|
||||
ele.velocity("stop");
|
||||
ele.velocity(
|
||||
{
|
||||
backgroundColorRed: colors[0],
|
||||
backgroundColorGreen: colors[1],
|
||||
backgroundColorBlue: colors[2],
|
||||
},
|
||||
{
|
||||
duration: 200,
|
||||
complete: execute()
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -30,8 +30,8 @@ Router.route('/', {
|
||||
this.redirect('/profile');
|
||||
} else {
|
||||
Session.set("user", Meteor.user().profile);
|
||||
this.render("main");
|
||||
//this.render("mobile");
|
||||
//this.render("main");
|
||||
this.render("mobile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,6 +501,7 @@ Meteor.methods({
|
||||
// Work Functions
|
||||
'createWork': function(input) {
|
||||
input.creator = Meteor.userId();
|
||||
if(input.description) input.description = input.description.trim();
|
||||
work.schema.validate(input);
|
||||
var found = classes.findOne({
|
||||
_id: input.class
|
||||
@ -522,6 +523,7 @@ Meteor.methods({
|
||||
var currentclass = classes.findOne({
|
||||
_id: currentwork.class
|
||||
});
|
||||
if(change.description) change.description = change.description.trim();
|
||||
var security = securityCheck([[1, 16, 13, 5, false], 11, 12, 10, 20, true],
|
||||
Object.assign({}, currentclass || {}, currentwork, {description: change.description, name: change.name, dueDate: change.dueDate, type: change.type}));
|
||||
if (!security) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user