implemented comments page
This commit is contained in:
@@ -4,7 +4,8 @@ from django.contrib.auth.models import User
|
|||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Rower, Workout,GraphImage,FavoriteChart,SiteAnnouncement,
|
Rower, Workout,GraphImage,FavoriteChart,SiteAnnouncement,
|
||||||
Team,TeamInvite,TeamRequest
|
Team,TeamInvite,TeamRequest,
|
||||||
|
WorkoutComment,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Register your models here so you can use them in the Admin module
|
# Register your models here so you can use them in the Admin module
|
||||||
@@ -36,6 +37,9 @@ class TeamInviteAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
class TeamRequestAdmin(admin.ModelAdmin):
|
class TeamRequestAdmin(admin.ModelAdmin):
|
||||||
list_display = ('issuedate','team','user','code')
|
list_display = ('issuedate','team','user','code')
|
||||||
|
|
||||||
|
class WorkoutCommentAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ('created','user','workout')
|
||||||
|
|
||||||
admin.site.unregister(User)
|
admin.site.unregister(User)
|
||||||
admin.site.register(User,UserAdmin)
|
admin.site.register(User,UserAdmin)
|
||||||
@@ -46,3 +50,4 @@ admin.site.register(FavoriteChart,FavoriteChartAdmin)
|
|||||||
admin.site.register(SiteAnnouncement,SiteAnnouncementAdmin)
|
admin.site.register(SiteAnnouncement,SiteAnnouncementAdmin)
|
||||||
admin.site.register(TeamInvite,TeamInviteAdmin)
|
admin.site.register(TeamInvite,TeamInviteAdmin)
|
||||||
admin.site.register(TeamRequest,TeamRequestAdmin)
|
admin.site.register(TeamRequest,TeamRequestAdmin)
|
||||||
|
admin.site.register(WorkoutComment,WorkoutCommentAdmin)
|
||||||
|
|||||||
@@ -855,21 +855,6 @@ class RowerForm(ModelForm):
|
|||||||
if an>=max:
|
if an>=max:
|
||||||
raise forms.ValidationError("AN should be lower than Max")
|
raise forms.ValidationError("AN should be lower than Max")
|
||||||
|
|
||||||
# A comment by a user on a training
|
|
||||||
class WorkoutComment(models.Model):
|
|
||||||
created = models.DateField(default=timezone.now)
|
|
||||||
comment = models.TextField(max_length=300)
|
|
||||||
read = models.BooleanField(default=False)
|
|
||||||
user = models.ForeignKey(User)
|
|
||||||
workout = models.ForeignKey(Workout)
|
|
||||||
|
|
||||||
class WorkoutCommentForm(ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = WorkoutComment
|
|
||||||
fields = ['comment']
|
|
||||||
widgets = {
|
|
||||||
'comment': forms.Textarea,
|
|
||||||
}
|
|
||||||
|
|
||||||
# An announcement that goes to the right of the workouts list
|
# An announcement that goes to the right of the workouts list
|
||||||
# optionally sends a tweet to our twitter account
|
# optionally sends a tweet to our twitter account
|
||||||
@@ -894,3 +879,28 @@ class SiteAnnouncement(models.Model):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return super(SiteAnnouncement,self).save(*args, **kwargs)
|
return super(SiteAnnouncement,self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
# A comment by a user on a training
|
||||||
|
class WorkoutComment(models.Model):
|
||||||
|
comment = models.TextField(max_length=300)
|
||||||
|
created = models.DateTimeField(default=timezone.now)
|
||||||
|
read = models.BooleanField(default=False)
|
||||||
|
user = models.ForeignKey(User)
|
||||||
|
workout = models.ForeignKey(Workout)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return u'Comment to: {w} by {u1} {u2}'.format(
|
||||||
|
w=self.workout.name,
|
||||||
|
u1 = self.user.first_name,
|
||||||
|
u2 = self.user.last_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class WorkoutCommentForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = WorkoutComment
|
||||||
|
fields = ['comment',]
|
||||||
|
widgets = {
|
||||||
|
'comment': forms.Textarea,
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,12 @@
|
|||||||
{% block title %}Workouts{% endblock %}
|
{% block title %}Workouts{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
setTimeout("location.reload(true);",60000);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<div class="grid_12">
|
<div class="grid_12">
|
||||||
|
|
||||||
Select start and end date for a date range:
|
Select start and end date for a date range:
|
||||||
@@ -27,7 +33,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid_8 alpha">
|
<div id="workouts_table" class="grid_8 alpha">
|
||||||
{% if team %}
|
{% if team %}
|
||||||
<h3>{{ team.name }} Team Workouts</h3>
|
<h3>{{ team.name }} Team Workouts</h3>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -6,172 +6,167 @@
|
|||||||
{% block title %}Change Workout {% endblock %}
|
{% block title %}Change Workout {% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="workouts" class="grid_6 alpha">
|
<script>
|
||||||
|
setTimeout("location.reload(true);",60000);
|
||||||
|
</script>
|
||||||
|
|
||||||
{% if form.errors %}
|
<div id="left" class="grid_6 alpha">
|
||||||
<p style="color: red;">
|
<div id="summary" class="grid_6 alpha">
|
||||||
Please correct the error{{ form.errors|pluralize }} below.
|
{% if form.errors %}
|
||||||
</p>
|
<p style="color: red;">
|
||||||
{% endif %}
|
Please correct the error{{ form.errors|pluralize }} below.
|
||||||
|
</p>
|
||||||
<h1>Comments {{ workout.name }}</h1>
|
{% endif %}
|
||||||
|
|
||||||
{% localtime on %}
|
<h1>Comments {{ workout.name }}</h1>
|
||||||
<table width=100%>
|
|
||||||
<tr>
|
{% localtime on %}
|
||||||
<th>Rower:</th><td>{{ first_name }} {{ last_name }}</td>
|
<table width=100%>
|
||||||
</tr><tr>
|
<tr>
|
||||||
<th>Date/Time:</th><td>{{ workout.startdatetime }}</td>
|
<th>Rower:</th><td>{{ first_name }} {{ last_name }}</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<th>Distance:</th><td>{{ workout.distance }}m</td>
|
<th>Date/Time:</th><td>{{ workout.startdatetime }}</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<th>Duration:</th><td>{{ workout.duration |durationprint:"%H:%M:%S.%f" }}</td>
|
<th>Distance:</th><td>{{ workout.distance }}m</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<th>Public link to this workout</th>
|
<th>Duration:</th><td>{{ workout.duration |durationprint:"%H:%M:%S.%f" }}</td>
|
||||||
<td>
|
</tr><tr>
|
||||||
<a href="/rowers/workout/{{ workout.id }}">https://rowsandall.com/rowers/workout/{{ workout.id }}</a>
|
<th>Public link to this workout</th>
|
||||||
<td>
|
<td>
|
||||||
</tr><tr>
|
<a href="/rowers/workout/{{ workout.id }}">https://rowsandall.com/rowers/workout/{{ workout.id }}</a>
|
||||||
<th>Public link to interactive chart</th>
|
<td>
|
||||||
<td>
|
</tr><tr>
|
||||||
|
<th>Public link to interactive chart</th>
|
||||||
|
<td>
|
||||||
<a href="/rowers/workout/{{ workout.id }}/interactiveplot">https://rowsandall.com/rowers/workout/{{ workout.id }}/interactiveplot</a>
|
<a href="/rowers/workout/{{ workout.id }}/interactiveplot">https://rowsandall.com/rowers/workout/{{ workout.id }}/interactiveplot</a>
|
||||||
<td>
|
<td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
{% endlocaltime %}
|
{% endlocaltime %}
|
||||||
<form enctype="multipart/form-data" action="" method="post">
|
</div>
|
||||||
<table width=100%>
|
{% for c in comments %}
|
||||||
{{ form.as_table }}
|
<div class="grid_6 alpha">
|
||||||
</table>
|
<div class="grid_2 alpha">
|
||||||
{% csrf_token %}
|
{{ c.created }}
|
||||||
<div id="formbutton" class="grid_1 prefix_4 suffix_1 omega">
|
<b>{{ c.user.first_name }} {{ c.user.last_name }}</b>
|
||||||
<input class="button green" type="submit" value="Save">
|
</div>
|
||||||
</div>
|
<div class="grid_4 omega">
|
||||||
</form>
|
<div class="talk-bubble tri-right left-top">
|
||||||
</div>
|
<div class="talktext">
|
||||||
<div id="images" class="grid_6 omega">
|
{{ c.comment }}
|
||||||
<h1>Images linked to this workout</h1>
|
</div>
|
||||||
<div class="grid_6 alpha">
|
|
||||||
<div class="grid_2 alpha">
|
|
||||||
<p>
|
|
||||||
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/addtimeplot">Add Time Plot</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="grid_2">
|
|
||||||
<p>
|
|
||||||
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/adddistanceplot">Add Distance Plot</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="grid_2 omega">
|
|
||||||
<p>
|
|
||||||
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/addpiechart">Add Pie Chart</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="grid_6 alpha">
|
|
||||||
|
|
||||||
<div class="grid_2 prefix_4 alpha">
|
|
||||||
<p>
|
|
||||||
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/addpowerpiechart">Power Pie Chart</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="grid_6">
|
|
||||||
<p>Generating images takes roughly 1 second per minute
|
|
||||||
of your workout's duration. Please reload after a minute or so.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% if graphs1 %}
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% for graph in graphs1 %}
|
<div id="form" class="grid_6 alpha">
|
||||||
{% if forloop.counter == 1 %}
|
<form enctype="multipart/form-data" action="" method="post">
|
||||||
<div id="thumb-container" class="grid_2 alpha">
|
<table width=100%>
|
||||||
<a href="/rowers/graph/{{ graph.id }}/">
|
{{ form.as_table }}
|
||||||
<img src="/{{ graph.filename }}"
|
</table>
|
||||||
onerror="this.src='/static/img/waiting.png'"
|
{% csrf_token %}
|
||||||
alt="{{ graph.filename }}" width="120" height="100"></a>
|
<div id="formbutton" class="grid_1 prefix_4 suffix_1 omega">
|
||||||
</div>
|
<input class="button green" type="submit" value="Save">
|
||||||
{% elif forloop.counter == 3 %}
|
</div>
|
||||||
<div id="thumb-container" class="grid_2 omega">
|
</form>
|
||||||
<a href="/rowers/graph/{{ graph.id }}/">
|
</div>
|
||||||
<img src="/{{ graph.filename }}"
|
|
||||||
onerror="this.src='/static/img/waiting.png'"
|
|
||||||
alt="{{ graph.filename }}" width="120" height="100"></a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
<div id="thumb-container" class="grid_2">
|
|
||||||
<a href="/rowers/graph/{{ graph.id }}/">
|
|
||||||
<img src="/{{ graph.filename }}"
|
|
||||||
onerror="this.src='/static/img/waiting.png'"
|
|
||||||
alt="{{ graph.filename }}" width="120" height="100"></a>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
|
|
||||||
{% for graph in graphs2 %}
|
|
||||||
{% if forloop.counter == 1 %}
|
|
||||||
<div id="thumb-container" class="grid_2 alpha">
|
|
||||||
<a href="/rowers/graph/{{ graph.id }}/">
|
|
||||||
<img src="/{{ graph.filename }}"
|
|
||||||
onerror="this.src='/static/img/waiting.png'"
|
|
||||||
alt="{{ graph.filename }}" width="120" height="100"></a>
|
|
||||||
</div>
|
|
||||||
{% elif forloop.counter == 3 %}
|
|
||||||
<div id="thumb-container" class="grid_2 omega">
|
|
||||||
<a href="/rowers/graph/{{ graph.id }}/">
|
|
||||||
<img src="/{{ graph.filename }}"
|
|
||||||
onerror="this.src='/static/img/waiting.png'"
|
|
||||||
alt="{{ graph.filename }}" width="120" height="100"></a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
<div id="thumb-container" class="grid_2">
|
|
||||||
<a href="/rowers/graph/{{ graph.id }}/">
|
|
||||||
<img src="/{{ graph.filename }}"
|
|
||||||
onerror="this.src='/static/img/waiting.png'"
|
|
||||||
alt="{{ graph.filename }}" width="120" height="100"></a>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
<p> No graphs found </p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<div id="images" class="grid_6 omega">
|
||||||
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
|
<h1>Images linked to this workout</h1>
|
||||||
html, body {height: 100%; margin:5px;}
|
|
||||||
</style>
|
{% if graphs1 %}
|
||||||
|
|
||||||
|
{% for graph in graphs1 %}
|
||||||
|
{% if forloop.counter == 1 %}
|
||||||
|
<div id="thumb-container" class="grid_2 alpha">
|
||||||
|
<a href="/rowers/graph/{{ graph.id }}/">
|
||||||
|
<img src="/{{ graph.filename }}"
|
||||||
|
onerror="this.src='/static/img/waiting.png'"
|
||||||
|
alt="{{ graph.filename }}" width="120" height="100"></a>
|
||||||
|
</div>
|
||||||
|
{% elif forloop.counter == 3 %}
|
||||||
|
<div id="thumb-container" class="grid_2 omega">
|
||||||
|
<a href="/rowers/graph/{{ graph.id }}/">
|
||||||
|
<img src="/{{ graph.filename }}"
|
||||||
|
onerror="this.src='/static/img/waiting.png'"
|
||||||
|
alt="{{ graph.filename }}" width="120" height="100"></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<div id="thumb-container" class="grid_2">
|
||||||
|
<a href="/rowers/graph/{{ graph.id }}/">
|
||||||
|
<img src="/{{ graph.filename }}"
|
||||||
|
onerror="this.src='/static/img/waiting.png'"
|
||||||
|
alt="{{ graph.filename }}" width="120" height="100"></a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
{% for graph in graphs2 %}
|
||||||
|
{% if forloop.counter == 1 %}
|
||||||
|
<div id="thumb-container" class="grid_2 alpha">
|
||||||
|
<a href="/rowers/graph/{{ graph.id }}/">
|
||||||
|
<img src="/{{ graph.filename }}"
|
||||||
|
onerror="this.src='/static/img/waiting.png'"
|
||||||
|
alt="{{ graph.filename }}" width="120" height="100"></a>
|
||||||
|
</div>
|
||||||
|
{% elif forloop.counter == 3 %}
|
||||||
|
<div id="thumb-container" class="grid_2 omega">
|
||||||
|
<a href="/rowers/graph/{{ graph.id }}/">
|
||||||
|
<img src="/{{ graph.filename }}"
|
||||||
|
onerror="this.src='/static/img/waiting.png'"
|
||||||
|
alt="{{ graph.filename }}" width="120" height="100"></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<div id="thumb-container" class="grid_2">
|
||||||
|
<a href="/rowers/graph/{{ graph.id }}/">
|
||||||
|
<img src="/{{ graph.filename }}"
|
||||||
|
onerror="this.src='/static/img/waiting.png'"
|
||||||
|
alt="{{ graph.filename }}" width="120" height="100"></a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<p> No graphs found </p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
|
||||||
|
html, body {height: 100%; margin:5px;}
|
||||||
|
</style>
|
||||||
|
|
||||||
<div id="summary" class="grid_6 omega">
|
<div id="summary" class="grid_6 omega">
|
||||||
<h1>Workout Summary</h1>
|
<h1>Workout Summary</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
{{ workout.summary }}
|
{{ workout.summary }}
|
||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
<div class="grid_2 alpha">
|
|
||||||
<a class="button green small" href="recalcsummary">Update Summary</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div id="interactiveplot" class="grid_6 omega">
|
<div id="interactiveplot" class="grid_6 omega">
|
||||||
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
|
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
|
||||||
<script async="true" type="text/javascript">
|
<script async="true" type="text/javascript">
|
||||||
Bokeh.set_log_level("info");
|
Bokeh.set_log_level("info");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{ gmscript |safe }}
|
{{ gmscript |safe }}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
|
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
|
||||||
html, body, #map_canvas {
|
html, body, #map_canvas {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -183,10 +178,10 @@
|
|||||||
|
|
||||||
#map_canvas {position: relative; top: 0; right: 0; bottom: 0; left: 0;}
|
#map_canvas {position: relative; top: 0; right: 0; bottom: 0; left: 0;}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<div id="map_canvas">
|
<div id="map_canvas">
|
||||||
{{ gmdiv|safe }}
|
{{ gmdiv|safe }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -3327,12 +3327,23 @@ def workout_comment_view(request,id=0):
|
|||||||
if w.privacy == 'private' and w.user.user != request.user:
|
if w.privacy == 'private' and w.user.user != request.user:
|
||||||
return HttpResponseForbidden("Permission error")
|
return HttpResponseForbidden("Permission error")
|
||||||
|
|
||||||
# ok we're permitted
|
# ok we're permitted
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = WorkoutCommentForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
cd = form.cleaned_data
|
||||||
|
comment = cd['comment']
|
||||||
|
c = WorkoutComment(workout=w,user=request.user,comment=comment)
|
||||||
|
c.save()
|
||||||
|
|
||||||
comments = WorkoutComment.objects.filter(workout=w).order_by("created")
|
comments = WorkoutComment.objects.filter(workout=w).order_by("created")
|
||||||
|
|
||||||
|
form = WorkoutCommentForm()
|
||||||
|
|
||||||
return render(request,
|
return render(request,
|
||||||
'workout_comments.html',
|
'workout_comments.html',
|
||||||
{'workout':w,
|
{'workout':w,
|
||||||
|
'comments':comments,
|
||||||
'form':form,
|
'form':form,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -554,3 +554,257 @@ a.wh:hover {
|
|||||||
.bk-canvas-map {
|
.bk-canvas-map {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* container */
|
||||||
|
.container {
|
||||||
|
padding: 5% 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CSS talk bubble */
|
||||||
|
.talk-bubble {
|
||||||
|
margin: 40px;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 200px;
|
||||||
|
height: auto;
|
||||||
|
background-color: lightyellow;
|
||||||
|
}
|
||||||
|
.border{
|
||||||
|
border: 8px solid #666;
|
||||||
|
}
|
||||||
|
.round{
|
||||||
|
border-radius: 30px;
|
||||||
|
-webkit-border-radius: 30px;
|
||||||
|
-moz-border-radius: 30px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right triangle placed top left flush. */
|
||||||
|
.tri-right.border.left-top:before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: -40px;
|
||||||
|
right: auto;
|
||||||
|
top: -8px;
|
||||||
|
bottom: auto;
|
||||||
|
border: 32px solid;
|
||||||
|
border-color: #666 transparent transparent transparent;
|
||||||
|
}
|
||||||
|
.tri-right.left-top:after{
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: -20px;
|
||||||
|
right: auto;
|
||||||
|
top: 0px;
|
||||||
|
bottom: auto;
|
||||||
|
border: 22px solid;
|
||||||
|
border-color: lightyellow transparent transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right triangle, left side slightly down */
|
||||||
|
.tri-right.border.left-in:before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: -40px;
|
||||||
|
right: auto;
|
||||||
|
top: 30px;
|
||||||
|
bottom: auto;
|
||||||
|
border: 20px solid;
|
||||||
|
border-color: #666 #666 transparent transparent;
|
||||||
|
}
|
||||||
|
.tri-right.left-in:after{
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: -20px;
|
||||||
|
right: auto;
|
||||||
|
top: 38px;
|
||||||
|
bottom: auto;
|
||||||
|
border: 12px solid;
|
||||||
|
border-color: lightyellow lightyellow transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Right triangle, placed bottom left side slightly in*/
|
||||||
|
.tri-right.border.btm-left:before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: -8px;
|
||||||
|
right: auto;
|
||||||
|
top: auto;
|
||||||
|
bottom: -40px;
|
||||||
|
border: 32px solid;
|
||||||
|
border-color: transparent transparent transparent #666;
|
||||||
|
}
|
||||||
|
.tri-right.btm-left:after{
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: 0px;
|
||||||
|
right: auto;
|
||||||
|
top: auto;
|
||||||
|
bottom: -20px;
|
||||||
|
border: 22px solid;
|
||||||
|
border-color: transparent transparent transparent lightyellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Right triangle, placed bottom left side slightly in*/
|
||||||
|
.tri-right.border.btm-left-in:before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: 30px;
|
||||||
|
right: auto;
|
||||||
|
top: auto;
|
||||||
|
bottom: -40px;
|
||||||
|
border: 20px solid;
|
||||||
|
border-color: #666 transparent transparent #666;
|
||||||
|
}
|
||||||
|
.tri-right.btm-left-in:after{
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: 38px;
|
||||||
|
right: auto;
|
||||||
|
top: auto;
|
||||||
|
bottom: -20px;
|
||||||
|
border: 12px solid;
|
||||||
|
border-color: lightyellow transparent transparent lightyellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Right triangle, placed bottom right side slightly in*/
|
||||||
|
.tri-right.border.btm-right-in:before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: auto;
|
||||||
|
right: 30px;
|
||||||
|
bottom: -40px;
|
||||||
|
border: 20px solid;
|
||||||
|
border-color: #666 #666 transparent transparent;
|
||||||
|
}
|
||||||
|
.tri-right.btm-right-in:after{
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: auto;
|
||||||
|
right: 38px;
|
||||||
|
bottom: -20px;
|
||||||
|
border: 12px solid;
|
||||||
|
border-color: lightyellow lightyellow transparent transparent;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
left: -8px;
|
||||||
|
right: auto;
|
||||||
|
top: auto;
|
||||||
|
bottom: -40px;
|
||||||
|
border: 32px solid;
|
||||||
|
border-color: transparent transparent transparent #666;
|
||||||
|
left: 0px;
|
||||||
|
right: auto;
|
||||||
|
top: auto;
|
||||||
|
bottom: -20px;
|
||||||
|
border: 22px solid;
|
||||||
|
border-color: transparent transparent transparent lightyellow;
|
||||||
|
|
||||||
|
/*Right triangle, placed bottom right side slightly in*/
|
||||||
|
.tri-right.border.btm-right:before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: auto;
|
||||||
|
right: -8px;
|
||||||
|
bottom: -40px;
|
||||||
|
border: 20px solid;
|
||||||
|
border-color: #666 #666 transparent transparent;
|
||||||
|
}
|
||||||
|
.tri-right.btm-right:after{
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: auto;
|
||||||
|
right: 0px;
|
||||||
|
bottom: -20px;
|
||||||
|
border: 12px solid;
|
||||||
|
border-color: lightyellow lightyellow transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right triangle, right side slightly down*/
|
||||||
|
.tri-right.border.right-in:before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: auto;
|
||||||
|
right: -40px;
|
||||||
|
top: 30px;
|
||||||
|
bottom: auto;
|
||||||
|
border: 20px solid;
|
||||||
|
border-color: #666 transparent transparent #666;
|
||||||
|
}
|
||||||
|
.tri-right.right-in:after{
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: auto;
|
||||||
|
right: -20px;
|
||||||
|
top: 38px;
|
||||||
|
bottom: auto;
|
||||||
|
border: 12px solid;
|
||||||
|
border-color: lightyellow transparent transparent lightyellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right triangle placed top right flush. */
|
||||||
|
.tri-right.border.right-top:before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: auto;
|
||||||
|
right: -40px;
|
||||||
|
top: -8px;
|
||||||
|
bottom: auto;
|
||||||
|
border: 32px solid;
|
||||||
|
border-color: #666 transparent transparent transparent;
|
||||||
|
}
|
||||||
|
.tri-right.right-top:after{
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
left: auto;
|
||||||
|
right: -20px;
|
||||||
|
top: 0px;
|
||||||
|
bottom: auto;
|
||||||
|
border: 20px solid;
|
||||||
|
border-color: lightyellow transparent transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* talk bubble contents */
|
||||||
|
.talktext{
|
||||||
|
padding: 1em;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
.talktext p{
|
||||||
|
/* remove webkit p margins */
|
||||||
|
-webkit-margin-before: 0em;
|
||||||
|
-webkit-margin-after: 0em;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user