Merge branch 'release/1.2'
This commit is contained in:
@@ -19,7 +19,7 @@ from bokeh.layouts import layout,widgetbox
|
|||||||
from bokeh.layouts import row as layoutrow
|
from bokeh.layouts import row as layoutrow
|
||||||
from bokeh.layouts import column as layoutcolumn
|
from bokeh.layouts import column as layoutcolumn
|
||||||
from bokeh.models import LinearAxis,LogAxis,Range1d,DatetimeTickFormatter,HoverTool
|
from bokeh.models import LinearAxis,LogAxis,Range1d,DatetimeTickFormatter,HoverTool
|
||||||
from bokeh.io import output_file, show
|
from bokeh.io import output_file, show, vplot
|
||||||
from bokeh.models import (
|
from bokeh.models import (
|
||||||
GMapPlot, GMapOptions, ColumnDataSource, Circle,
|
GMapPlot, GMapOptions, ColumnDataSource, Circle,
|
||||||
DataRange1d, PanTool, WheelZoomTool, BoxSelectTool,
|
DataRange1d, PanTool, WheelZoomTool, BoxSelectTool,
|
||||||
@@ -1604,10 +1604,6 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
|
|||||||
if datadf.empty:
|
if datadf.empty:
|
||||||
return ['','<p>No non-zero data in selection</p>','','']
|
return ['','<p>No non-zero data in selection</p>','','']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if xparam != 'distance' and xparam != 'time' and xparam != 'cumdist':
|
if xparam != 'distance' and xparam != 'time' and xparam != 'cumdist':
|
||||||
xaxmax = yaxmaxima[xparam]
|
xaxmax = yaxmaxima[xparam]
|
||||||
xaxmin = yaxminima[xparam]
|
xaxmin = yaxminima[xparam]
|
||||||
@@ -1673,17 +1669,29 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
|
|||||||
group
|
group
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TIPS = OrderedDict([
|
||||||
|
('time','@ftime'),
|
||||||
|
('pace','@fpace'),
|
||||||
|
('hr','@hr'),
|
||||||
|
('spm','@spm{1.1}'),
|
||||||
|
('distance','@distance{5}'),
|
||||||
|
])
|
||||||
|
|
||||||
|
hover = plot.select(type=HoverTool)
|
||||||
|
hover.tooltips = TIPS
|
||||||
|
|
||||||
if labeldict:
|
if labeldict:
|
||||||
legend=labeldict[id]
|
legend=labeldict[id]
|
||||||
else:
|
else:
|
||||||
legend=str(id)
|
legend=str(id)
|
||||||
|
|
||||||
if plottype=='line':
|
if plottype=='line':
|
||||||
plot.line('x','y',source=source,color=color,legend=legend)
|
l1 = plot.line('x','y',source=source,color=color,legend=legend)
|
||||||
else:
|
else:
|
||||||
plot.scatter('x','y',source=source,color=color,legend=legend,
|
l1 = plot.scatter('x','y',source=source,color=color,legend=legend,
|
||||||
fill_alpha=0.4,line_color=None)
|
fill_alpha=0.4,line_color=None)
|
||||||
|
|
||||||
|
plot.add_tools(HoverTool(renderers=[l1],tooltips=TIPS))
|
||||||
cntr += 1
|
cntr += 1
|
||||||
|
|
||||||
plot.legend.location='bottom_right'
|
plot.legend.location='bottom_right'
|
||||||
@@ -1725,7 +1733,7 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
|
|||||||
|
|
||||||
|
|
||||||
def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
|
def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
|
||||||
promember=0,plottype='line'):
|
promember=0,plottype='line'):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1743,8 +1751,8 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
|
|||||||
rowdata2 = dataprep.getsmallrowdata_db(columns,ids=[id2])
|
rowdata2 = dataprep.getsmallrowdata_db(columns,ids=[id2])
|
||||||
row1 = Workout.objects.get(id=id1)
|
row1 = Workout.objects.get(id=id1)
|
||||||
row2 = Workout.objects.get(id=id2)
|
row2 = Workout.objects.get(id=id2)
|
||||||
|
|
||||||
|
|
||||||
if rowdata1.empty:
|
if rowdata1.empty:
|
||||||
return "","CSV Data File Not Found"
|
return "","CSV Data File Not Found"
|
||||||
else:
|
else:
|
||||||
@@ -1797,32 +1805,39 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
|
|||||||
TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
|
TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
|
||||||
|
|
||||||
|
|
||||||
data = pd.DataFrame(
|
data1 = pd.DataFrame(
|
||||||
dict(
|
dict(
|
||||||
x1=x1,
|
x1=x1,
|
||||||
x2=x2,
|
|
||||||
y1=y1,
|
y1=y1,
|
||||||
y2=y2,
|
|
||||||
ftime1=ftime1,
|
ftime1=ftime1,
|
||||||
ftime2=ftime2,
|
|
||||||
fpace1=fpace1,
|
fpace1=fpace1,
|
||||||
fpace2=fpace2,
|
|
||||||
hr1 = hr1,
|
hr1 = hr1,
|
||||||
hr2 = hr2,
|
|
||||||
spm1 = spm1,
|
spm1 = spm1,
|
||||||
spm2 = spm2,
|
|
||||||
distance1=distance1,
|
distance1=distance1,
|
||||||
|
)
|
||||||
|
).dropna()
|
||||||
|
|
||||||
|
data2 = pd.DataFrame(
|
||||||
|
dict(
|
||||||
|
x2=x2,
|
||||||
|
y2=y2,
|
||||||
|
ftime2=ftime2,
|
||||||
|
fpace2=fpace2,
|
||||||
|
hr2 = hr2,
|
||||||
|
spm2 = spm2,
|
||||||
distance2=distance2,
|
distance2=distance2,
|
||||||
)
|
)
|
||||||
).dropna()
|
).dropna()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
source = ColumnDataSource(
|
|
||||||
data
|
source1 = ColumnDataSource(
|
||||||
|
data1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
source2 = ColumnDataSource(
|
||||||
|
data2
|
||||||
|
)
|
||||||
|
|
||||||
# create interactive plot
|
# create interactive plot
|
||||||
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
|
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
|
||||||
@@ -1830,22 +1845,52 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
|
|||||||
plot_width=920,
|
plot_width=920,
|
||||||
toolbar_sticky=False)
|
toolbar_sticky=False)
|
||||||
|
|
||||||
|
TIPS = OrderedDict([
|
||||||
|
('time','@ftime1'),
|
||||||
|
('pace','@fpace1'),
|
||||||
|
('hr','@hr1'),
|
||||||
|
('spm','@spm1{1.1}'),
|
||||||
|
('distance','@distance1{5}'),
|
||||||
|
])
|
||||||
|
TIPS2 = OrderedDict([
|
||||||
|
('time','@ftime2'),
|
||||||
|
('pace','@fpace2'),
|
||||||
|
('hr','@hr2'),
|
||||||
|
('spm','@spm2{1.1}'),
|
||||||
|
('distance','@distance2{5}'),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
hover1 = plot.select(type=HoverTool)
|
||||||
|
hover1.tooltips = TIPS
|
||||||
|
hover2 = plot.select(type=HoverTool)
|
||||||
|
hover2.tooltips = TIPS2
|
||||||
|
|
||||||
|
|
||||||
if plottype=='line':
|
if plottype=='line':
|
||||||
plot.line('x1','y1',source=source,color="blue",legend=row1.name)
|
l1 = plot.line('x1','y1',source=source1,
|
||||||
plot.line('x2','y2',source=source,color="red",legend=row2.name)
|
color="blue",legend=row1.name,
|
||||||
|
)
|
||||||
|
l2 = plot.line('x2','y2',source=source2,
|
||||||
|
color="red",legend=row2.name,
|
||||||
|
)
|
||||||
elif plottype=='scatter':
|
elif plottype=='scatter':
|
||||||
plot.scatter('x1','y1',source=source,legend=row1.name,fill_alpha=0.4,
|
l1 = plot.scatter('x1','y1',source=source1,legend=row1.name,
|
||||||
line_color=None)
|
fill_alpha=0.4,
|
||||||
plot.scatter('x2','y2',source=source,legend=row2.name,fill_alpha=0.4,
|
line_color=None)
|
||||||
line_color=None,color="red")
|
l2 = plot.scatter('x2','y2',source=source2,legend=row2.name,
|
||||||
|
fill_alpha=0.4,
|
||||||
|
line_color=None,color="red")
|
||||||
|
|
||||||
|
plot.add_tools(HoverTool(renderers=[l1],tooltips=TIPS))
|
||||||
|
plot.add_tools(HoverTool(renderers=[l2],tooltips=TIPS2))
|
||||||
plot.legend.location = "bottom_right"
|
plot.legend.location = "bottom_right"
|
||||||
|
|
||||||
plot.title.text = row1.name+' vs '+row2.name
|
plot.title.text = row1.name+' vs '+row2.name
|
||||||
plot.title.text_font_size=value("1.2em")
|
plot.title.text_font_size=value("1.2em")
|
||||||
plot.xaxis.axis_label = axlabels[xparam]
|
plot.xaxis.axis_label = axlabels[xparam]
|
||||||
plot.yaxis.axis_label = axlabels[yparam]
|
|
||||||
|
|
||||||
if xparam == 'time':
|
if xparam == 'time':
|
||||||
plot.xaxis[0].formatter = DatetimeTickFormatter(
|
plot.xaxis[0].formatter = DatetimeTickFormatter(
|
||||||
@@ -1863,27 +1908,10 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
|
|||||||
seconds = ["%S"],
|
seconds = ["%S"],
|
||||||
minutes = ["%M"]
|
minutes = ["%M"]
|
||||||
)
|
)
|
||||||
|
|
||||||
plot.y_range = Range1d(ymin,ymax)
|
plot.y_range = Range1d(ymin,ymax)
|
||||||
#plot.y_range = Range1d(ymin,ymax)
|
|
||||||
|
|
||||||
hover = plot.select(dict(type=HoverTool))
|
|
||||||
|
|
||||||
|
|
||||||
hover.tooltips = OrderedDict([
|
|
||||||
('time1','@ftime1'),
|
|
||||||
('time2','@ftime2'),
|
|
||||||
('pace1','@fpace1'),
|
|
||||||
('pace2','@fpace2'),
|
|
||||||
('hr1','@hr1'),
|
|
||||||
('hr2','@hr2'),
|
|
||||||
('spm1','@spm1{1.1}'),
|
|
||||||
('spm2','@spm2{1.1}'),
|
|
||||||
('distance1','@distance1{5}'),
|
|
||||||
('distance2','@distance2{5}'),
|
|
||||||
])
|
|
||||||
|
|
||||||
hover.mode = 'mouse'
|
|
||||||
|
|
||||||
script, div = components(plot)
|
script, div = components(plot)
|
||||||
|
|
||||||
return [script,div]
|
return [script,div]
|
||||||
|
|||||||
@@ -891,6 +891,7 @@ class WorkoutComment(models.Model):
|
|||||||
comment = models.TextField(max_length=300)
|
comment = models.TextField(max_length=300)
|
||||||
created = models.DateTimeField(default=timezone.now)
|
created = models.DateTimeField(default=timezone.now)
|
||||||
read = models.BooleanField(default=False)
|
read = models.BooleanField(default=False)
|
||||||
|
notification = models.BooleanField(default=False,verbose_name="Send me notifications")
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
workout = models.ForeignKey(Workout)
|
workout = models.ForeignKey(Workout)
|
||||||
|
|
||||||
@@ -905,7 +906,7 @@ class WorkoutComment(models.Model):
|
|||||||
class WorkoutCommentForm(ModelForm):
|
class WorkoutCommentForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WorkoutComment
|
model = WorkoutComment
|
||||||
fields = ['comment',]
|
fields = ['comment','notification']
|
||||||
widgets = {
|
widgets = {
|
||||||
'comment': forms.Textarea,
|
'comment': forms.Textarea,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -273,6 +273,37 @@ def handle_sendemail_invite(email,name,code,teamname,manager):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def handle_sendemailnewresponse(first_name,last_name,
|
||||||
|
email,
|
||||||
|
commenter_first_name,
|
||||||
|
commenter_last_name,
|
||||||
|
comment,
|
||||||
|
workoutname,workoutid,commentid):
|
||||||
|
fullemail = first_name+' '+last_name+' <'+email+'>'
|
||||||
|
subject = 'New comment on workout '+workoutname
|
||||||
|
message = 'Dear '+first_name+',\n\n'
|
||||||
|
message += commenter_first_name+' '+commenter_last_name
|
||||||
|
message += ' has written a new comment on the workout '
|
||||||
|
message += workoutname+'\n\n'
|
||||||
|
message += comment
|
||||||
|
message += '\n\n'
|
||||||
|
message += 'You can read the comment here:\n'
|
||||||
|
message += 'https://rowsandall.com/rowers/workout/'+str(workoutid)+'/comment'
|
||||||
|
message += '\n\n'
|
||||||
|
message += 'You are receiving this email because you are subscribed '
|
||||||
|
message += 'to comments on this workout. To unsubscribe, follow this link:\n'
|
||||||
|
message += 'https://rowsandall.com/rowers/workout/unsubscribe/'+str(workoutid)+'/'
|
||||||
|
|
||||||
|
email = EmailMessage(subject, message,
|
||||||
|
'Rowsandall <info@rowsandall.com>',
|
||||||
|
[fullemail])
|
||||||
|
|
||||||
|
|
||||||
|
res = email.send()
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def handle_sendemailnewcomment(first_name,
|
def handle_sendemailnewcomment(first_name,
|
||||||
last_name,
|
last_name,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<div class="grid_12">
|
<div class="grid_12">
|
||||||
<div class="grid_8 suffix_4">
|
<div class="grid_8 suffix_4">
|
||||||
{% include "teambuttons.html" with teamid=teamid%}
|
{% include "teambuttons.html" with teamid=team.id %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid_12 alpha">
|
<div class="grid_12 alpha">
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<div id="form" class="grid_6 alpha">
|
<div id="form" class="grid_6 alpha">
|
||||||
<form enctype="multipart/form-data" action="" method="post">
|
<form enctype="multipart/form-data" action="/rowers/workout/{{ workout.id }}/comment" method="post">
|
||||||
<table width=100%>
|
<table width=100%>
|
||||||
{{ form.as_table }}
|
{{ form.as_table }}
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ urlpatterns = [
|
|||||||
url(r'^workout/upload/(.+.*)$',views.workout_upload_view),
|
url(r'^workout/upload/(.+.*)$',views.workout_upload_view),
|
||||||
url(r'^workout/(?P<id>\d+)/histo$',views.workout_histo_view),
|
url(r'^workout/(?P<id>\d+)/histo$',views.workout_histo_view),
|
||||||
url(r'^workout/(?P<id>\d+)/forcecurve$',views.workout_forcecurve_view),
|
url(r'^workout/(?P<id>\d+)/forcecurve$',views.workout_forcecurve_view),
|
||||||
|
url(r'^workout/(?P<id>\d+)/unsubscribe$',views.workout_unsubscribe_view),
|
||||||
url(r'^workout/(?P<id>\d+)/export/c/(?P<message>\w+.*)/s/(?P<successmessage>\w+.*)$',views.workout_export_view),
|
url(r'^workout/(?P<id>\d+)/export/c/(?P<message>\w+.*)/s/(?P<successmessage>\w+.*)$',views.workout_export_view),
|
||||||
url(r'^workout/(?P<id>\d+)/export/c/(?P<message>\w+.*)$',views.workout_export_view),
|
url(r'^workout/(?P<id>\d+)/export/c/(?P<message>\w+.*)$',views.workout_export_view),
|
||||||
url(r'^workout/(?P<id>\d+)/export/s/(?P<successmessage>\w+.*)$',views.workout_export_view),
|
url(r'^workout/(?P<id>\d+)/export/s/(?P<successmessage>\w+.*)$',views.workout_export_view),
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ from rest_framework.parsers import JSONParser
|
|||||||
from rowers.rows import handle_uploaded_file
|
from rowers.rows import handle_uploaded_file
|
||||||
from rowers.tasks import handle_makeplot,handle_otwsetpower,handle_sendemailtcx,handle_sendemailcsv
|
from rowers.tasks import handle_makeplot,handle_otwsetpower,handle_sendemailtcx,handle_sendemailcsv
|
||||||
from rowers.tasks import (
|
from rowers.tasks import (
|
||||||
handle_sendemail_unrecognized,handle_sendemailnewcomment
|
handle_sendemail_unrecognized,handle_sendemailnewcomment,
|
||||||
|
handle_sendemailnewresponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
from scipy.signal import savgol_filter
|
from scipy.signal import savgol_filter
|
||||||
@@ -2064,10 +2065,6 @@ def multi_compare_view(request):
|
|||||||
if result:
|
if result:
|
||||||
promember=1
|
promember=1
|
||||||
|
|
||||||
if 'ids' in request.session:
|
|
||||||
print request.session['ids']
|
|
||||||
|
|
||||||
print request.POST
|
|
||||||
|
|
||||||
if request.method == 'POST' and 'workouts' in request.POST:
|
if request.method == 'POST' and 'workouts' in request.POST:
|
||||||
form = WorkoutMultipleCompareForm(request.POST)
|
form = WorkoutMultipleCompareForm(request.POST)
|
||||||
@@ -3586,6 +3583,37 @@ def workout_export_view(request,id=0, message="", successmessage=""):
|
|||||||
'successmessage':successmessage,
|
'successmessage':successmessage,
|
||||||
'c2userid':c2userid,
|
'c2userid':c2userid,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#
|
||||||
|
@login_required()
|
||||||
|
def workout_unsubscribe_view(request,id=0):
|
||||||
|
try:
|
||||||
|
w = Workout.objects.get(id=id)
|
||||||
|
except Workout.DoesNotExist:
|
||||||
|
raise Http404("Workout doesn't exist")
|
||||||
|
|
||||||
|
if w.privacy == 'private' and w.user.user != request.user:
|
||||||
|
return HttpResponseForbidden("Permission error")
|
||||||
|
|
||||||
|
comments = WorkoutComment.objects.filter(workout=w,
|
||||||
|
user=request.user).order_by("created")
|
||||||
|
|
||||||
|
for c in comments:
|
||||||
|
c.notify = False
|
||||||
|
c.save()
|
||||||
|
|
||||||
|
form = WorkoutCommentForm()
|
||||||
|
|
||||||
|
message = 'You have been unsubscribed from new comment notifications for this workout'
|
||||||
|
|
||||||
|
return render(request,
|
||||||
|
'workout_comments.html',
|
||||||
|
{'workout':w,
|
||||||
|
'comments':comments,
|
||||||
|
'successmessage':message,
|
||||||
|
'form':form,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
# list of comments to a workout
|
# list of comments to a workout
|
||||||
@login_required()
|
@login_required()
|
||||||
@@ -3597,6 +3625,8 @@ 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")
|
||||||
|
|
||||||
|
comments = WorkoutComment.objects.filter(workout=w).order_by("created")
|
||||||
|
|
||||||
# ok we're permitted
|
# ok we're permitted
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
@@ -3604,7 +3634,9 @@ def workout_comment_view(request,id=0):
|
|||||||
form = WorkoutCommentForm(request.POST)
|
form = WorkoutCommentForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
cd = form.cleaned_data
|
cd = form.cleaned_data
|
||||||
comment = cd['comment']
|
comment = cd['comment']
|
||||||
|
notification = cd['notification']
|
||||||
|
c = WorkoutComment(workout=w,user=request.user,comment=comment,
|
||||||
notification=notification)
|
notification=notification)
|
||||||
c.save()
|
c.save()
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
@@ -3615,6 +3647,7 @@ def workout_comment_view(request,id=0):
|
|||||||
request.user.last_name,
|
request.user.last_name,
|
||||||
comment,w.name,
|
comment,w.name,
|
||||||
w.id)
|
w.id)
|
||||||
|
|
||||||
|
|
||||||
elif request.user != r.user:
|
elif request.user != r.user:
|
||||||
res = queuehigh.enqueue(handle_sendemailnewcomment,r.user.first_name,
|
res = queuehigh.enqueue(handle_sendemailnewcomment,r.user.first_name,
|
||||||
@@ -3622,9 +3655,30 @@ def workout_comment_view(request,id=0):
|
|||||||
r.user.email,
|
r.user.email,
|
||||||
request.user.first_name,
|
request.user.first_name,
|
||||||
request.user.last_name,
|
request.user.last_name,
|
||||||
comment,w.name,w.id)
|
|
||||||
comment,w.name,w.id)
|
comment,w.name,w.id)
|
||||||
|
|
||||||
|
commenters = {oc.user for oc in comments if oc.notification}
|
||||||
|
for u in commenters:
|
||||||
|
if settings.DEBUG:
|
||||||
|
res = handle_sendemailnewresponse.delay(u.first_name,
|
||||||
|
u.last_name,
|
||||||
|
u.email,
|
||||||
|
request.user.first_name,
|
||||||
|
request.user.last_name,
|
||||||
|
comment,
|
||||||
|
w.name,
|
||||||
|
w.id,
|
||||||
|
c.id)
|
||||||
|
else:
|
||||||
|
res = queuelow.enqueue(handle_sendemailnewresponse,
|
||||||
|
u.first_name,
|
||||||
|
u.last_name,
|
||||||
|
u.email,
|
||||||
|
request.user.first_name,
|
||||||
|
request.user.last_name,
|
||||||
|
comment,
|
||||||
|
w.name,
|
||||||
|
w.id,
|
||||||
c.id)
|
c.id)
|
||||||
|
|
||||||
form = WorkoutCommentForm()
|
form = WorkoutCommentForm()
|
||||||
|
|||||||
@@ -799,9 +799,10 @@ a.wh:hover {
|
|||||||
|
|
||||||
/* talk bubble contents */
|
/* talk bubble contents */
|
||||||
.talktext{
|
.talktext{
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
.talktext p{
|
.talktext p{
|
||||||
/* remove webkit p margins */
|
/* remove webkit p margins */
|
||||||
|
|||||||
Reference in New Issue
Block a user