initial commit

This commit is contained in:
Luke Ogburn
2019-03-30 22:43:34 -04:00
commit c4a666e3b6
78 changed files with 5332 additions and 0 deletions

1
res/classes Normal file
View File

@@ -0,0 +1 @@
biology,history,chemistry,english,world_language

16
res/commentSub.php Normal file
View File

@@ -0,0 +1,16 @@
<?php
require $_SERVER['DOCUMENT_ROOT']."/globalFuncs.php";
conn();
$pid = $_GET["post"];
$uid = $current_user;
$cmt = $_POST["comment"];
$cmt = encodeUserLink($cmt, $uid, $pid);
$stmt = $conn->prepare("INSERT INTO comments (post_id, poster_id, text) VALUES (:pid, :uid, :cmt)");
$stmt->bindParam(":pid", $pid);
$stmt->bindParam(":uid", $uid);
$stmt->bindParam(":cmt", $cmt);
$result = $stmt->execute();
header("Location: /forum/post/?post=$pid#bottomOfComments");
?>

131
res/comments Normal file
View File

@@ -0,0 +1,131 @@
<?php
//deleting and reporting comments are in the actual post in order to be able to give the affirmative or negative msg on completion or error
$stmt = $conn->prepare("SELECT * FROM comments WHERE post_id = :pid ORDER BY date ASC");
$stmt->bindParam(":pid", $_GET["post"]);
$stmt->execute();
$row = $stmt->fetchAll();
if(isset($_GET["a"])){
conn();
$stmt = $GLOBALS['conn']->prepare("SELECT * FROM alerts WHERE id = :id");
$stmt->bindParam(":id", $_GET["a"]);
$stmt->execute();
$res = $stmt->fetch(PDO::FETCH_OBJ);
if($res->mentionee == $current_user){
alertDelete($_GET["a"]);
}
}
?>
<div class="container card noHover">
<div id=comments>
<div id=commentWriter>
<script>
function getContent(){
document.getElementById("realText").value = document.getElementById("commentEditor").innerHTML;
}
function findPos(obj) {
return obj.getBoundingClientRect().top - obj.clientHeight;
}
function addToCW(text){
document.getElementById("commentEditor").innerHTML = document.getElementById("commentEditor").innerHTML + "@" + text + " ";
document.getElementById("realText").value = document.getElementById("commentEditor").innerHTML;
window.scrollBy(0, findPos(document.getElementById("commentWriter")));
}
</script>
<?php
if(isset($_GET["report"])){
$stmt = $conn->prepare("SELECT * FROM comments WHERE id = :id");
$rid = $_GET["report"];
$stmt->bindParam(":id", $rid);
$stmt->execute();
$comment = $stmt->fetch(PDO::FETCH_OBJ);
$commentID = intval($comment->id);
if($commentID!=""){
$stmt = $conn->prepare("SELECT * FROM comments WHERE id = :id");
$stmt->bindParam(":id", $commentID);
$stmt->execute();
$return = $stmt->fetch(PDO::FETCH_OBJ);
$current = $return->reports;
if(strpos($current, $current_user) === false){
$new = $current.$current_user.",";
$stmt = $conn->prepare("UPDATE comments SET reports = :new WHERE id = :id");
$stmt->bindParam(":new", $new);
$stmt->bindParam(":id", $commentID);
$stmt->execute();
if($stmt){
msg("Comment reported.");
header("Refresh:0");
}else{
msg("Error reporting comment.");
header("Refresh:0");
}
}else{
msg("Your report has already been recorded.");
header("Refresh:0");
}
}
}
if(isset($_GET["reply"])){
$name = getUserInfo($_GET["reply"])->name;
$reply = "&reply=".$_GET["reply"];
$repNotif = "<p style=\"float:left;font-size:1em;margin:0.5em 0.3em;\">(Replying to $name)</p>";
}else{
$reply = $repNotif = "";
}
?>
<form method=POST action=/res/commentSub.php?post=<?=$_GET["post"].$reply; ?>>
<div contentEditable=true id=commentEditor name=commentPsuedo placeholder="Add your ideas" onkeyup=getContent()></div>
<textarea id=realText name=comment style="display:none"></textarea>
<div id=commentWriterButtons>
<?=$repNotif; ?>
<div id=commentSubmitWrapper>
<p id=rulesReminder>Remember: we have <a href="/rules.php" target=_BLANK>rules</a>!</p>
<button id=commentSubmitButton type=submit>SUBMIT</button>
</div>
</div>
</form>
</div>
<!-- submitted comments -->
<div id=submittedComments>
<?php
foreach($row as $comment){
$uname = getUserInfo($comment["poster_id"])->name;
$comment["text"] = decodeUserLink($comment["text"]);
$teacher = getUserInfo($comment["poster_id"])->teacher?"<i class=material-icons>school</i>":"";
if($comment["poster_id"] == $current_user){
$repDel = "<p class=commentReport><a href=?delc=".$comment["id"]."&post=".$_GET['post'].">delete</a></p>";
}else{
$repDel = "<a href=?post=".$_GET['post']."&repc=".$comment["id"]." class=commentReport>report</a>";
}
if($_GET["a"]==$comment['id']){
$a = "current";
echo "<script>document.addEventListener('DOMContentLoaded',function(event) {window.scrollBy(-500,-500);});</script>";
}else{
$a = "";
}
echo "
<div class='comment $a'>
<a name=".$comment['id']."></a>
<div class=commentTop>
<p><a href=/user/?user=".$comment["poster_id"]." class=commentName> ".$uname."</a>".$teacher." <span class=commentTime>".makeDate($comment['date'])."</span></p>
</div>
<div class=commentMiddle>".hyperlink($comment['text'])."</div>
<div class=commentBottom>
".$repDel."
<span class=commentReply onclick=\"addToCW('".$uname."')\">Reply</span>
</div>
</div>";
}
?>
<a name=bottomOfComments></a>
</div>
</div>
</div>

23
res/head Normal file
View File

@@ -0,0 +1,23 @@
<head>
<meta charset=UTF-8>
<title>IB Forum</title>
<link rel=stylesheet type=text/css href=/style.css>
<link rel=stylesheet type=text/css href=/mobile.css>
<?php
if(getUserInfo($current_user)->dark_theme){
echo "<link rel=stylesheet type=text/css href=/darkTheme.css>";
}
?>
<link rel=stylesheet type=text/css href=<?php echo isset($css)?$css:"/unset"; ?>.css>
<link rel=stylesheet type=text/css href=<?php echo isset($css2)?$css2:"/unset"; ?>.css>
<link rel="icon" href="/res/i/favicon.png">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<?php
if(getUserInfo($current_user)->snow){
echo "<script src=/res/snowstorm.js></script>";
}
?>
<meta name="google-signin-client_id" content="107876463917-vju8u1c0m5ceu00v92ejim138gae7ktb.apps.googleusercontent.com">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>

BIN
res/i/clip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
res/i/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
res/i/ham.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

BIN
res/i/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
res/i/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
res/montserrat.ttf Normal file

Binary file not shown.

93
res/notifs Normal file
View File

@@ -0,0 +1,93 @@
<?php
if(isset($_GET["del"])&&verifyUser("admin")){
conn();
$stmt = $conn->prepare("DELETE FROM notices WHERE id = :id");
$stmt->bindParam(":id", $_GET["del"]);
$stmt->execute();
header("Location: /forum");
}
if(isset($_POST["notif"])&&verifyUser("admin")){
conn();
$stmt = $conn->prepare("INSERT INTO notices (text) VALUES (:text)");
$stmt->bindParam(":text", $_POST["notif"]);
$stmt->execute();
unset($_POST["notif"]);
header("Location: /forum");
}
?>
<div id=right>
<div class="card noHover">
<h3 class=notifTitle>NOTIFS</h3>
<p>
<?php
conn();
$stmt = $conn->prepare("SELECT * FROM notices ORDER BY id DESC");
$stmt->execute();
$notices = $stmt->fetchAll();
foreach($notices as $notice){
if(verifyUser("admin")){
$notice = "<p class=notif><a class=deletable href=?del=".$notice['id'].">".$notice["text"]."</a></p>";
}else{
$notice = "<p>".$notice["text"]."</p>";
}
echo $notice;
}
if($notices==NULL){
echo "<i>No notifs.</i>";
}
?>
</p>
</div>
<div class="card noHover">
<h3 class=notifTitle>MENTIONS</h3>
<p>
<?php
conn();
$stmt = $conn->prepare("SELECT * FROM alerts WHERE mentionee = :cu ORDER BY id ASC");
$stmt->bindParam(":cu", $current_user);
$stmt->execute();
$alerts = $stmt->fetchAll();
foreach($alerts as $alert){
echo "<a class=alert href=/forum/post/?a=".$alert['id']."&post=".$alert['post_id']."#".$alert['id'].">".getUserInfo($alert['mentioner'])->name." mentioned you</a>";
}
if($alerts==NULL){
echo "<i>No mentions</i>";
}
?>
</p>
</div>
<?php
if(verifyUser("admin")){
//Reported posts
echo "<div class='card noHover'>
<h3 class=norifTitle>REPORTED POSTS</h3>
";
conn();
$stmt = $conn->prepare("SELECT * FROM forums WHERE reports IS NOT NULL");
$stmt->execute();
$res = $stmt->fetchAll();
foreach($res as $post){
$times = substr_count($post["reports"], ",");
$times = $times==1?"1 time":"$times times";
echo "<p><a class=noStyle href=/admin/portal/reportedPost.php?post=".$post['post_id'].">Post ".$post["post_id"]." has been reported $times</a></p>";
}
if(count($res)==0){
echo "<p><i>Nothing has been reported.</i></p>";
}
echo "</div>";
//Adding notifs
echo"\n<div class='card noHover'>
<h3 class=notifTitle>ADD NOTIFS</h3>
<form method=POST action='' style='width:100%;'>
<input id=notifAdder type=text name=notif placeholder='Press enter to submit' style=color:inherit>
</form>
<br>
<h3 class=notifTitle>DELETE NOTIFS</h3>
<p id=notifAdminMsg>You can delete any notif by clicking on it. Keep in mind that once you click it, it's gone forever. Don't delete something if you aren't sure it should be deleted!<br><br>
Make sure notifs apply to everyone!</p>
</div>";
}
?>
</div>

64
res/randomZone Normal file
View File

@@ -0,0 +1,64 @@
<div class="card noHover">
<h3 class=notifTitle>RANDOM ZONE</h3>
<p>
<?php
$randomArray = [
"You look nice today.",
"You're doing a great job.",
"I hope you're having a good day! You deserve it.",
"Your friends are all rooting for you.",
"Ever noticed that the search bar's words change?",
"I bet giraffes' coffee is cold by the time it gets to its stomach.",
"I saw some guy walking around with a duck the other day.",
"This site is user-based; make sure you contribute!",
"Ever considered buying a boat?",
"We should all go ice-skating over winter break, that would be fun.",
"Remember to take a breath every once in a while.",
"School isn't everything. Take care of yourself.",
"The surface area of an average-sized brick is 79 cm squared.",
"Despite what Mrs. Trickett says, the mitochondria IS the powerhouse of the cell.",
"ATLEE stands for All Trees Like Eating Eggs.",
"I heard that someone has a crush on ".str_replace(str_split(-_), " ", getUserInfo($current_user)->name),
"Left handed people tend to be more artistic.",
"I hope you're not going to leave this site... that literally kills me, you know.",
"Ctrl (or cmd on Mac) + Shift + T reopens your last closed tab.",
"Aliens probably don't go to school.",
"^-^",
"Edelman has a Keurig you can use.",
"Does Santa know when I procrastinate?",
"You're in a coma.<br>We're trying a new technique to get to you.<br>Please wake up.<br>We miss you.",
"The patent for toilet paper shows it going over, not under.",
"Luke Ogburn carries mints in his backpack. Just ask and he'll give you one!",
"Someone ate my pringes :(",
"What if time goes backwards, but we just don't notice because our memories rewind too.",
"You seem like a nice person.",
"The school's layout is based off of that of a prison's.",
"Text someone you like and tell them why you like them. They'll appreciate it.",
"Rice isn't that hard to cook.",
"I wonder if there are any secret passages in the school.",
"Pineapples have neither pines nor apples in them.",
"Fear is information, don't ignore it.",
"If you're hungry, then eat.",
"If you're thirsty, then drink",
"Give yourself time. Butterflies don't form in a day.",
"Ask yourself: What would make me happy today?",
"Beauty shouldn't be pain. Being comfortable will make you happy, which will make you beautiful.",
"The more people use this site, the better it becomes.",
"Onions don't cry when they chop humans.",
"Never trust a plastic hippo.",
"Tabs are just capital spaces.",
"The very existence of socks is proof that shoes don't work.",
"Humans are the only creatures who care about time. Maybe it doesn't matter as much as we think it does.",
"People like you.",
"Chicken is better than turkey and you can't change my mind.",
"You look great today.",
"People are happy when you're happy, because they like you and want you to succeed in life.",
"In dog years, humans regularly live to 800+ years old. They probably think we're immortal or something.",
"If tipping were illegal, wait staff would be paid more and wouldn't neet tips in the first place.",
"I, for one, think that you're a good person."
];
$randomArray = array_filter($randomArray);
echo $randomArray[mt_rand(0, sizeof($randomArray)-1)];
?>
</p>
</div>

BIN
res/roboto.ttf Normal file

Binary file not shown.

7
res/rules Normal file
View File

@@ -0,0 +1,7 @@
<ul>
<li>Don't hurt anyone</li>
<li>Any cheating will be reported</li>
<li>Cyber bullying is still illegal</li>
<li>Be hum</li>
<li>Remember anyone can see your post</li>
<li>Just be sensible</li>

666
res/snowstorm.js Normal file
View File

@@ -0,0 +1,666 @@
/** @license
* DHTML Snowstorm! JavaScript-based snow for web pages
* Making it snow on the internets since 2003. You're welcome.
* -----------------------------------------------------------
* Version 1.44.20131208 (Previous rev: 1.44.20131125)
* Copyright (c) 2007, Scott Schiller. All rights reserved.
* Code provided under the BSD License
* http://schillmania.com/projects/snowstorm/license.txt
*/
/*jslint nomen: true, plusplus: true, sloppy: true, vars: true, white: true */
/*global window, document, navigator, clearInterval, setInterval */
var snowStorm = (function(window, document) {
// --- common properties ---
this.autoStart = true; // Whether the snow should start automatically or not.
this.excludeMobile = true; // Snow is likely to be bad news for mobile phones' CPUs (and batteries.) Enable at your own risk.
this.flakesMax = 128; // Limit total amount of snow made (falling + sticking)
this.flakesMaxActive = 64; // Limit amount of snow falling at once (less = lower CPU use)
this.animationInterval = 33; // Theoretical "miliseconds per frame" measurement. 20 = fast + smooth, but high CPU use. 50 = more conservative, but slower
this.useGPU = true; // Enable transform-based hardware acceleration, reduce CPU load.
this.className = null; // CSS class name for further customization on snow elements
this.excludeMobile = true; // Snow is likely to be bad news for mobile phones' CPUs (and batteries.) By default, be nice.
this.flakeBottom = null; // Integer for Y axis snow limit, 0 or null for "full-screen" snow effect
this.followMouse = false; // Snow movement can respond to the user's mouse
this.snowColor = '#aaf'; // Don't eat (or use?) yellow snow.
this.snowCharacter = '&bull;'; // &bull; = bullet, &middot; is square on some systems etc.
this.snowStick = true; // Whether or not snow should "stick" at the bottom. When off, will never collect.
this.targetElement = null; // element which snow will be appended to (null = document.body) - can be an element ID eg. 'myDiv', or a DOM node reference
this.useMeltEffect = true; // When recycling fallen snow (or rarely, when falling), have it "melt" and fade out if browser supports it
this.useTwinkleEffect = false; // Allow snow to randomly "flicker" in and out of view while falling
this.usePositionFixed = true; // true = snow does not shift vertically when scrolling. May increase CPU load, disabled by default - if enabled, used only where supported
this.usePixelPosition = false; // Whether to use pixel values for snow top/left vs. percentages. Auto-enabled if body is position:relative or targetElement is specified.
// --- less-used bits ---
this.freezeOnBlur = true; // Only snow when the window is in focus (foreground.) Saves CPU.
this.flakeLeftOffset = 0; // Left margin/gutter space on edge of container (eg. browser window.) Bump up these values if seeing horizontal scrollbars.
this.flakeRightOffset = 0; // Right margin/gutter space on edge of container
this.flakeWidth = 8; // Max pixel width reserved for snow element
this.flakeHeight = 8; // Max pixel height reserved for snow element
this.vMaxX = 3; // Maximum X velocity range for snow
this.vMaxY = 3; // Maximum Y velocity range for snow
this.zIndex = -1; // CSS stacking order applied to each snowflake
// --- "No user-serviceable parts inside" past this point, yadda yadda ---
var storm = this,
features,
// UA sniffing and backCompat rendering mode checks for fixed position, etc.
isIE = navigator.userAgent.match(/msie/i),
isIE6 = navigator.userAgent.match(/msie 6/i),
isMobile = navigator.userAgent.match(/mobile|opera m(ob|in)/i),
isBackCompatIE = (isIE && document.compatMode === 'BackCompat'),
noFixed = (isBackCompatIE || isIE6),
screenX = null, screenX2 = null, screenY = null, scrollY = null, docHeight = null, vRndX = null, vRndY = null,
windOffset = 1,
windMultiplier = 1, //used to be 2
flakeTypes = 6,
fixedForEverything = false,
targetElementIsRelative = false,
opacitySupported = (function(){
try {
document.createElement('div').style.opacity = '0.9';
} catch(e) {
return false;
}
return true;
}()),
didInit = false,
docFrag = document.createDocumentFragment();
features = (function() {
var getAnimationFrame;
/**
* hat tip: paul irish
* http://paulirish.com/2011/requestanimationframe-for-smart-animating/
* https://gist.github.com/838785
*/
function timeoutShim(callback) {
window.setTimeout(callback, 1000/(storm.animationInterval || 20));
}
var _animationFrame = (window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
timeoutShim);
// apply to window, avoid "illegal invocation" errors in Chrome
getAnimationFrame = _animationFrame ? function() {
return _animationFrame.apply(window, arguments);
} : null;
var testDiv;
testDiv = document.createElement('div');
function has(prop) {
// test for feature support
var result = testDiv.style[prop];
return (result !== undefined ? prop : null);
}
// note local scope.
var localFeatures = {
transform: {
ie: has('-ms-transform'),
moz: has('MozTransform'),
opera: has('OTransform'),
webkit: has('webkitTransform'),
w3: has('transform'),
prop: null // the normalized property value
},
getAnimationFrame: getAnimationFrame
};
localFeatures.transform.prop = (
localFeatures.transform.w3 ||
localFeatures.transform.moz ||
localFeatures.transform.webkit ||
localFeatures.transform.ie ||
localFeatures.transform.opera
);
testDiv = null;
return localFeatures;
}());
this.timer = null;
this.flakes = [];
this.disabled = false;
this.active = false;
this.meltFrameCount = 20;
this.meltFrames = [];
this.setXY = function(o, x, y) {
if (!o) {
return false;
}
if (storm.usePixelPosition || targetElementIsRelative) {
o.style.left = (x - storm.flakeWidth) + 'px';
o.style.top = (y - storm.flakeHeight) + 'px';
} else if (noFixed) {
o.style.right = (100-(x/screenX*100)) + '%';
// avoid creating vertical scrollbars
o.style.top = (Math.min(y, docHeight-storm.flakeHeight)) + 'px';
} else {
if (!storm.flakeBottom) {
// if not using a fixed bottom coordinate...
o.style.right = (100-(x/screenX*100)) + '%';
o.style.bottom = (100-(y/screenY*100)) + '%';
} else {
// absolute top.
o.style.right = (100-(x/screenX*100)) + '%';
o.style.top = (Math.min(y, docHeight-storm.flakeHeight)) + 'px';
}
}
};
this.events = (function() {
var old = (!window.addEventListener && window.attachEvent), slice = Array.prototype.slice,
evt = {
add: (old?'attachEvent':'addEventListener'),
remove: (old?'detachEvent':'removeEventListener')
};
function getArgs(oArgs) {
var args = slice.call(oArgs), len = args.length;
if (old) {
args[1] = 'on' + args[1]; // prefix
if (len > 3) {
args.pop(); // no capture
}
} else if (len === 3) {
args.push(false);
}
return args;
}
function apply(args, sType) {
var element = args.shift(),
method = [evt[sType]];
if (old) {
element[method](args[0], args[1]);
} else {
element[method].apply(element, args);
}
}
function addEvent() {
apply(getArgs(arguments), 'add');
}
function removeEvent() {
apply(getArgs(arguments), 'remove');
}
return {
add: addEvent,
remove: removeEvent
};
}());
function rnd(n,min) {
if (isNaN(min)) {
min = 0;
}
return (Math.random()*n)+min;
}
function plusMinus(n) {
return (parseInt(rnd(2),10)===1?n*-1:n);
}
this.randomizeWind = function() {
var i;
vRndX = plusMinus(rnd(storm.vMaxX,0.2));
vRndY = rnd(storm.vMaxY,0.2);
if (this.flakes) {
for (i=0; i<this.flakes.length; i++) {
if (this.flakes[i].active) {
this.flakes[i].setVelocities();
}
}
}
};
this.scrollHandler = function() {
var i;
// "attach" snowflakes to bottom of window if no absolute bottom value was given
scrollY = (storm.flakeBottom ? 0 : parseInt(window.scrollY || document.documentElement.scrollTop || (noFixed ? document.body.scrollTop : 0), 10));
if (isNaN(scrollY)) {
scrollY = 0; // Netscape 6 scroll fix
}
if (!fixedForEverything && !storm.flakeBottom && storm.flakes) {
for (i=0; i<storm.flakes.length; i++) {
if (storm.flakes[i].active === 0) {
storm.flakes[i].stick();
}
}
}
};
this.resizeHandler = function() {
if (window.innerWidth || window.innerHeight) {
screenX = window.innerWidth - 16 - storm.flakeRightOffset;
screenY = (storm.flakeBottom || window.innerHeight);
} else {
screenX = (document.documentElement.clientWidth || document.body.clientWidth || document.body.scrollWidth) - (!isIE ? 8 : 0) - storm.flakeRightOffset;
screenY = storm.flakeBottom || document.documentElement.clientHeight || document.body.clientHeight || document.body.scrollHeight;
}
docHeight = document.body.offsetHeight;
screenX2 = parseInt(screenX/2,10);
};
this.resizeHandlerAlt = function() {
screenX = storm.targetElement.offsetWidth - storm.flakeRightOffset;
screenY = storm.flakeBottom || storm.targetElement.offsetHeight;
screenX2 = parseInt(screenX/2,10);
docHeight = document.body.offsetHeight;
};
this.freeze = function() {
// pause animation
if (!storm.disabled) {
storm.disabled = 1;
} else {
return false;
}
storm.timer = null;
};
this.resume = function() {
if (storm.disabled) {
storm.disabled = 0;
} else {
return false;
}
storm.timerInit();
};
this.toggleSnow = function() {
if (!storm.flakes.length) {
// first run
storm.start();
} else {
storm.active = !storm.active;
if (storm.active) {
storm.show();
storm.resume();
} else {
storm.stop();
storm.freeze();
}
}
};
this.stop = function() {
var i;
this.freeze();
for (i=0; i<this.flakes.length; i++) {
this.flakes[i].o.style.display = 'none';
}
storm.events.remove(window,'scroll',storm.scrollHandler);
storm.events.remove(window,'resize',storm.resizeHandler);
if (storm.freezeOnBlur) {
if (isIE) {
storm.events.remove(document,'focusout',storm.freeze);
storm.events.remove(document,'focusin',storm.resume);
} else {
storm.events.remove(window,'blur',storm.freeze);
storm.events.remove(window,'focus',storm.resume);
}
}
};
this.show = function() {
var i;
for (i=0; i<this.flakes.length; i++) {
this.flakes[i].o.style.display = 'block';
}
};
this.SnowFlake = function(type,x,y) {
var s = this;
this.type = type;
this.x = x||parseInt(rnd(screenX-20),10);
this.y = (!isNaN(y)?y:-rnd(screenY)-12);
this.vX = null;
this.vY = null;
this.vAmpTypes = [1,1.2,1.4,1.6,1.8]; // "amplification" for vX/vY (based on flake size/type)
this.vAmp = this.vAmpTypes[this.type] || 1;
this.melting = false;
this.meltFrameCount = storm.meltFrameCount;
this.meltFrames = storm.meltFrames;
this.meltFrame = 0;
this.twinkleFrame = 0;
this.active = 1;
this.fontSize = (10+(this.type/5)*10);
this.o = document.createElement('div');
this.o.innerHTML = storm.snowCharacter;
if (storm.className) {
this.o.setAttribute('class', storm.className);
}
this.o.style.color = storm.snowColor;
this.o.style.position = (fixedForEverything?'fixed':'absolute');
if (storm.useGPU && features.transform.prop) {
// GPU-accelerated snow.
this.o.style[features.transform.prop] = 'translate3d(0px, 0px, 0px)';
}
this.o.style.width = storm.flakeWidth+'px';
this.o.style.height = storm.flakeHeight+'px';
this.o.style.fontFamily = 'arial,verdana';
this.o.style.cursor = 'default';
this.o.style.overflow = 'hidden';
this.o.style.fontWeight = 'normal';
this.o.style.zIndex = storm.zIndex;
docFrag.appendChild(this.o);
this.refresh = function() {
if (isNaN(s.x) || isNaN(s.y)) {
// safety check
return false;
}
storm.setXY(s.o, s.x, s.y);
};
this.stick = function() {
if (noFixed || (storm.targetElement !== document.documentElement && storm.targetElement !== document.body)) {
s.o.style.top = (screenY+scrollY-storm.flakeHeight)+'px';
} else if (storm.flakeBottom) {
s.o.style.top = storm.flakeBottom+'px';
} else {
s.o.style.display = 'none';
s.o.style.bottom = '0%';
s.o.style.position = 'fixed';
s.o.style.display = 'block';
}
};
this.vCheck = function() {
if (s.vX>=0 && s.vX<0.2) {
s.vX = 0.2;
} else if (s.vX<0 && s.vX>-0.2) {
s.vX = -0.2;
}
if (s.vY>=0 && s.vY<0.2) {
s.vY = 0.2;
}
};
this.move = function() {
var vX = s.vX*windOffset, yDiff;
s.x += vX;
s.y += (s.vY*s.vAmp);
if (s.x >= screenX || screenX-s.x < storm.flakeWidth) { // X-axis scroll check
s.x = 0;
} else if (vX < 0 && s.x-storm.flakeLeftOffset < -storm.flakeWidth) {
s.x = screenX-storm.flakeWidth-1; // flakeWidth;
}
s.refresh();
yDiff = screenY+scrollY-s.y+storm.flakeHeight;
if (yDiff<storm.flakeHeight) {
s.active = 0;
if (storm.snowStick) {
s.stick();
} else {
s.recycle();
}
} else {
if (storm.useMeltEffect && s.active && s.type < 3 && !s.melting && Math.random()>0.998) {
// ~1/1000 chance of melting mid-air, with each frame
s.melting = true;
s.melt();
// only incrementally melt one frame
// s.melting = false;
}
if (storm.useTwinkleEffect) {
if (s.twinkleFrame < 0) {
if (Math.random() > 0.97) {
s.twinkleFrame = parseInt(Math.random() * 8, 10);
}
} else {
s.twinkleFrame--;
if (!opacitySupported) {
s.o.style.visibility = (s.twinkleFrame && s.twinkleFrame % 2 === 0 ? 'hidden' : 'visible');
} else {
s.o.style.opacity = (s.twinkleFrame && s.twinkleFrame % 2 === 0 ? 0 : 1);
}
}
}
}
};
this.animate = function() {
// main animation loop
// move, check status, die etc.
s.move();
};
this.setVelocities = function() {
s.vX = vRndX+rnd(storm.vMaxX*0.12,0.1);
s.vY = vRndY+rnd(storm.vMaxY*0.12,0.1);
};
this.setOpacity = function(o,opacity) {
if (!opacitySupported) {
return false;
}
o.style.opacity = opacity;
};
this.melt = function() {
if (!storm.useMeltEffect || !s.melting) {
s.recycle();
} else {
if (s.meltFrame < s.meltFrameCount) {
s.setOpacity(s.o,s.meltFrames[s.meltFrame]);
s.o.style.fontSize = s.fontSize-(s.fontSize*(s.meltFrame/s.meltFrameCount))+'px';
s.o.style.lineHeight = storm.flakeHeight+2+(storm.flakeHeight*0.75*(s.meltFrame/s.meltFrameCount))+'px';
s.meltFrame++;
} else {
s.recycle();
}
}
};
this.recycle = function() {
s.o.style.display = 'none';
s.o.style.position = (fixedForEverything?'fixed':'absolute');
s.o.style.bottom = 'auto';
s.setVelocities();
s.vCheck();
s.meltFrame = 0;
s.melting = false;
s.setOpacity(s.o,1);
s.o.style.padding = '0px';
s.o.style.margin = '0px';
s.o.style.fontSize = s.fontSize+'px';
s.o.style.lineHeight = (storm.flakeHeight+2)+'px';
s.o.style.textAlign = 'center';
s.o.style.verticalAlign = 'baseline';
s.x = parseInt(rnd(screenX-storm.flakeWidth-20),10);
s.y = parseInt(rnd(screenY)*-1,10)-storm.flakeHeight;
s.refresh();
s.o.style.display = 'block';
s.active = 1;
};
this.recycle(); // set up x/y coords etc.
this.refresh();
};
this.snow = function() {
var active = 0, flake = null, i, j;
for (i=0, j=storm.flakes.length; i<j; i++) {
if (storm.flakes[i].active === 1) {
storm.flakes[i].move();
active++;
}
if (storm.flakes[i].melting) {
storm.flakes[i].melt();
}
}
if (active<storm.flakesMaxActive) {
flake = storm.flakes[parseInt(rnd(storm.flakes.length),10)];
if (flake.active === 0) {
flake.melting = true;
}
}
if (storm.timer) {
features.getAnimationFrame(storm.snow);
}
};
this.mouseMove = function(e) {
if (!storm.followMouse) {
return true;
}
var x = parseInt(e.clientX,10);
if (x<screenX2) {
windOffset = -windMultiplier+(x/screenX2*windMultiplier);
} else {
x -= screenX2;
windOffset = (x/screenX2)*windMultiplier;
}
};
this.createSnow = function(limit,allowInactive) {
var i;
for (i=0; i<limit; i++) {
storm.flakes[storm.flakes.length] = new storm.SnowFlake(parseInt(rnd(flakeTypes),10));
if (allowInactive || i>storm.flakesMaxActive) {
storm.flakes[storm.flakes.length-1].active = -1;
}
}
storm.targetElement.appendChild(docFrag);
};
this.timerInit = function() {
storm.timer = true;
storm.snow();
};
this.init = function() {
var i;
for (i=0; i<storm.meltFrameCount; i++) {
storm.meltFrames.push(1-(i/storm.meltFrameCount));
}
storm.randomizeWind();
storm.createSnow(storm.flakesMax); // create initial batch
storm.events.add(window,'resize',storm.resizeHandler);
storm.events.add(window,'scroll',storm.scrollHandler);
if (storm.freezeOnBlur) {
if (isIE) {
storm.events.add(document,'focusout',storm.freeze);
storm.events.add(document,'focusin',storm.resume);
} else {
storm.events.add(window,'blur',storm.freeze);
storm.events.add(window,'focus',storm.resume);
}
}
storm.resizeHandler();
storm.scrollHandler();
if (storm.followMouse) {
storm.events.add(isIE?document:window,'mousemove',storm.mouseMove);
}
storm.animationInterval = Math.max(20,storm.animationInterval);
storm.timerInit();
};
this.start = function(bFromOnLoad) {
if (!didInit) {
didInit = true;
} else if (bFromOnLoad) {
// already loaded and running
return true;
}
if (typeof storm.targetElement === 'string') {
var targetID = storm.targetElement;
storm.targetElement = document.getElementById(targetID);
if (!storm.targetElement) {
throw new Error('Snowstorm: Unable to get targetElement "'+targetID+'"');
}
}
if (!storm.targetElement) {
storm.targetElement = (document.body || document.documentElement);
}
if (storm.targetElement !== document.documentElement && storm.targetElement !== document.body) {
// re-map handler to get element instead of screen dimensions
storm.resizeHandler = storm.resizeHandlerAlt;
//and force-enable pixel positioning
storm.usePixelPosition = true;
}
storm.resizeHandler(); // get bounding box elements
storm.usePositionFixed = (storm.usePositionFixed && !noFixed && !storm.flakeBottom); // whether or not position:fixed is to be used
if (window.getComputedStyle) {
// attempt to determine if body or user-specified snow parent element is relatlively-positioned.
try {
targetElementIsRelative = (window.getComputedStyle(storm.targetElement, null).getPropertyValue('position') === 'relative');
} catch(e) {
// oh well
targetElementIsRelative = false;
}
}
fixedForEverything = storm.usePositionFixed;
if (screenX && screenY && !storm.disabled) {
storm.init();
storm.active = true;
}
};
function doDelayedStart() {
window.setTimeout(function() {
storm.start(true);
}, 20);
// event cleanup
storm.events.remove(isIE?document:window,'mousemove',doDelayedStart);
}
function doStart() {
if (!storm.excludeMobile || !isMobile) {
doDelayedStart();
}
// event cleanup
storm.events.remove(window, 'load', doStart);
}
// hooks for starting the snow
if (storm.autoStart) {
storm.events.add(window, 'load', doStart, false);
}
return this;
}(window, document));

21
res/toggleDarkTheme.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
require $_SERVER['DOCUMENT_ROOT']."/globalFuncs.php";
if(getUserInfo($current_user)->dark_theme){
$stmt = $conn->prepare("UPDATE users SET dark_theme = 0 WHERE id = :usr");
$stmt->bindParam(":usr", $current_user);
$stmt->execute();
}else{
$stmt = $conn->prepare("UPDATE users SET dark_theme = 1 WHERE id = :usr");
$stmt->bindParam(":usr", $current_user);
$stmt->execute();
}
if($stmt){
msg("Theme updated.");
}else{
msg("Error updating theme.");
}
header("Location: /user/settings.php");
?>

21
res/toggleSnow.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
require $_SERVER['DOCUMENT_ROOT']."/globalFuncs.php";
if(getUserInfo($current_user)->snow){
$stmt = $conn->prepare("UPDATE users SET snow = 0 WHERE id = :usr");
$stmt->bindParam(":usr", $current_user);
$stmt->execute();
}else{
$stmt = $conn->prepare("UPDATE users SET snow = 1 WHERE id = :usr");
$stmt->bindParam(":usr", $current_user);
$stmt->execute();
}
if($stmt){
msg("Snow setting changed.");
}else{
msg("Error changing snow.");
}
header("Location: /user/settings.php");
?>

49
res/top Normal file
View File

@@ -0,0 +1,49 @@
<?php
$searchArrayMobile = ["Search", "Looking for something?", "Hey, a search bar!"];
$searchArray = ["You can search all posts and questions here", "Looking for something specific?", "Type 'history:' before your search to narrow it down to one class", "Looking for something?", "Search for what you need", "Oh look, there's a search bar", "Don't do a search now, I'm sleeping (zzz)"];
$searchPlaceholder = "\"".$searchArray[array_rand($searchArray)]."\"";
$searchPlaceholderMobile = "\"".$searchArrayMobile[array_rand($searchArrayMobile)]."\"";
?>
<div id=topSpacer></div>
<div id=top>
<a id=logoLink href="/"><img id=logo src="/res/i/logo.png"></a>
<div id=search>
<form id=searchForm method=GET action=/search>
<input placeholder=<?=$searchPlaceholder?> id=searchBar type=text autocomplete=off name=q value=<?=isset($_GET["q"])?"\"".htmlspecialchars($_GET["q"])."\"":"";?>>
</form>
</div>
<div id=addPost class=noSelect><a href="/post">+ Post</a></div>
<a id=accountWrapper href=<?php echo $verified?"/user/?user=".$current_user:"/user/login.php"; ?>>
<img id=account src=<?php echo $verified?getUserInfo($current_user)->image_url:"/res/i/user.png"; ?>>
</a>
</div>
<!-- Mobile -->
<input id=hamCheck type=checkbox style=display:none>
<div id=topMobile class=mobile>
<div id=mobileMenu><label for=hamCheck><img class=hamburger src=/res/i/ham.png></label></div>
<a id=logoLinkMobile href="/"><img id=logoMobile src="/res/i/logo.png"></a>
<div id=topMobileSpacer></div>
</div>
<div id=leftMobile class='mobile keepRight'>
<label for=hamCheck><img id=hamburgerInLeft class=hamburger src=/res/i/ham.png></label>
<a id=accountWrapperMobile class=noStyle href=<?php echo $verified?"/user/?user=".$current_user:"/user/login.php"; ?>>
<img id=accountMobile src=<?php echo $verified?getUserInfo($current_user)->image_url:"/res/i/user.png"; ?>>
<h2><?=getUserInfo($current_user)->name?></h2>
</a>
<div id=searchMobile>
<form id=searchFormMobile method=GET action=/search>
<input placeholder=<?=$searchPlaceholderMobile?> id=searchBarMobile type=text autocomplete=off name=q value=<?=isset($_GET["q"])?"\"".htmlspecialchars($_GET["q"])."\"":"";?>>
</form>
</div>
<div id=addPostMobile class=noSelect><a href="/post">+ Post</a></div>
<?php include $_SERVER['DOCUMENT_ROOT']."/res/notifs"; ?>
</div>
<?php
if($msg != NULL){
echo "<msg class=neutral>".$msg."</msg>";
}
?>