Browse Source

adds multi-photo CSS, and dismiss button

master
Aaron Parecki 6 years ago
parent
commit
a31fbff8c2
No known key found for this signature in database GPG Key ID: 276C2817346D6056
11 changed files with 492 additions and 40 deletions
  1. +2
    -0
      .gitignore
  2. +10
    -5
      app/Http/Controllers/DashboardController.php
  3. +1
    -1
      app/Http/Controllers/TwitterController.php
  4. +1
    -0
      package.json
  5. +205
    -0
      public/css/app.css
  6. +131
    -15
      public/js/app.js
  7. +3
    -0
      resources/assets/js/bootstrap.js
  8. +60
    -14
      resources/assets/js/components/Scorecard.vue
  9. +22
    -3
      resources/assets/js/components/TweetQueue.vue
  10. +0
    -2
      resources/assets/js/event-bus.js
  11. +57
    -0
      resources/assets/sass/app.scss

+ 2
- 0
.gitignore View File

@ -9,3 +9,5 @@ Homestead.json
Homestead.yaml
npm-debug.log
.env
.DS_Store

+ 10
- 5
app/Http/Controllers/DashboardController.php View File

@ -45,11 +45,16 @@ class DashboardController extends Controller
public function claim_tweet(Request $request) {
$tweet = Tweet::where('id', $request->input('tweet_id'))->first();
if($tweet) {
$tweet->claimed_at = date('Y-m-d H:i:s');
$tweet->save();
// Broadcast that this tweet was claimed
event(new TweetClaimedEvent($tweet));
if($request->input('status') == 'unclaimed') {
$tweet->claimed_at = null;
$tweet->save();
event(new NewTweetEvent($tweet));
} else {
$tweet->claimed_at = date('Y-m-d H:i:s');
$tweet->save();
// Broadcast that this tweet was claimed
event(new TweetClaimedEvent($tweet));
}
}
return response()->json(['result'=>'ok']);
}

+ 1
- 1
app/Http/Controllers/TwitterController.php View File

@ -53,7 +53,7 @@ class TwitterController extends BaseController
$tweet->player_id = $player ? $player->id : 0;
$tweet->team_id = $player ? $player->team->id : 0;
$tweet->text = $text;
$tweet->photo = json_encode($photos);
$tweet->photo = json_encode($photos, JSON_UNESCAPED_SLASHES);
$tweet->mission_id = $mission_id;
$tweet->tweet_date = date('Y-m-d H:i:s', strtotime($data['created_at']));
$tweet->save();

+ 1
- 0
package.json View File

@ -19,6 +19,7 @@
"vue": "^2.1.10"
},
"dependencies": {
"featherlight": "^1.7.6",
"laravel-echo": "^1.3.0",
"pusher-js": "^4.1.0"
}

+ 205
- 0
public/css/app.css View File

@ -8350,6 +8350,153 @@ button.close {
}
}
/**
* Featherlight ultra slim jQuery lightbox
* Version 1.7.6 - http://noelboss.github.io/featherlight/
*
* Copyright 2017, Noël Raoul Bossart (http://www.noelboss.com)
* MIT Licensed.
**/
@media all {
.featherlight {
display: none;
/* dimensions: spanning the background from edge to edge */
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2147483647;
/* z-index needs to be >= elements on the site. */
/* position: centering content */
text-align: center;
/* insures that the ::before pseudo element doesn't force wrap with fixed width content; */
white-space: nowrap;
/* styling */
cursor: pointer;
background: #333;
/* IE8 "hack" for nested featherlights */
background: transparent;
}
/* support for nested featherlights. Does not work in IE8 (use JS to fix) */
.featherlight:last-of-type {
background: rgba(0, 0, 0, 0.8);
}
.featherlight:before {
/* position: trick to center content vertically */
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.featherlight .featherlight-content {
/* make content container for positioned elements (close button) */
position: relative;
/* position: centering vertical and horizontal */
text-align: left;
vertical-align: middle;
display: inline-block;
/* dimensions: cut off images */
overflow: auto;
padding: 25px 25px 0;
border-bottom: 25px solid transparent;
/* dimensions: handling large content */
margin-left: 5%;
margin-right: 5%;
max-height: 95%;
/* styling */
background: #fff;
cursor: auto;
/* reset white-space wrapping */
white-space: normal;
}
/* contains the content */
.featherlight .featherlight-inner {
/* make sure its visible */
display: block;
}
/* don't show these though */
.featherlight script.featherlight-inner,
.featherlight link.featherlight-inner,
.featherlight style.featherlight-inner {
display: none;
}
.featherlight .featherlight-close-icon {
/* position: centering vertical and horizontal */
position: absolute;
z-index: 9999;
top: 0;
right: 0;
/* dimensions: 25px x 25px */
line-height: 25px;
width: 25px;
/* styling */
cursor: pointer;
text-align: center;
font-family: Arial, sans-serif;
background: #fff;
/* Set the background in case it overlaps the content */
background: rgba(255, 255, 255, 0.3);
color: #000;
border: none;
padding: 0;
}
/* See http://stackoverflow.com/questions/16077341/how-to-reset-all-default-styles-of-the-html5-button-element */
.featherlight .featherlight-close-icon::-moz-focus-inner {
border: 0;
padding: 0;
}
.featherlight .featherlight-image {
/* styling */
width: 100%;
}
.featherlight-iframe .featherlight-content {
/* removed the border for image croping since iframe is edge to edge */
border-bottom: 0;
padding: 0;
-webkit-overflow-scrolling: touch;
overflow-y: scroll;
}
.featherlight iframe {
/* styling */
border: none;
}
.featherlight * {
/* See https://github.com/noelboss/featherlight/issues/42 */
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
}
/* handling phones and small screens */
@media only screen and (max-width: 1024px) {
.featherlight .featherlight-content {
/* dimensions: maximize lightbox with for small screens */
margin-left: 0;
margin-right: 0;
max-height: 98%;
padding: 10px 10px 0;
border-bottom: 10px solid transparent;
}
}
.team {
display: -webkit-box;
display: -ms-flexbox;
@ -8419,7 +8566,65 @@ button.close {
padding: 8px;
}
.scorecard .panel-heading {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.scorecard .panel-heading .team {
-webkit-box-flex: 1;
-ms-flex: 1 0;
flex: 1 0;
}
.scorecard .tweet .text {
white-space: pre-wrap;
}
.scorecard .tweet img {
max-width: 100%;
}
.multi-photo .photo {
position: relative;
overflow: hidden;
float: left;
cursor: pointer;
/* This positions and sizes the image (background-image) within the grid container */
background-size: cover;
background-position: 50% 50%;
/* for multi-photo posts with 4 or more photos, use this */
width: 50%;
height: 240px;
}
.multi-photo .photo img {
/* hide the img tag because the image is shown by the background image */
display: none;
}
.multi-photo-clear {
clear: both;
}
/* 2-up multi-photos use this layout */
.multi-photo.photos-2 .photo {
width: 50%;
height: 300px;
}
/* 3-up multi-photos use this layout */
.multi-photo.photos-3 .photo:nth-child(1) {
width: 65%;
height: 400px;
}
.multi-photo.photos-3 .photo:nth-child(2),
.multi-photo.photos-3 .photo:nth-child(3) {
width: 35%;
height: 200px;
}

+ 131
- 15
public/js/app.js
File diff suppressed because it is too large
View File


+ 3
- 0
resources/assets/js/bootstrap.js View File

@ -23,6 +23,9 @@ window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
require('featherlight');
$.featherlight.autoBind = false;
/**
* Next we will register the CSRF Token as a common header with Axios so that
* all outgoing HTTP requests automatically have it attached. This is just

+ 60
- 14
resources/assets/js/components/Scorecard.vue View File

@ -1,21 +1,52 @@
<template>
<div class="panel panel-default" v-show="show">
<div class="panel-heading"><div class="team-name">{{ tweet.team_name }}</div></div>
<div class="panel-body scorecard">
<div class="profile">
<img :src="tweet.player_photo" :style="'border-color: #'+tweet.team_color">
<span><a :href="'https://twitter.com/'+tweet.player_username">@{{ tweet.player_username }}</a></span>
<div class="panel panel-default scorecard" v-show="show">
<div class="panel-heading">
<div class="team">
<span class="team-icon" :style="'background-color: #'+tweet.team_color"></span>
<span class="team-name">{{ tweet.team_name }}</span>
</div>
<button type="button" class="close" v-on:click="dismiss"><span>&times;</span></button>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-8">
<div class="profile">
<img :src="tweet.player_photo" :style="'border-color: #'+tweet.team_color">
<span><a :href="'https://twitter.com/'+tweet.player_username">@{{ tweet.player_username }}</a></span>
</div>
<div class="tweet">
<div class="text">{{ tweet.text }}</div>
<div v-if="tweet.photos">
<template v-if="tweet.photos.length == 1">
<div v-for="img in tweet.photos">
<img :src="img">
</div>
</template>
<template v-else>
<div :class="'multi-photo photos-'+tweet.photos.length" v-if="tweet.photos">
<div v-for="img in tweet.photos" class="photo" :style="'background-image:url('+img+')'" :data-featherlight="img">
<img :src="img">
</div>
</div>
<div class="multi-photo-clear"></div>
</template>
</div>
</div>
<div class="tweet">
{{ tweet.text }}
<div v-for="img in tweet.photos">
<img :src="img">
</div>
</div>
<div class="col-md-4">
<div>{{ tweet.mission }}</div>
<div>{{ tweet.mission }}</div>
</div>
</div>
</div>
</div>
@ -27,8 +58,23 @@ module.exports = {
return {
}
},
methods: {
dismiss() {
this.$emit('dismiss')
}
},
watch: {
// https://vuejs.org/v2/guide/computed.html#Watchers
show: function(val) {
if(val) {
// https://vuejs.org/v2/guide/reactivity.html#Async-Update-Queue
Vue.nextTick(function() {
$(".multi-photo .photo").featherlight();
});
}
}
},
created() {
console.log(this.tweet);
}
}
</script>

+ 22
- 3
resources/assets/js/components/TweetQueue.vue View File

@ -10,7 +10,7 @@
<div class="mission" :data-mission-id="tweet.mission_id">{{ tweet.mission }}</div>
<div class="profile">
<img :src="tweet.player_photo" :style="'border-color: #'+tweet.team_color">
<span><a :href="'https://twitter.com/'+tweet.player_username">@{{ tweet.player_username }}</a></span>
<span>@{{ tweet.player_username }}</span>
</div>
<div class="text">{{ tweet.text }}</div>
</div>
@ -18,7 +18,7 @@
</div>
</div>
<div class="col-xs-8 col-md-8">
<scorecard :show.sync="show" :tweet="tweet"></scorecard>
<scorecard :show.sync="show" :tweet="tweet" v-on:dismiss="dismissTweet"></scorecard>
</div>
</div>
</div>
@ -70,7 +70,13 @@ module.exports = {
}
},
clickedTweet(event) {
var tweet_id = $(event.target).parents(".tweet").data('tweet-id');
var tweet_id;
if($(event.target).data('tweet-id')) {
tweet_id = $(event.target).data('tweet-id')
} else {
tweet_id = $(event.target).parents(".tweet").data('tweet-id');
}
var tweet_data = this.removeTweetFromQueue(tweet_id);
if(tweet_data) {
@ -89,6 +95,19 @@ module.exports = {
} else {
console.log("Tweet not found: "+tweet_id);
}
},
dismissTweet() {
console.log('caught event')
// Mark as un-claimed
$.post('/dashboard/claim-tweet', {
tweet_id: this.tweet.tweet_id,
status: 'unclaimed'
}, function(response){
});
this.tweet = {};
this.show = false;
}
},
created() {

+ 0
- 2
resources/assets/js/event-bus.js View File

@ -1,2 +0,0 @@
import Vue from 'vue';
export const EventBus = new Vue();

+ 57
- 0
resources/assets/sass/app.scss View File

@ -8,6 +8,9 @@
// Bootstrap
@import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
// Featherlight
@import "node_modules/featherlight/src/featherlight";
.team {
display: flex;
align-items: center;
@ -85,11 +88,65 @@
}
.scorecard {
.panel-heading {
display: flex;
.team {
flex: 1 0;
}
}
.tweet {
.text {
white-space: pre-wrap;
}
img {
max-width: 100%;
}
}
}
.multi-photo {
.photo {
position: relative;
overflow: hidden;
float: left;
cursor: pointer;
/* This positions and sizes the image (background-image) within the grid container */
background-size: cover;
background-position: 50% 50%;
/* for multi-photo posts with 4 or more photos, use this */
width: 50%;
height: 240px;
img {
/* hide the img tag because the image is shown by the background image */
display: none;
}
}
}
.multi-photo-clear {
clear: both;
}
/* 2-up multi-photos use this layout */
.multi-photo.photos-2 .photo {
width: 50%;
height: 300px;
}
/* 3-up multi-photos use this layout */
.multi-photo.photos-3 .photo:nth-child(1) {
width: 65%;
height: 400px;
}
.multi-photo.photos-3 .photo:nth-child(2),
.multi-photo.photos-3 .photo:nth-child(3) {
width: 35%;
height: 200px;
}

Loading…
Cancel
Save