Skip to content
Snippets Groups Projects
Commit 7bd8552a authored by Tor Martin Frøberg Wang's avatar Tor Martin Frøberg Wang
Browse files

Merge branch 'workoutLikes' into 'dev'

Workout likes

See merge request !3
parents a5270963 fbe66920
No related branches found
No related tags found
3 merge requests!5Ad ci/cs setup,!4Dev,!3Workout likes
...@@ -2,9 +2,11 @@ ...@@ -2,9 +2,11 @@
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="d5050d50-3f7c-4f19-b4bf-cacb771bc0b4" name="Default Changelist" comment=""> <list default="true" id="d5050d50-3f7c-4f19-b4bf-cacb771bc0b4" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/backend/secfit/secfit/settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/backend/secfit/secfit/settings.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/www/exercise.html" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/www/exercise.html" afterDir="false" /> <change beforePath="$PROJECT_DIR$/backend/secfit/workouts/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/backend/secfit/workouts/views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/www/scripts/exercise.js" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/www/scripts/exercise.js" afterDir="false" /> <change beforePath="$PROJECT_DIR$/frontend/www/scripts/workouts.js" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/www/scripts/workouts.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/www/styles/style.css" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/www/styles/style.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/www/workouts.html" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/www/workouts.html" afterDir="false" />
</list> </list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
...@@ -15,79 +17,82 @@ ...@@ -15,79 +17,82 @@
<component name="FileEditorManager"> <component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300"> <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/frontend/www/exercise.html"> <entry file="file://$PROJECT_DIR$/backend/secfit/workouts/views.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="289"> <state relative-caret-position="247">
<caret line="53" column="85" selection-start-line="53" selection-start-column="85" selection-end-line="53" selection-end-column="85" /> <caret line="406" column="84" selection-start-line="406" selection-start-column="84" selection-end-line="406" selection-end-column="84" />
<folding>
<element signature="e#88#131#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="true"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/exercise.js"> <entry file="file://$PROJECT_DIR$/backend/secfit/users/views.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-506"> <state relative-caret-position="-408">
<caret line="137" column="15" selection-start-line="137" selection-start-column="15" selection-end-line="137" selection-end-column="15" /> <folding>
<element signature="e#0#13#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/backend/secfit/secfit/settings.py"> <entry file="file://$PROJECT_DIR$/frontend/www/workouts.html">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="295"> <state relative-caret-position="315">
<caret line="143" column="8" selection-start-line="143" selection-start-column="8" selection-end-line="143" selection-end-column="8" /> <caret line="57" column="27" lean-forward="true" selection-start-line="57" selection-start-column="27" selection-end-line="57" selection-end-column="27" />
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/backend/secfit/users/permissions.py"> <entry file="file://$PROJECT_DIR$/frontend/www/scripts/workouts.js">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state> <state relative-caret-position="-226">
<folding> <caret line="149" column="26" selection-start-line="149" selection-start-column="26" selection-end-line="149" selection-end-column="26" />
<element signature="e#0#38#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/permissions.py"> <entry file="file://$PROJECT_DIR$/frontend/www/scripts/exercises.js">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/frontend/www/styles/style.css"> <entry file="file://$PROJECT_DIR$/frontend/www/scripts/exercise.js">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="216">
<caret line="39" column="75" lean-forward="true" selection-start-line="39" selection-start-column="2" selection-end-line="39" selection-end-column="75" />
</state>
</provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/frontend/www/workouts.html"> <entry file="file://$PROJECT_DIR$/frontend/www/styles/style.css">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="935"> <state relative-caret-position="97">
<caret line="55" column="15" selection-start-line="55" selection-start-column="15" selection-end-line="55" selection-end-column="15" /> <caret line="74" column="21" selection-start-line="74" selection-start-column="15" selection-end-line="74" selection-end-column="21" />
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/workouts.js"> <entry file="file://$PROJECT_DIR$/backend/secfit/runtime.txt">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/workout.js"> <entry file="file://$PROJECT_DIR$/backend/secfit/seed.json">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
</file> </file>
<file pinned="false" current-in-tab="false"> <file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/models.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/manage.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor" />
<state relative-caret-position="85">
<caret line="5" column="28" selection-start-line="5" selection-end-line="6" />
</state>
</provider>
</entry> </entry>
</file> </file>
</leaf> </leaf>
...@@ -97,6 +102,13 @@ ...@@ -97,6 +102,13 @@
<find>user</find> <find>user</find>
<find>lead</find> <find>lead</find>
<find>leader</find> <find>leader</find>
<find>isow</find>
<find>isownerofw</find>
<find>status</find>
<find>like</find>
<find>DJANGO_SUPERUSER_PASSWORD</find>
<find>User</find>
<find>post</find>
</findStrings> </findStrings>
</component> </component>
<component name="Git.Settings"> <component name="Git.Settings">
...@@ -105,11 +117,18 @@ ...@@ -105,11 +117,18 @@
<component name="IdeDocumentHistory"> <component name="IdeDocumentHistory">
<option name="CHANGED_PATHS"> <option name="CHANGED_PATHS">
<list> <list>
<option value="$PROJECT_DIR$/backend/secfit/workouts/models.py" />
<option value="$PROJECT_DIR$/backend/secfit/workouts/views.py" />
<option value="$PROJECT_DIR$/backend/secfit/secfit/settings.py" /> <option value="$PROJECT_DIR$/backend/secfit/secfit/settings.py" />
<option value="$PROJECT_DIR$/frontend/www/exercise.html" />
<option value="$PROJECT_DIR$/frontend/www/scripts/exercise.js" /> <option value="$PROJECT_DIR$/frontend/www/scripts/exercise.js" />
<option value="$PROJECT_DIR$/frontend/www/exercise.html" />
<option value="$PROJECT_DIR$/backend/secfit/workouts/permissions.py" />
<option value="$PROJECT_DIR$/backend/secfit/workouts/serializers.py" />
<option value="$PROJECT_DIR$/backend/secfit/workouts/models.py" />
<option value="$PROJECT_DIR$/backend/secfit/workouts/admin.py" />
<option value="$PROJECT_DIR$/backend/secfit/workouts/urls.py" />
<option value="$PROJECT_DIR$/frontend/www/styles/style.css" />
<option value="$PROJECT_DIR$/frontend/www/workouts.html" />
<option value="$PROJECT_DIR$/backend/secfit/workouts/views.py" />
<option value="$PROJECT_DIR$/frontend/www/scripts/workouts.js" />
</list> </list>
</option> </option>
</component> </component>
...@@ -124,7 +143,6 @@ ...@@ -124,7 +143,6 @@
<foldersAlwaysOnTop value="true" /> <foldersAlwaysOnTop value="true" />
</navigator> </navigator>
<panes> <panes>
<pane id="Scope" />
<pane id="ProjectPane"> <pane id="ProjectPane">
<subPane> <subPane>
<expand> <expand>
...@@ -143,13 +161,6 @@ ...@@ -143,13 +161,6 @@
<item name="backend" type="462c0819:PsiDirectoryNode" /> <item name="backend" type="462c0819:PsiDirectoryNode" />
<item name="secfit" type="462c0819:PsiDirectoryNode" /> <item name="secfit" type="462c0819:PsiDirectoryNode" />
</path> </path>
<path>
<item name="tdt4242-base" type="b2602c69:ProjectViewProjectNode" />
<item name="tdt4242-base" type="462c0819:PsiDirectoryNode" />
<item name="backend" type="462c0819:PsiDirectoryNode" />
<item name="secfit" type="462c0819:PsiDirectoryNode" />
<item name="secfit" type="462c0819:PsiDirectoryNode" />
</path>
<path> <path>
<item name="tdt4242-base" type="b2602c69:ProjectViewProjectNode" /> <item name="tdt4242-base" type="b2602c69:ProjectViewProjectNode" />
<item name="tdt4242-base" type="462c0819:PsiDirectoryNode" /> <item name="tdt4242-base" type="462c0819:PsiDirectoryNode" />
...@@ -193,6 +204,7 @@ ...@@ -193,6 +204,7 @@
<select /> <select />
</subPane> </subPane>
</pane> </pane>
<pane id="Scope" />
</panes> </panes>
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
...@@ -226,20 +238,19 @@ ...@@ -226,20 +238,19 @@
</component> </component>
<component name="ToolWindowManager"> <component name="ToolWindowManager">
<frame x="-7" y="-7" width="1550" height="838" extended-state="6" /> <frame x="-7" y="-7" width="1550" height="838" extended-state="6" />
<editor active="true" />
<layout> <layout>
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.24983476" /> <window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.24983476" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" /> <window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info id="Favorites" order="2" side_tool="true" /> <window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" /> <window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" /> <window_info anchor="bottom" id="Find" order="1" visible="true" weight="0.3286119" />
<window_info anchor="bottom" id="Run" order="2" /> <window_info anchor="bottom" id="Run" order="2" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" /> <window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" /> <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" /> <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" /> <window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="bottom" id="Version Control" order="7" /> <window_info anchor="bottom" id="Version Control" order="7" />
<window_info anchor="bottom" id="Terminal" order="8" visible="true" weight="0.22096318" /> <window_info active="true" anchor="bottom" id="Terminal" order="8" visible="true" weight="0.22096318" />
<window_info anchor="bottom" id="Event Log" order="9" side_tool="true" /> <window_info anchor="bottom" id="Event Log" order="9" side_tool="true" />
<window_info anchor="bottom" id="Python Console" order="10" /> <window_info anchor="bottom" id="Python Console" order="10" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" /> <window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
...@@ -257,18 +268,6 @@ ...@@ -257,18 +268,6 @@
<entry file="file://$PROJECT_DIR$/backend/secfit/secfit/views.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/secfit/views.py">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/comments/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-495">
<folding>
<element signature="e#0#28#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/mixins.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/comments/urls.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/comments/urls.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state> <state>
...@@ -286,11 +285,6 @@ ...@@ -286,11 +285,6 @@
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/defaults.js"> <entry file="file://$PROJECT_DIR$/frontend/www/scripts/defaults.js">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/exercises.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-370" />
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/login.js"> <entry file="file://$PROJECT_DIR$/frontend/www/scripts/login.js">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-319" /> <state relative-caret-position="-319" />
...@@ -320,116 +314,208 @@ ...@@ -320,116 +314,208 @@
<entry file="file://$PROJECT_DIR$/backend/secfit/comments/permissions.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/comments/permissions.py">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/users/views.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/comments/views.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-3045"> <state relative-caret-position="-1600">
<folding> <folding>
<element signature="e#0#13#0" expanded="true" /> <element signature="e#0#35#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/users/models.py"> <entry file="file://$USER_HOME$/PU/gruppe-15/apartments/views.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-971"> <state relative-caret-position="-3201">
<caret line="71" column="44" lean-forward="true" selection-start-line="71" selection-start-column="44" selection-end-line="71" selection-end-column="44" />
<folding> <folding>
<element signature="e#0#28#0" expanded="true" /> <element signature="e#0#15#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/comments/views.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/users/permissions.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-1600"> <state>
<folding> <folding>
<element signature="e#0#35#0" expanded="true" /> <element signature="e#0#38#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$USER_HOME$/PU/gruppe-15/apartments/views.py"> <entry file="file://$PROJECT_DIR$/frontend/www/scripts/workout.js">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/frontend/www/exercise.html">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-3201"> <state relative-caret-position="272">
<caret line="71" column="44" lean-forward="true" selection-start-line="71" selection-start-column="44" selection-end-line="71" selection-end-column="44" /> <caret line="52" column="21" selection-start-line="52" selection-start-column="21" selection-end-line="52" selection-end-column="21" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/comments/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="321">
<caret line="45" column="5" selection-start-line="43" selection-start-column="4" selection-end-line="45" selection-end-column="5" />
<folding> <folding>
<element signature="e#0#15#0" expanded="true" /> <element signature="e#0#28#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/views.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/workouts/mixins.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/tests.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/permissions.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="600"> <state relative-caret-position="1037">
<caret line="261" column="46" selection-start-line="261" selection-start-column="46" selection-end-line="261" selection-end-column="46" /> <caret line="68" lean-forward="true" selection-start-line="68" selection-end-line="68" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/serializers.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="4" column="88" lean-forward="true" selection-start-line="4" selection-start-column="88" selection-end-line="4" selection-end-column="88" />
<folding> <folding>
<element signature="e#88#131#0" expanded="true" /> <element signature="e#48#86#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="187">
<caret line="11" lean-forward="true" selection-start-line="11" selection-end-line="11" />
<folding>
<element signature="e#89#121#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/urls.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/workouts/urls.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="408"> <state relative-caret-position="374">
<caret line="30" column="29" selection-start-line="30" selection-start-column="17" selection-end-line="30" selection-end-column="29" /> <caret line="37" column="31" selection-start-line="37" selection-start-column="31" selection-end-line="37" selection-end-column="31" />
<folding> <folding>
<element signature="e#0#37#0" expanded="true" /> <element signature="e#0#37#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/users/permissions.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/workouts/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2312">
<caret line="163" column="76" selection-start-line="163" selection-start-column="76" selection-end-line="163" selection-end-column="76" />
<folding>
<element signature="e#225#234#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/secfit/settings.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="278">
<caret line="143" column="8" selection-start-line="143" selection-start-column="8" selection-end-line="143" selection-end-column="8" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/users/forms.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state> <state>
<folding> <folding>
<element signature="e#0#38#0" expanded="true" /> <element signature="e#0#24#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/permissions.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/db.sqlite3">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
<entry file="file://$PROJECT_DIR$/frontend/www/styles/style.css"> <entry file="file://$PROJECT_DIR$/backend/secfit/users/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="901">
<caret line="55" column="67" selection-start-line="55" selection-start-column="67" selection-end-line="55" selection-end-column="67" />
<folding>
<element signature="e#0#28#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/docker-compose.yml">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
<entry file="file://$PROJECT_DIR$/frontend/www/workouts.html"> <entry file="file://$PROJECT_DIR$/backend/secfit/Dockerfile">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="935"> <state relative-caret-position="663">
<caret line="55" column="15" selection-start-line="55" selection-start-column="15" selection-end-line="55" selection-end-column="15" /> <caret line="39" column="4" selection-start-line="39" selection-start-column="4" selection-end-line="39" selection-end-column="4" />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/workouts.js"> <entry file="file://$PROJECT_DIR$/Dockerfile">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/workout.js"> <entry file="file://$PROJECT_DIR$/nginx.conf">
<provider selected="true" editor-type-id="text-editor" /> <provider selected="true" editor-type-id="text-editor" />
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/models.py"> <entry file="file://$PROJECT_DIR$/backend/secfit/runtime.txt">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/seed.json">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/manage.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/users/views.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="85"> <state relative-caret-position="-408">
<caret line="5" column="28" selection-start-line="5" selection-end-line="6" /> <folding>
<element signature="e#0#13#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/secfit/settings.py"> <entry file="file://$PROJECT_DIR$/frontend/www/styles/style.css">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="295"> <state relative-caret-position="97">
<caret line="143" column="8" selection-start-line="143" selection-start-column="8" selection-end-line="143" selection-end-column="8" /> <caret line="74" column="21" selection-start-line="74" selection-start-column="15" selection-end-line="74" selection-end-column="21" />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/frontend/www/exercise.html"> <entry file="file://$PROJECT_DIR$/frontend/www/scripts/exercises.js">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/backend/secfit/workouts/views.py">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="289"> <state relative-caret-position="247">
<caret line="53" column="85" selection-start-line="53" selection-start-column="85" selection-end-line="53" selection-end-column="85" /> <caret line="406" column="84" selection-start-line="406" selection-start-column="84" selection-end-line="406" selection-end-column="84" />
<folding>
<element signature="e#88#131#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/exercise.js"> <entry file="file://$PROJECT_DIR$/frontend/www/scripts/exercise.js">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-506"> <state relative-caret-position="216">
<caret line="137" column="15" selection-start-line="137" selection-start-column="15" selection-end-line="137" selection-end-column="15" /> <caret line="39" column="75" lean-forward="true" selection-start-line="39" selection-start-column="2" selection-end-line="39" selection-end-column="75" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/frontend/www/workouts.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="315">
<caret line="57" column="27" lean-forward="true" selection-start-line="57" selection-start-column="27" selection-end-line="57" selection-end-column="27" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/frontend/www/scripts/workouts.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-226">
<caret line="149" column="26" selection-start-line="149" selection-start-column="26" selection-end-line="149" selection-end-column="26" />
</state> </state>
</provider> </provider>
</entry> </entry>
......
...@@ -3,9 +3,10 @@ ...@@ -3,9 +3,10 @@
from django.contrib import admin from django.contrib import admin
# Register your models here. # Register your models here.
from .models import Exercise, ExerciseInstance, Workout, WorkoutFile from .models import Exercise, ExerciseInstance, Workout, WorkoutFile, WorkoutLike
admin.site.register(Exercise) admin.site.register(Exercise)
admin.site.register(ExerciseInstance) admin.site.register(ExerciseInstance)
admin.site.register(Workout) admin.site.register(Workout)
admin.site.register(WorkoutFile) admin.site.register(WorkoutFile)
admin.site.register(WorkoutLike)
# Generated by Django 3.1 on 2021-02-21 14:35
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('workouts', '0003_rememberme'),
]
operations = [
migrations.CreateModel(
name='WorkoutLike',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('userLiking', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='userLiking', to=settings.AUTH_USER_MODEL)),
('workoutToLike', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='workouts.workout')),
],
),
]
...@@ -151,3 +151,15 @@ class RememberMe(models.Model): ...@@ -151,3 +151,15 @@ class RememberMe(models.Model):
def __str__(self): def __str__(self):
return self.remember_me return self.remember_me
# Likes for a workout
class WorkoutLike(models.Model):
# The workout that is being liked
workoutToLike = models.ForeignKey(Workout, on_delete=models.CASCADE)
# The user doing the liking
userLiking = models.ForeignKey(
get_user_model(), on_delete=models.CASCADE, related_name="userLiking"
)
\ No newline at end of file
...@@ -32,6 +32,11 @@ urlpatterns = format_suffix_patterns( ...@@ -32,6 +32,11 @@ urlpatterns = format_suffix_patterns(
views.Leaderboards.as_view(), views.Leaderboards.as_view(),
name="leaderboards", name="leaderboards",
), ),
path(
"api/workoutLiking/<int:pk>/",
views.WorkoutLiking.as_view(),
name="WorkoutLiking",
),
path( path(
"api/exercise-instances/<int:pk>/", "api/exercise-instances/<int:pk>/",
views.ExerciseInstanceDetail.as_view(), views.ExerciseInstanceDetail.as_view(),
......
...@@ -7,6 +7,7 @@ from rest_framework.parsers import ( ...@@ -7,6 +7,7 @@ from rest_framework.parsers import (
JSONParser, JSONParser,
) )
import json import json
from rest_framework import status
from rest_framework.decorators import api_view from rest_framework.decorators import api_view
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
...@@ -23,7 +24,7 @@ from workouts.permissions import ( ...@@ -23,7 +24,7 @@ from workouts.permissions import (
IsWorkoutPublic, IsWorkoutPublic,
) )
from workouts.mixins import CreateListModelMixin from workouts.mixins import CreateListModelMixin
from workouts.models import Workout, Exercise, ExerciseInstance, WorkoutFile from workouts.models import Workout, Exercise, ExerciseInstance, WorkoutFile, WorkoutLike
from workouts.serializers import WorkoutSerializer, ExerciseSerializer from workouts.serializers import WorkoutSerializer, ExerciseSerializer
from workouts.serializers import RememberMeSerializer from workouts.serializers import RememberMeSerializer
from workouts.serializers import ExerciseInstanceSerializer, WorkoutFileSerializer from workouts.serializers import ExerciseInstanceSerializer, WorkoutFileSerializer
...@@ -380,3 +381,35 @@ class WorkoutFileDetail( ...@@ -380,3 +381,35 @@ class WorkoutFileDetail(
def delete(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs) return self.destroy(request, *args, **kwargs)
# View for fetching like amount, and for creating new likes
class WorkoutLiking(APIView):
permission_classes = [permissions.IsAuthenticated]
# Returns a tuple with a boolean value that is true if liking is allowed (the workout does not belong to the user
# and the workout has not been liked before), and the amount of likes that the workout has
def get(self, request, pk):
likingAllowed = Workout.objects.get(pk=pk).owner != self.request.user and WorkoutLike.objects.filter(
Q(userLiking=self.request.user) & Q(workoutToLike__pk=pk)).count() == 0
likeAmount = WorkoutLike.objects.filter(Q(workoutToLike__pk=pk)).count() + 1
return Response((likingAllowed, likeAmount), status.HTTP_200_OK)
# Tries to like a new post and returns the same as the GET above
def post(self, request, pk):
likingAllowed = Workout.objects.get(pk=pk).owner != self.request.user and WorkoutLike.objects.filter(
Q(userLiking=self.request.user) & Q(workoutToLike__pk=pk)).count() == 0
likeAmount = WorkoutLike.objects.filter(Q(workoutToLike__pk=pk)).count() + 1
if likingAllowed:
newWorkoutLike = WorkoutLike(workoutToLike=Workout.objects.get(pk=pk), userLiking=self.request.user)
newWorkoutLike.save()
return Response((False, likeAmount + 1), status.HTTP_201_CREATED)
return Response((likingAllowed, likeAmount), status.HTTP_100_CONTINUE)
\ No newline at end of file
...@@ -8,7 +8,17 @@ async function fetchWorkouts(ordering) { ...@@ -8,7 +8,17 @@ async function fetchWorkouts(ordering) {
let workouts = data.results; let workouts = data.results;
let container = document.getElementById('div-content'); let container = document.getElementById('div-content');
workouts.forEach(workout => {
for(const workout of workouts){
let workoutLikes = await sendRequest("GET", `${HOST}/api/workoutLiking/${workout.id}`);
let workoutLikesData = [true, 1]
if(workoutLikes.ok){
workoutLikesData = await workoutLikes.json()
}
let templateWorkout = document.querySelector("#template-workout"); let templateWorkout = document.querySelector("#template-workout");
let cloneWorkout = templateWorkout.content.cloneNode(true); let cloneWorkout = templateWorkout.content.cloneNode(true);
...@@ -27,8 +37,35 @@ async function fetchWorkouts(ordering) { ...@@ -27,8 +37,35 @@ async function fetchWorkouts(ordering) {
rows[2].querySelectorAll("td")[1].textContent = workout.owner_username; //Owner rows[2].querySelectorAll("td")[1].textContent = workout.owner_username; //Owner
rows[3].querySelectorAll("td")[1].textContent = workout.exercise_instances.length; // Exercises rows[3].querySelectorAll("td")[1].textContent = workout.exercise_instances.length; // Exercises
rows[4].querySelectorAll("td")[1].textContent = workoutLikesData[1]
let likeButton = rows[4].querySelectorAll("td")[2].querySelector(".like-button")
if(!workoutLikesData[0]){
likeButton.classList.add("active")
}
likeButton.addEventListener("click", async function(e) {
e.preventDefault();
if(!this.classList.contains("active")){
this.classList.add("active");
this.classList.add("animated");
generateClones(this);
let likeWorkoutResponse = await sendRequest("POST", `${HOST}/api/workoutLiking/${workout.id}/`, {});
if(likeWorkoutResponse.ok){
let likeWorkoutData = await likeWorkoutResponse.json()
rows[4].querySelectorAll("td")[1].textContent = likeWorkoutData[1]
likeButton.classList.add("active")
}
}
})
container.appendChild(aWorkout); container.appendChild(aWorkout);
}); };
return workouts; return workouts;
} }
} }
...@@ -103,4 +140,48 @@ window.addEventListener("DOMContentLoaded", async () => { ...@@ -103,4 +140,48 @@ window.addEventListener("DOMContentLoaded", async () => {
} }
}); });
} }
}); });
\ No newline at end of file
function generateClones(button) {
let clones = randomInt(4, 7);
for (let it = 1; it <= clones; it++) {
let clone = button.querySelector("svg").cloneNode(true),
size = randomInt(5, 16);
button.appendChild(clone);
clone.setAttribute("width", size);
clone.setAttribute("height", size);
clone.style.position = "absolute";
clone.style.transition =
"transform 0.5s cubic-bezier(0.12, 0.74, 0.58, 0.99) 0.3s, opacity 1s ease-out .5s";
let animTimeout = setTimeout(function() {
clearTimeout(animTimeout);
clone.style.transform =
"translate3d(" +
(plusOrMinus() * randomInt(10, 25)) +
"px," +
(plusOrMinus() * randomInt(10, 25)) +
"px,0)";
clone.style.opacity = 0;
}, 1);
let removeNodeTimeout = setTimeout(function() {
clone.parentNode.removeChild(clone);
clearTimeout(removeNodeTimeout);
}, 900);
let removeClassTimeout = setTimeout( function() {
button.classList.remove("animated")
}, 600);
}
}
function plusOrMinus() {
return Math.random() < 0.5 ? -1 : 1;
}
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
...@@ -62,3 +62,96 @@ ...@@ -62,3 +62,96 @@
.link-block { .link-block {
display: block; display: block;
} }
/*
Like button example from https://codepen.io/abaicus/pen/gNXdQP/
*/
.like-button {
display: flex;
align-items: center;
justify-content: center;
}
.like-button.animated {
-webkit-animation: pop 0.9s both;
animation: pop 0.9s both;
}
.like-button svg {
opacity: 1;
}
.like-button svg path {
fill: #333;
transition: fill .4s ease-out;
}
.like-button.active svg path {
fill: #2196f3;
}
.like-button.active {
pointer-events: none;
}
@-webkit-keyframes pop {
0% {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
30% {
-webkit-transform: scale3d(1.25, 0.75, 1);
transform: scale3d(1.25, 0.75, 1);
}
40% {
-webkit-transform: scale3d(0.75, 1.25, 1);
transform: scale3d(0.75, 1.25, 1);
}
50% {
-webkit-transform: scale3d(1.15, 0.85, 1);
transform: scale3d(1.15, 0.85, 1);
}
65% {
-webkit-transform: scale3d(0.95, 1.05, 1);
transform: scale3d(0.95, 1.05, 1);
}
75% {
-webkit-transform: scale3d(1.05, 0.95, 1);
transform: scale3d(1.05, 0.95, 1);
}
100% {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
}
@keyframes pop {
0% {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
30% {
-webkit-transform: scale3d(1.25, 0.75, 1);
transform: scale3d(1.25, 0.75, 1);
}
40% {
-webkit-transform: scale3d(0.75, 1.25, 1);
transform: scale3d(0.75, 1.25, 1);
}
50% {
-webkit-transform: scale3d(1.15, 0.85, 1);
transform: scale3d(1.15, 0.85, 1);
}
65% {
-webkit-transform: scale3d(0.95, 1.05, 1);
transform: scale3d(0.95, 1.05, 1);
}
75% {
-webkit-transform: scale3d(1.05, 0.95, 1);
transform: scale3d(1.05, 0.95, 1);
}
100% {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
}
\ No newline at end of file
...@@ -50,6 +50,18 @@ ...@@ -50,6 +50,18 @@
<tr><td>Time:</td><td></td></tr> <tr><td>Time:</td><td></td></tr>
<tr><td>Owner:</td><td></td></tr> <tr><td>Owner:</td><td></td></tr>
<tr><td>Exercises:</td><td></td></tr> <tr><td>Exercises:</td><td></td></tr>
<tr>
<td>
Likes:
</td>
<td></td>
<td>
<a href="#" class="like-button">
<?xml version="1.0" encoding="utf-8"?>
<svg width="20" height="20" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M320 1344q0-26-19-45t-45-19q-27 0-45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45-18.5t19-45.5zm160-512v640q0 26-19 45t-45 19h-288q-26 0-45-19t-19-45v-640q0-26 19-45t45-19h288q26 0 45 19t19 45zm1184 0q0 86-55 149 15 44 15 76 3 76-43 137 17 56 0 117-15 57-54 94 9 112-49 181-64 76-197 78h-129q-66 0-144-15.5t-121.5-29-120.5-39.5q-123-43-158-44-26-1-45-19.5t-19-44.5v-641q0-25 18-43.5t43-20.5q24-2 76-59t101-121q68-87 101-120 18-18 31-48t17.5-48.5 13.5-60.5q7-39 12.5-61t19.5-52 34-50q19-19 45-19 46 0 82.5 10.5t60 26 40 40.5 24 45 12 50 5 45 .5 39q0 38-9.5 76t-19 60-27.5 56q-3 6-10 18t-11 22-8 24h277q78 0 135 57t57 135z"/></svg>
</a>
</td>
</tr>
</table> </table>
</div> </div>
</a> </a>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment