aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluxagraf <sng@luxagraf.net>2018-11-29 16:57:26 -0600
committerluxagraf <sng@luxagraf.net>2018-11-29 16:57:26 -0600
commit4974eb58480f413c67f5f6e8fac430186eda2b62 (patch)
tree7402ecba682dbda38db4b6db221cc8378a390977
parent0c2a092e8d8ad33a1c306ee9efca0da96eb56415 (diff)
uploading all recent changes ahead of sys upgrade
-rw-r--r--.gitignore3
-rw-r--r--README.md3
-rw-r--r--apps/accounts/models.py9
-rw-r--r--apps/accounts/views.py4
-rw-r--r--apps/notes/forms.py11
-rw-r--r--apps/notes/models.py4
-rw-r--r--apps/notes/serializers.py4
-rw-r--r--apps/notes/urls.py6
-rw-r--r--apps/notes/views.py62
-rw-r--r--apps/utils/util.py5
-rw-r--r--config/base_urls.py13
-rw-r--r--config/settings.py4
-rw-r--r--design/sass/_forms.scss34
-rw-r--r--design/sass/_global.scss17
-rw-r--r--design/sass/_header.scss44
-rw-r--r--design/sass/_notes.scss269
-rw-r--r--design/templates/base.html39
-rw-r--r--design/templates/notes/notebook_create.html46
-rw-r--r--design/templates/notes/notebook_detail.html49
-rw-r--r--design/templates/notes/notes_detail.html38
-rw-r--r--design/templates/notes/notes_list.html34
-rw-r--r--design/templates/notes/notes_listold.html9
-rw-r--r--design/templates/sell.html6
-rw-r--r--scripts/gulpfile.js17
-rw-r--r--scripts/package.json20
-rw-r--r--scripts/src/js.cookie.js165
-rw-r--r--scripts/src/main-nav.js71
-rw-r--r--scripts/src/overlay.js (renamed from scripts/overlay.js)0
-rw-r--r--scripts/src/util.js (renamed from scripts/util.js)35
29 files changed, 950 insertions, 71 deletions
diff --git a/.gitignore b/.gitignore
index 69f3431..6d6fa2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,6 @@ htmlcov/
.sass-cache/
media/
static/
+scripts/node_modules
+scripts/package-lock.json
+scripts/quill
diff --git a/README.md b/README.md
index 872c983..c87cb3b 100644
--- a/README.md
+++ b/README.md
@@ -38,3 +38,6 @@ Create, edit and view notes
#### [Django-Extensions](https://github.com/django-extensions/django-extensions)
* Because I'd go crazy without it. shell_plus is a godsend
+
+## Art credits
+<div>Icons made by <a href="https://www.freepik.com/" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>
diff --git a/apps/accounts/models.py b/apps/accounts/models.py
index 5ed7634..d000e3e 100644
--- a/apps/accounts/models.py
+++ b/apps/accounts/models.py
@@ -1,5 +1,8 @@
from django.db import models
from django.contrib.auth.models import AbstractUser
+from django.utils.functional import cached_property
+
+from notes.models import Notebook
class User(AbstractUser):
@@ -10,7 +13,7 @@ class User(AbstractUser):
class UserProfile(models.Model):
- user = models.OneToOneField(User, on_delete=models.CASCADE)
+ user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
photo = models.ImageField(upload_to='profile', null=True, blank=True)
website = models.CharField(max_length=300, null=True, blank=True, default='')
location = models.CharField(max_length=300, null=True, blank=True, default='')
@@ -20,3 +23,7 @@ class UserProfile(models.Model):
def __str__(self):
return self.user.username
+
+ @cached_property
+ def get_notebook_list(self):
+ return Notebook.objects.filter(owner=self.user).select_related()[:8]
diff --git a/apps/accounts/views.py b/apps/accounts/views.py
index e51c60e..d463522 100644
--- a/apps/accounts/views.py
+++ b/apps/accounts/views.py
@@ -21,7 +21,7 @@ class ProfileView(UpdateViewWithUser):
template_name = "accounts/profile.html"
def get_object(self):
- return self.request.user.userprofile
+ return self.request.user.profile
class SettingsListView(DetailView):
@@ -29,4 +29,4 @@ class SettingsListView(DetailView):
template_name = "accounts/profile.html"
def get_object(self):
- return self.request.user.userprofile
+ return self.request.user.profile
diff --git a/apps/notes/forms.py b/apps/notes/forms.py
index a7a4f8d..c1df176 100644
--- a/apps/notes/forms.py
+++ b/apps/notes/forms.py
@@ -1,7 +1,7 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
-from .models import Note
+from .models import Note, Notebook
class NoteForm(forms.ModelForm):
@@ -15,3 +15,12 @@ class NoteForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user", None)
super(NoteForm, self).__init__(*args, **kwargs)
+
+
+class NotebookForm(NoteForm):
+ class Meta:
+ model = Notebook
+ fields = ['name']
+ labels = {
+ "name": _("Notebook Name"),
+ }
diff --git a/apps/notes/models.py b/apps/notes/models.py
index 83766a9..c0b23ce 100644
--- a/apps/notes/models.py
+++ b/apps/notes/models.py
@@ -33,6 +33,10 @@ class Notebook(models.Model):
self.slug = unique_slug_generator(self)
super(Notebook, self).save()
+ @cached_property
+ def get_absolute_url(self):
+ return reverse("notes:notebook-detail", kwargs={"user": self.owner.username, "slug": self.slug})
+
class Note(models.Model):
unique_id = models.UUIDField(default=uuid.uuid4, editable=False)
diff --git a/apps/notes/serializers.py b/apps/notes/serializers.py
index 2fbcc1f..daef52e 100644
--- a/apps/notes/serializers.py
+++ b/apps/notes/serializers.py
@@ -13,6 +13,8 @@ class NoteSerializer(TaggitSerializer, serializers.ModelSerializer):
class NotebookSerializer(serializers.HyperlinkedModelSerializer):
+ json_absolute_url = serializers.URLField(source='get_absolute_url', read_only=True)
+
class Meta:
model = Notebook
- fields = ('name',)
+ fields = ('name', 'json_absolute_url')
diff --git a/apps/notes/urls.py b/apps/notes/urls.py
index ccfcc9e..a79c7cd 100644
--- a/apps/notes/urls.py
+++ b/apps/notes/urls.py
@@ -5,12 +5,18 @@ from .views import (
NoteCreateView,
NoteListView,
NoteListRedirectView,
+ NotebookListView,
+ NotebookDetailView,
+ NoteTagView,
)
app_name = "notes"
urlpatterns = [
path(r'create/', NoteCreateView.as_view(), name='note-create',),
+ path(r'<str:user>/tagged/<slug>', NoteTagView.as_view(), name='note-tag',),
+ path(r'<str:user>/notebooks/<slug>', NotebookDetailView.as_view(), name='notebook-detail',),
+ path(r'<str:user>/notebooks/', NotebookListView.as_view(), name='notebook-list',),
path(r'<str:user>/<slug>', NoteDetailView.as_view(), name='note-detail',),
path(r'<str:user>/', NoteListView.as_view(), name='note-list',),
path(r'', NoteListRedirectView.as_view(), name='note-redirect',),
diff --git a/apps/notes/views.py b/apps/notes/views.py
index b971390..d885ad9 100644
--- a/apps/notes/views.py
+++ b/apps/notes/views.py
@@ -13,7 +13,7 @@ from rest_framework import permissions
from .serializers import NoteSerializer, NotebookSerializer
from .models import Note, Notebook
-from .forms import NoteForm
+from .forms import NoteForm, NotebookForm
@method_decorator(login_required, name='dispatch')
@@ -40,6 +40,35 @@ class NoteListView(LoggedInViewWithUser, ListView):
return ['sell.html']
+class NoteTagView(LoggedInViewWithUser, ListView):
+ model = Note
+ template_name = 'notes/notes_list.html'
+
+ def get_queryset(self):
+ '''
+ This can generate a crazy amount of joins if there's a lot of tags
+ have to keep an eye on it. Would be better to do:
+ from django.db.models import Q
+ from functools import reduce
+ from operator import and_, or_
+ #query = reduce(and_, (Q(tags__slug=t) for t in self.tag_list))
+ # Note.objects.filter(query, owner=self.request.user)
+ But that doesn't work for some reason.
+ '''
+ if not self.request.user.is_anonymous:
+ self.tag_list = [x.strip() for x in self.kwargs['slug'].split("+")]
+ qs = Note.objects.filter(owner=self.request.user)
+ for tag in self.tag_list:
+ qs = qs.filter(tags__slug=tag)
+ return qs
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['notes_list'] = Note.objects.filter(owner=self.request.user)
+ context['tags'] = self.tag_list
+ return context
+
+
class NoteListRedirectView(RedirectView, LoggedInViewWithUser):
def get_redirect_url(self, *args, **kwargs):
@@ -75,6 +104,34 @@ class NoteCreateView(CreateView, LoggedInViewWithUser):
return reverse_lazy('notes:note-detail', kwargs={'user': self.request.user.username, 'slug': self.object.slug})
+class NotebookListView(CreateView, LoggedInViewWithUser):
+ model = Notebook
+ form_class = NotebookForm
+ template_name = 'notes/notebook_create.html'
+
+ def get_queryset(self):
+ if not self.request.user.is_anonymous:
+ return Notebook.objects.filter(owner=self.request.user)
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['notebook_list'] = Notebook.objects.filter(owner=self.request.user)
+ context['notes_list'] = Note.objects.filter(owner=self.request.user).select_related()
+ return context
+
+
+class NotebookDetailView(DetailView, LoggedInViewWithUser):
+ model = Notebook
+
+ def get_object(self):
+ return get_object_or_404(self.get_queryset().select_related(), owner=self.request.user, slug=self.kwargs["slug"])
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['notes_list'] = Note.objects.filter(owner=self.request.user).select_related()
+ return context
+
+
class IsOwnerOrDeny(permissions.BasePermission):
"""
Custom permission to only allow owners to post to their endpoint
@@ -118,3 +175,6 @@ class NotebookViewSet(viewsets.ModelViewSet):
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
+
+ def get_menu_data(self, serializer):
+ return Notebook.objects.filter(owner=self.request.user).order_by('-name')[:1]
diff --git a/apps/utils/util.py b/apps/utils/util.py
index 899b73f..415704c 100644
--- a/apps/utils/util.py
+++ b/apps/utils/util.py
@@ -95,7 +95,10 @@ def unique_slug_generator(instance, new_slug=None):
if new_slug is not None:
slug = new_slug
else:
- slug = slugify(instance.title)
+ try:
+ slug = slugify(instance.title)
+ except AttributeError:
+ slug = slugify(instance.name)
Klass = instance.__class__
qs_exists = Klass.objects.filter(slug=slug).exists()
if qs_exists:
diff --git a/config/base_urls.py b/config/base_urls.py
index 953ceae..c881679 100644
--- a/config/base_urls.py
+++ b/config/base_urls.py
@@ -15,10 +15,15 @@ from notes.views import (
NotebookViewSet,
NoteListView,
)
+
+# redirect admin as per Adrian holovaty's site
+ADMIN_URL = 'https://docs.djangoproject.com/en/dev/ref/contrib/admin/'
+
router = routers.DefaultRouter()
-router.register(r'notes/notebook/', NotebookViewSet, basename="notebook-api")
+router.register(r'notes/notebook', NotebookViewSet, basename="notebook-api")
router.register(r'notes', NoteViewSet, basename="notes-api")
-ADMIN_URL = 'https://docs.djangoproject.com/en/dev/ref/contrib/admin/'
+
+
urlpatterns = static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += [
path('admin/', RedirectView.as_view(url=ADMIN_URL)),
@@ -31,11 +36,12 @@ urlpatterns += [
path(r'', include('django.contrib.auth.urls')),
path(r'', NoteListView.as_view(), name='homepage',),
path(r'notes/', include('notes.urls')),
- path(r'api/', include(router.urls)),
+ path(r'api/v1/', include(router.urls)),
path(r'<slug>', PageDetailView.as_view(), name="pages"),
#path(r'<path>/<slug>/', PageDetailView.as_view(), name="pages"),
path(r'api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
+'''
if settings.DEBUG:
import debug_toolbar
urlpatterns = [
@@ -45,3 +51,4 @@ if settings.DEBUG:
# url(r'^__debug__/', include(debug_toolbar.urls)),
] + urlpatterns
+'''
diff --git a/config/settings.py b/config/settings.py
index b95c18d..da75f57 100644
--- a/config/settings.py
+++ b/config/settings.py
@@ -64,7 +64,7 @@ THIRD_PARTY_APPS = [
'taggit_serializer',
'django_extensions',
'rest_framework',
- 'debug_toolbar'
+ #'debug_toolbar'
]
LOCAL_APPS = [
'utils',
@@ -80,7 +80,7 @@ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
- 'debug_toolbar.middleware.DebugToolbarMiddleware',
+ #'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
diff --git a/design/sass/_forms.scss b/design/sass/_forms.scss
index d6b0931..5923e1f 100644
--- a/design/sass/_forms.scss
+++ b/design/sass/_forms.scss
@@ -101,6 +101,40 @@ table {
color: $link_color !important;
}
}
+.btn-hollow {
+ @include fontsize(17);
+ padding: 6px 8px;
+ border: none; //1px solid $body_font_light;
+ color: $link_color !important;
+ outline: $link_color !important;
+ background: white;
+ border: 1px solid $link_color;
+ &:hover {
+ background: white;
+ color: $link_color !important;
+ }
+}
+.btn-link {
+ @include fontsize(15);
+ padding: 0;
+ border: none; //1px solid $body_font_light;
+ color: lighten($body_font_color, 15) !important;
+ background: white;
+ border: none;
+ &:hover {
+ background: white;
+ color: $body_font_color !important;
+ }
+}
+.save {
+ color: white !important;
+ background: $link_color !important;
+ &:hover {
+ background: $link_color;
+ color: white !important;
+ }
+
+}
.btn-accent {
padding: 3px 5px;
border: 1px solid $text_accent;
diff --git a/design/sass/_global.scss b/design/sass/_global.scss
index d394042..c242ace 100644
--- a/design/sass/_global.scss
+++ b/design/sass/_global.scss
@@ -152,7 +152,7 @@ h3 {
}
}
.wrapper {
- @include constrain_wide;
+ @include constrain(1440px);
//margin-top: 5rem;
}
//************** Universals ************************
@@ -186,6 +186,21 @@ h3 {
.left-margin-2 {
margin-left: 2px;
}
+.right-padding-0 {
+ padding-right: 0 !important;
+}
+.center {
+ text-align: center;
+ margin-right: auto;
+ margin-left: auto;
+}
+.list-style-none {
+ list-style-type: none;
+ padding: 0;
+}
+.vertical li {
+ display: block;
+}
//************** other global classes ************************
.sans {
@include generic_sans;
diff --git a/design/sass/_header.scss b/design/sass/_header.scss
index 7f98419..487f1fc 100644
--- a/design/sass/_header.scss
+++ b/design/sass/_header.scss
@@ -54,3 +54,47 @@ nav {
}
}
}
+.dropmenu {
+ outline: white;
+ position: absolute;
+ z-index: 10;
+ margin-top: 4px;
+ margin-left: 2rem;
+ background: #fff;
+ color: #60516E;
+ padding: 10px;
+ border-radius: 4px;
+ border: 1px solid rgba(0,0,0,0.05);
+ filter: drop-shadow(0 0px 4px rgba(0,0,0,0.08));
+ &:after {
+ top: unset;
+ left: unset;
+ margin-left: unset;
+ border-top-color: unset;
+ content: "";
+ position: absolute;
+ border: 10px solid transparent;
+ bottom: 100%;
+ left: 50%;
+ margin-left: -10px;
+ border-bottom-color: white;
+ }
+ a, a:visited {
+ color: lighten($body_font_color, 15);
+ }
+ a:hover {
+ color: $body_font_color;
+ }
+ .menu-divider {
+ border-top: 1px solid #e7e2ee;
+ padding: 8px 16px 0;
+ margin: 8px -10px 0;
+ }
+ li {
+ margin-top: 4px;
+ margin-bottom: 4px;
+ }
+}
+#user-menu {
+ margin-left: 4rem;
+}
diff --git a/design/sass/_notes.scss b/design/sass/_notes.scss
index 09d234a..cd10e39 100644
--- a/design/sass/_notes.scss
+++ b/design/sass/_notes.scss
@@ -1,25 +1,163 @@
+main {
+ width: 100%;
+ display: flex ;
+ align-items: stretch ;
+ flex-flow: row wrap ;
+ margin: 0;
+}
+.svg-icon-arrow {
+ display: block;
+ z-index: 2;
+ width: 18px;
+ height: 18px;
+ &:hover {
+ -moz-transform: scaleX(-1);
+ -o-transform: scaleX(-1);
+ -webkit-transform: scaleX(-1);
+ transform: scaleX(-1);
+ filter: FlipH;
+ -ms-filter: "FlipH";
+ transition: 0.5s;
+ }
+}
+.note-list-container, .balance-container {
+ position: relative;
+ order: 1;
+ z-index: 1;
+ visibility: hidden;
+ //background: #fbfafa;
+ padding: 4px;
+ border-left: 1px #f9f9f9 solid;
+ max-width: 320px;
+ .list-note-preview {
+ li {
+ height: 4.5rem;
+ }
+ h4 {
+ @include fontsize(15);
+ }
+ }
+ .note-preview {
+ overflow: hidden;
+ white-space: nowrap;
+ }
+}
+.balance-container {
+ order: 3;
+ min-width: 320px;
+}
+.list-notebook {
+
+}
+.icon-notebook {
+ display: inline-block;
+ content: " ";
+ width: 24px;
+ height: 24px;
+ background: url('/media/moleskine.svg');
+}
+.list-note-preview {
+ padding: 0;
+ margin: 0;
+ list-style-type: none;
+ li {
+ @include fontsize(13);
+ min-height: 4.5rem;
+ box-shadow: 0 -1px 0 #e7e2ee inset;
+ margin: 0;
+ padding: 6px 12px;
+ &:hover {
+ background: #f1f1f1;
+ }
+ a {
+ color: lighten($body_font_color, 15);
+ text-decoration: none;
+ }
+ }
+ h4 {
+ @include fontsize(16);
+ margin: 0;
+ padding: 8px 0 8px 6px;
+ font-weight: normal;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+ .note-preview {
+ padding-left: 6px;
+ margin-bottom: 16px;
+ margin-right: 6px;
+ }
+}
.note-title {
- @include fontsize(22);
+ @include fontsize(26);
}
.note-header {
@extend %clearfix;
}
-.note-header-float {
- width: 30%;
- float: right;
+.note-header-right {
text-align: right;
+ float: right;
+ width: 50%;
}
.note-time, .note-url {
text-align: right;
@include fancy-sans;
+ @include fontsize(12);
+ margin-bottom: 0;
+ text-transform: uppercase;
+}
+.note-url {
+ margin-top: 0;
+}
+.note-header {
+ margin-top: 1rem;
+ margin-bottom: 3rem;
+}
+.edit-btn-wrapper{
+ text-align: right;
+}
+.note-header-left {
+ @include fancy-sans;
@include fontsize(13);
+ float: left;
+ width: 50%;
+ .label {
+ text-transform: uppercase;
+ @include fontsize(11);
+ color: $body_font_light;
+ margin-right: 4px;
+ }
+ ul {
+ display: inline-block;
+ padding: 0;
+ margin-bottom: 0;
+ }
+ li {
+ margin-right: 4px;
+ display: inline-block;
+ }
+ a {
+ text-decoration: none;
+ color: darken($body_font_light, 5);;
+ &:hover {
+ color: darken($body_font_light, 25);
+ }
+ }
+}
+.notebook {
+ display: block;
}
.note-container {
- @include constrain(80%);
+ max-width: 60%;
+ position: relative;
+ flex:1;
+ order: 2;
+ background: #fff;
+ z-index: 4;
}
#note-body {
@include fancy-sans;
- @include fontsize(15);
+ @include fontsize(14);
}
.inactive {
.ql-editor {
@@ -39,33 +177,94 @@
font-size:inherit;
}
}
-.note-list-container {
- max-width: 300px;
- ul {
- padding: 0;
- list-style-type: none;
- }
- li {
- @include fontsize(13);
- height: 4.5rem;
- box-shadow: 0 -1px 0 #e7e2ee inset;
- margin: 0;
- a {
- color: lighten($body_font_color, 15);
- text-decoration: none;
- }
- }
- h4 {
- @include fontsize(15);
- margin: 0;
- padding: 8px 0 8px 6px;
- font-weight: normal;
- overflow: hidden;
- white-space: nowrap;
- }
- .note-preview {
- padding-left: 6px;
- overflow: hidden;
- white-space: nowrap;
- }
+#user-menu, #notebooks-menu {
+ display: none;
+}
+.active {
+ display: block !important;
+}
+
+/*
+
+Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>
+
+*/
+
+.hljs, pre.ql-syntax {
+ display: block;
+ overflow-x: auto;
+ padding: 0.5em;
+ background: #002b36 !important;
+ color: #839496;
+}
+
+.hljs-comment,
+.hljs-quote {
+ color: #586e75;
+}
+
+/* Solarized Green */
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-addition {
+ color: #859900;
+}
+
+/* Solarized Cyan */
+.hljs-number,
+.hljs-string,
+.hljs-meta .hljs-meta-string,
+.hljs-literal,
+.hljs-doctag,
+.hljs-regexp {
+ color: #2aa198;
+}
+
+/* Solarized Blue */
+.hljs-title,
+.hljs-section,
+.hljs-name,
+.hljs-selector-id,
+.hljs-selector-class {
+ color: #268bd2;
+}
+
+/* Solarized Yellow */
+.hljs-attribute,
+.hljs-attr,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-class .hljs-title,
+.hljs-type {
+ color: #b58900;
+}
+
+/* Solarized Orange */
+.hljs-symbol,
+.hljs-bullet,
+.hljs-subst,
+.hljs-meta,
+.hljs-meta .hljs-keyword,
+.hljs-selector-attr,
+.hljs-selector-pseudo,
+.hljs-link {
+ color: #cb4b16;
+}
+
+/* Solarized Red */
+.hljs-built_in,
+.hljs-deletion {
+ color: #dc322f;
+}
+
+.hljs-formula {
+ background: #073642;
+}
+
+.hljs-emphasis {
+ font-style: italic;
+}
+
+.hljs-strong {
+ font-weight: bold;
}
diff --git a/design/templates/base.html b/design/templates/base.html
index f14e5df..bb54717 100644
--- a/design/templates/base.html
+++ b/design/templates/base.html
@@ -20,8 +20,16 @@
<div class="head-wrapper">
<header>
<nav class="left">
- <ul>
- <li><a href="/" title="">Home</a></li>
+ <ul>{% if not request.user.is_anonymous %}
+ <li><a href="{%url 'notes:note-list' user.username %}">Notes</a></li>
+ <li><a id="notebook-menu-link" href="{%url 'notes:notebook-list' user.username %}" title="view notebooks">Notebooks</a>
+ <div id="notebooks-menu" class="dropmenu">
+ <ul id="notebooks-menu-list" class="list-style-none vertical">{% for obj in user.profile.get_notebook_list %}
+ <li><a href="{{obj.get_absolute_url}}">{{obj}}</a></li>
+ {% endfor %}</ul>
+ </div>
+ </li>{%else%}
+ <li><a href="/" title="">Home</a></li>{%endif%}
</ul>
</nav>
<div class="logo"></div>
@@ -29,8 +37,23 @@
<ul>
<li><a href="{% url 'pages' slug='tour' %}" title="">Tour</a></li>
<li><a href="{% url 'pages' slug='howto' %}" title="">How to</a></li>{% if not request.user.is_anonymous %}
- <li><a href="{% url 'settings' %}" title="">Account</a></li>
- <li><a href="{% url 'logout' %}" title="">Log out</a></li>{% else %}
+ <li><a id="account-menu" href="{% url 'settings' %}" title="">Account</a>
+ <div id="user-menu" class="dropmenu" tabindex="-1">
+ <ul id="user-menu-list" class="list-style-none vertical">
+ <li><a href="/users/luxagraf/" class="">Your Notes</a></li>
+ <li><a href="/settings/" class="">Account settings</a></li>
+ <li><a href="/plans/" class="">Subscription plans</a></li>
+ </ul>
+ <ul class="menu-divider list-style-none">
+ <li>
+ <form action="/logout/" method="post">
+ <input type="hidden" name="a" value="3">
+ <button type="submit" value="Log out" class="btn-link">Log out</button>
+ </form>
+ </li>
+ </ul>
+ </div>
+ </li>{% else %}
<li><a href="{% url 'login' %}" title="" id="overlay-trigger" data-element="#js-overlay-content">Login</a></li>
<li><a href="{% url 'django_registration_register' %}" title="" class="btn">Get Started</a></li>{% endif %}
</ul>
@@ -38,12 +61,12 @@
</header>
</div>
<div class="wrapper">
- <ul class="breadcrumb" id="breadcrumbs" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+ {%comment%}<ul class="breadcrumb" id="breadcrumbs" itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<li>
<a href="/" title="home" itemprop="url"><span itemprop="title">Home</span></a>
</li>
{% block breadcrumbs %}{% endblock %}
- </ul>
+ </ul>{%endcomment%}
{% block content %}
{% endblock %}
</div>
@@ -65,9 +88,11 @@
<script async src="/media/js/package.min.js"></script>
{% block jsinclude %}{%endblock%}
<script>
-// Waiting for the DOM to load
+
+
document.addEventListener("DOMContentLoaded", function () {
{% block jsdomready %}{%endblock%}
+ // Notebook menu
});
</script>
</body>
diff --git a/design/templates/notes/notebook_create.html b/design/templates/notes/notebook_create.html
new file mode 100644
index 0000000..8ffc94a
--- /dev/null
+++ b/design/templates/notes/notebook_create.html
@@ -0,0 +1,46 @@
+{% extends 'base.html' %}
+
+{% block extrastyles %}
+<link rel="stylesheet" href="/media/quill.snow.css" />
+{% endblock %}
+{% block content %}
+<main>
+ <article class="note-container">
+ <form id="new-notebook-form" action="{% url 'notebook-api-list' %}" method="post">
+{% csrf_token %}
+{{ form.non_field_errors }}
+{% for field in form %}
+<fieldset class="{% if field.errors %}error {%endif%}{% if field.name == 'body_qjson' or field.name == 'body_html' %}hide {%endif%}" id="fs-{{field.name}}" >
+{{field.label_tag}}
+{{field}}
+{% if field.errors %}{{field.errors}}{% endif %}
+</fieldset>
+{% endfor %}
+<p><input class="btn btn-inline" value="create" type="submit" /></p>
+</form>
+ <ul>{% for object in notebook_list %}
+ <li>
+ <a href="{% url 'notes:notebook-detail' user.username object.slug %}"><i class="icon-notebook"> </i>{{object.name}}</a>
+ </li>
+ {%endfor%}</ul>
+ </article>
+ <aside class="note-list-container">
+ <div class="svg-wrapper"><svg class="svg-icon-arrow">
+ <svg viewBox="0 0 16 13" id="shape-double-arrow" width="100%" height="100%"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square"><g id="Showing-post-info" transform="translate(-297.000000, -105.000000)" stroke="currentColor"><g transform="translate(305.000000, 111.500000) scale(-1, 1) rotate(-180.000000) translate(-305.000000, -111.500000) translate(297.000000, 105.000000)"><path d="M2.20710678,6.5 L6.85355339,1.85355339 L7.20710678,1.5 L6.5,0.792893219 L6.14644661,1.14644661 L1.14644661,6.14644661 L1.05805826,6.23483496 L0.792893219,6.5 L1.14644661,6.85355339 L6.14644661,11.8535534 L6.5,12.2071068 L7.20710678,11.5 L6.85355339,11.1464466 L2.20710678,6.5 Z" id="Combined-Shape"></path><path d="M10.2071068,6.5 L14.8535534,1.85355339 L15.2071068,1.5 L14.5,0.792893219 L14.1464466,1.14644661 L9.14644661,6.14644661 L9.05805826,6.23483496 L8.79289322,6.5 L9.14644661,6.85355339 L14.1464466,11.8535534 L14.5,12.2071068 L15.2071068,11.5 L14.8535534,11.1464466 L10.2071068,6.5 Z" id="Combined-Shape"></path></g></g></g></svg>
+ </svg></div>
+ <div class="">
+ <ul class="list-note-preview">{% for obj in notes_list %}
+ <li>
+ <a href="{% url 'notes:note-detail' user.username obj.slug %}">
+ <h4>{{obj.title}}</h4>
+ <div class="note-preview">{{obj.body_text|truncatewords:12}}</div>
+ </a>
+ </li>
+ {% endfor %}</ul>
+ </div>
+ </aside>
+ <div class="balance-container">
+ </div>
+</main>
+{% endblock %}
+
diff --git a/design/templates/notes/notebook_detail.html b/design/templates/notes/notebook_detail.html
new file mode 100644
index 0000000..36873e1
--- /dev/null
+++ b/design/templates/notes/notebook_detail.html
@@ -0,0 +1,49 @@
+{% extends 'base.html' %}
+
+{% block content %}
+<main>
+ <article class="note-container">
+ {%comment%}
+ <form id="new-note-form" action="{% url 'notebook-api-list' %}" method="post">
+ <label>Create a new notebook</label>
+ {% csrf_token %}
+ {{ form.non_field_errors }}
+ {% for field in form %}
+ <fieldset class="{% if field.errors %}error {%endif%}{% if field.name == 'body_qjson' or field.name == 'body_html' %}hide {%endif%}" id="fs-{{field.name}}" >
+ {{field.label_tag}}
+ {{field}}
+ {% if field.errors %}{{field.errors}}{% endif %}
+ </fieldset>
+ {% endfor %}
+ <p><input class="btn btn-inline" value="create" type="submit" /></p>
+ </form>
+ {%endcomment%}
+{{object}}
+ <ul class="list-note-preview">{% for obj in object.note_set.all %}
+ <li>
+ <a href="{% url 'notes:note-detail' user.username obj.slug %}">
+ <h4>{{obj.title}}</h4>
+ <div class="note-preview">{{obj.body_text|truncatewords:36}}</div>
+ </a>
+ </li>
+ {% endfor %}</ul>
+ </article>
+ <aside class="note-list-container">
+ <div class="svg-wrapper"><svg class="svg-icon-arrow">
+ <svg viewBox="0 0 16 13" id="shape-double-arrow" width="100%" height="100%"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square"><g id="Showing-post-info" transform="translate(-297.000000, -105.000000)" stroke="currentColor"><g transform="translate(305.000000, 111.500000) scale(-1, 1) rotate(-180.000000) translate(-305.000000, -111.500000) translate(297.000000, 105.000000)"><path d="M2.20710678,6.5 L6.85355339,1.85355339 L7.20710678,1.5 L6.5,0.792893219 L6.14644661,1.14644661 L1.14644661,6.14644661 L1.05805826,6.23483496 L0.792893219,6.5 L1.14644661,6.85355339 L6.14644661,11.8535534 L6.5,12.2071068 L7.20710678,11.5 L6.85355339,11.1464466 L2.20710678,6.5 Z" id="Combined-Shape"></path><path d="M10.2071068,6.5 L14.8535534,1.85355339 L15.2071068,1.5 L14.5,0.792893219 L14.1464466,1.14644661 L9.14644661,6.14644661 L9.05805826,6.23483496 L8.79289322,6.5 L9.14644661,6.85355339 L14.1464466,11.8535534 L14.5,12.2071068 L15.2071068,11.5 L14.8535534,11.1464466 L10.2071068,6.5 Z" id="Combined-Shape"></path></g></g></g></svg>
+ </svg></div>
+ <div class="">
+ <ul class="list-note-preview">{% for obj in notes_list %}
+ <li>
+ <a href="{% url 'notes:note-detail' user.username obj.slug %}">
+ <h4>{{obj.title}}</h4>
+ <div class="note-preview">{{obj.body_text|truncatewords:12}}</div>
+ </a>
+ </li>
+ {% endfor %}</ul>
+ </div>
+ </aside>
+ <div class="balance-container">
+ </div>
+</main>
+{% endblock %}
diff --git a/design/templates/notes/notes_detail.html b/design/templates/notes/notes_detail.html
index bf46ab8..95583bd 100644
--- a/design/templates/notes/notes_detail.html
+++ b/design/templates/notes/notes_detail.html
@@ -10,12 +10,24 @@
<main>
<article class="note-container">
<header class="note-header">
- <button class="hide btn btn-accent" id="edit-toggle-btn">Edit</button>
- <div class="note-header-float">
+ <div class="note-header-left">
+ <span class="label">tags:</span>
+ <ul>{% for tag in object.tags.all %}
+ <li>
+ <a href="{% url 'notes:note-tag' user.username tag.slug %}">{{tag}}</a>
+ </li>
+ {%endfor%}</ul>
+ <div class="notebook">
+ <span class="label">notebook:</span>
+ <a href="">{{object.notebook.name}}</a>
+ </div>
+ </div>
+ <div class="note-header-right">
<h2 class="note-time">{{object.date_created|date:"M d, Y"}}</h2>
- {% if object.url %}<h3 class="note-url"><a class="btn btn-small btn-subtle" href="{{object.url}}">Source</a><a class="btn btn-small btn-subtle left-margin-2" href="object.cache">Archive</a></h3>{% endif %}
+ {% if object.url %}<h3 class="note-url"><a class="btn btn-small btn-subtle" href="{{object.url}}">Source</a><a class="btn btn-small btn-subtle right-padding-0 left-margin-2" href="object.cache">Archive</a></h3>{% endif %}
</div>
</header>
+ <div class="edit-btn-wrapper"><button class="hide btn btn-hollow" id="edit-toggle-btn">Edit</button></div>
<h1 id="note-title" class="note-title">{{object.title}}</h1>
<div id="q-container" class="inactive"><div id="note-body">{% if object.body_html %}{{object.body_html|safe}}{%else%}{{object.body_text}}{%endif%}</div></div>
<form action="" method="post" id="note-edit-form">{% csrf_token %}
@@ -26,8 +38,11 @@
</form>
</article>
<aside class="note-list-container">
+ <div class="svg-wrapper"><svg class="svg-icon-arrow">
+ <svg viewBox="0 0 16 13" id="shape-double-arrow" width="100%" height="100%"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square"><g id="Showing-post-info" transform="translate(-297.000000, -105.000000)" stroke="currentColor"><g transform="translate(305.000000, 111.500000) scale(-1, 1) rotate(-180.000000) translate(-305.000000, -111.500000) translate(297.000000, 105.000000)"><path d="M2.20710678,6.5 L6.85355339,1.85355339 L7.20710678,1.5 L6.5,0.792893219 L6.14644661,1.14644661 L1.14644661,6.14644661 L1.05805826,6.23483496 L0.792893219,6.5 L1.14644661,6.85355339 L6.14644661,11.8535534 L6.5,12.2071068 L7.20710678,11.5 L6.85355339,11.1464466 L2.20710678,6.5 Z" id="Combined-Shape"></path><path d="M10.2071068,6.5 L14.8535534,1.85355339 L15.2071068,1.5 L14.5,0.792893219 L14.1464466,1.14644661 L9.14644661,6.14644661 L9.05805826,6.23483496 L8.79289322,6.5 L9.14644661,6.85355339 L14.1464466,11.8535534 L14.5,12.2071068 L15.2071068,11.5 L14.8535534,11.1464466 L10.2071068,6.5 Z" id="Combined-Shape"></path></g></g></g></svg>
+ </svg></div>
<div class="">
- <ul>{% for obj in notes_list %}
+ <ul class="list-note-preview">{% for obj in notes_list %}
<li>
<a href="{% url 'notes:note-detail' user.username obj.slug %}">
<h4>{{obj.title}}</h4>
@@ -37,12 +52,24 @@
{% endfor %}</ul>
</div>
</aside>
+ <div class="balance-container">
+ </div>
</main>
{% endblock %}
{% block jsinclude %}
<script src="/media/js/highlight.pack.js"></script>
<script src="/media/js/quill.min.js"></script>
+<script>
+document.addEventListener('readystatechange', event => {
+ if (event.target.readyState === "interactive") {
+ //initLoader();
+ }
+ else if (event.target.readyState === "complete") {
+ initQuill("#note-body");
+ }
+});
+</script>
{% endblock %}
<script>
{% block jsdomready %}
@@ -56,8 +83,8 @@
window.editing = false;
window.quillchange = false;
+ hljs.initHighlightingOnLoad();
btn.classList.remove('hide');
- initQuill("#note-body");
note_html.setAttribute('name', 'body_html');
note_html.setAttribute('class', 'hide');
note_html.setAttribute('id', 'id_body_html');
@@ -68,7 +95,6 @@
form.appendChild(note_qjson);
document.getElementById("btn-js-hide").classList.add("hide");
btn.addEventListener('click', function(){edit_note(this, title, qcontainer, window.quill, "{% url 'notes-api-detail' object.pk %}" )}, false)
-
{%endblock%}
</script>
diff --git a/design/templates/notes/notes_list.html b/design/templates/notes/notes_list.html
index 8066369..b1c1700 100644
--- a/design/templates/notes/notes_list.html
+++ b/design/templates/notes/notes_list.html
@@ -1,9 +1,35 @@
{% extends 'base.html' %}
+
{% block content %}
<main>
- <h1> Notes</h1>
- <ul>{% for obj in object_list %}
- <li><a href="{% url 'notes:note-detail' user.username obj.slug %}">{{obj}}</a></li>
- {% endfor %}</ul>
+ <article class="note-container">
+ <h1>Notes {% if tags|length == 1%} tagged {% for tag in tags%}{{tag}}{%endfor%}{%endif%}</h1>
+ <div>Tagged with: {% for tag in tags%}<a href="{{tag|slugify}}">{{tag}}</a>{%endfor%}</div>
+ <ul class="list-note-preview">{% for obj in object_list %}
+ <li>
+ <a href="{% url 'notes:note-detail' user.username obj.slug %}">
+ <h4>{{obj.title}}</h4>
+ <div class="note-preview">{{obj.body_text|truncatewords:36}}</div>
+ </a>
+ </li>
+ {% endfor %}</ul>
+ </article>
+ <aside class="note-list-container">
+ <div class="svg-wrapper"><svg class="svg-icon-arrow">
+ <svg viewBox="0 0 16 13" id="shape-double-arrow" width="100%" height="100%"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square"><g id="Showing-post-info" transform="translate(-297.000000, -105.000000)" stroke="currentColor"><g transform="translate(305.000000, 111.500000) scale(-1, 1) rotate(-180.000000) translate(-305.000000, -111.500000) translate(297.000000, 105.000000)"><path d="M2.20710678,6.5 L6.85355339,1.85355339 L7.20710678,1.5 L6.5,0.792893219 L6.14644661,1.14644661 L1.14644661,6.14644661 L1.05805826,6.23483496 L0.792893219,6.5 L1.14644661,6.85355339 L6.14644661,11.8535534 L6.5,12.2071068 L7.20710678,11.5 L6.85355339,11.1464466 L2.20710678,6.5 Z" id="Combined-Shape"></path><path d="M10.2071068,6.5 L14.8535534,1.85355339 L15.2071068,1.5 L14.5,0.792893219 L14.1464466,1.14644661 L9.14644661,6.14644661 L9.05805826,6.23483496 L8.79289322,6.5 L9.14644661,6.85355339 L14.1464466,11.8535534 L14.5,12.2071068 L15.2071068,11.5 L14.8535534,11.1464466 L10.2071068,6.5 Z" id="Combined-Shape"></path></g></g></g></svg>
+ </svg></div>
+ <div class="">
+ <ul class="list-note-preview">{% for obj in notes_list %}
+ <li>
+ <a href="{% url 'notes:note-detail' user.username obj.slug %}">
+ <h4>{{obj.title}}</h4>
+ <div class="note-preview">{{obj.body_text|truncatewords:12}}</div>
+ </a>
+ </li>
+ {% endfor %}</ul>
+ </div>
+ </aside>
+ <div class="balance-container">
+ </div>
</main>
{% endblock %}
diff --git a/design/templates/notes/notes_listold.html b/design/templates/notes/notes_listold.html
new file mode 100644
index 0000000..8066369
--- /dev/null
+++ b/design/templates/notes/notes_listold.html
@@ -0,0 +1,9 @@
+{% extends 'base.html' %}
+{% block content %}
+<main>
+ <h1> Notes</h1>
+ <ul>{% for obj in object_list %}
+ <li><a href="{% url 'notes:note-detail' user.username obj.slug %}">{{obj}}</a></li>
+ {% endfor %}</ul>
+</main>
+{% endblock %}
diff --git a/design/templates/sell.html b/design/templates/sell.html
new file mode 100644
index 0000000..001823b
--- /dev/null
+++ b/design/templates/sell.html
@@ -0,0 +1,6 @@
+{% extends 'base.html' %}
+{% block content %}
+<main>
+ <h1> TK Notes</h1>
+</main>
+{% endblock %}
diff --git a/scripts/gulpfile.js b/scripts/gulpfile.js
new file mode 100644
index 0000000..67c5bf7
--- /dev/null
+++ b/scripts/gulpfile.js
@@ -0,0 +1,17 @@
+const { src, dest } = require('gulp');
+const uglify = require('gulp-uglify');
+const rename = require('gulp-rename');
+const concat = require('gulp-concat');
+const babel = require('gulp-babel');
+
+exports.default = function() {
+ return src('src/*.js')
+ .pipe(babel({
+ presets: ['@babel/env']
+ }))
+ .pipe(concat('package.js'))
+ .pipe(uglify())
+ .pipe(dest('../media/js/'))
+ .pipe(rename({ extname: '.min.js' }))
+ .pipe(dest('../media/js/'));
+}
diff --git a/scripts/package.json b/scripts/package.json
new file mode 100644
index 0000000..778b5e6
--- /dev/null
+++ b/scripts/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "scripts",
+ "version": "1.0.0",
+ "description": "javascript for aite",
+ "main": "common.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "luxagraf",
+ "license": "ISC",
+ "devDependencies": {
+ "@babel/core": "^7.1.6",
+ "@babel/preset-env": "^7.1.6",
+ "gulp": "^4.0.0",
+ "gulp-babel": "^8.0.0",
+ "gulp-concat": "^2.6.1",
+ "gulp-rename": "^1.4.0",
+ "gulp-uglify": "^3.0.1"
+ }
+}
diff --git a/scripts/src/js.cookie.js b/scripts/src/js.cookie.js
new file mode 100644
index 0000000..9a0945e
--- /dev/null
+++ b/scripts/src/js.cookie.js
@@ -0,0 +1,165 @@
+/*!
+ * JavaScript Cookie v2.2.0
+ * https://github.com/js-cookie/js-cookie
+ *
+ * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
+ * Released under the MIT license
+ */
+;(function (factory) {
+ var registeredInModuleLoader = false;
+ if (typeof define === 'function' && define.amd) {
+ define(factory);
+ registeredInModuleLoader = true;
+ }
+ if (typeof exports === 'object') {
+ module.exports = factory();
+ registeredInModuleLoader = true;
+ }
+ if (!registeredInModuleLoader) {
+ var OldCookies = window.Cookies;
+ var api = window.Cookies = factory();
+ api.noConflict = function () {
+ window.Cookies = OldCookies;
+ return api;
+ };
+ }
+}(function () {
+ function extend () {
+ var i = 0;
+ var result = {};
+ for (; i < arguments.length; i++) {
+ var attributes = arguments[ i ];
+ for (var key in attributes) {
+ result[key] = attributes[key];
+ }
+ }
+ return result;
+ }
+
+ function init (converter) {
+ function api (key, value, attributes) {
+ var result;
+ if (typeof document === 'undefined') {
+ return;
+ }
+
+ // Write
+
+ if (arguments.length > 1) {
+ attributes = extend({
+ path: '/'
+ }, api.defaults, attributes);
+
+ if (typeof attributes.expires === 'number') {
+ var expires = new Date();
+ expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
+ attributes.expires = expires;
+ }
+
+ // We're using "expires" because "max-age" is not supported by IE
+ attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
+
+ try {
+ result = JSON.stringify(value);
+ if (/^[\{\[]/.test(result)) {
+ value = result;
+ }
+ } catch (e) {}
+
+ if (!converter.write) {
+ value = encodeURIComponent(String(value))
+ .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
+ } else {
+ value = converter.write(value, key);
+ }
+
+ key = encodeURIComponent(String(key));
+ key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
+ key = key.replace(/[\(\)]/g, escape);
+
+ var stringifiedAttributes = '';
+
+ for (var attributeName in attributes) {
+ if (!attributes[attributeName]) {
+ continue;
+ }
+ stringifiedAttributes += '; ' + attributeName;
+ if (attributes[attributeName] === true) {
+ continue;
+ }
+ stringifiedAttributes += '=' + attributes[attributeName];
+ }
+ return (document.cookie = key + '=' + value + stringifiedAttributes);
+ }
+
+ // Read
+
+ if (!key) {
+ result = {};
+ }
+
+ // To prevent the for loop in the first place assign an empty array
+ // in case there are no cookies at all. Also prevents odd result when
+ // calling "get()"
+ var cookies = document.cookie ? document.cookie.split('; ') : [];
+ var rdecode = /(%[0-9A-Z]{2})+/g;
+ var i = 0;
+
+ for (; i < cookies.length; i++) {
+ var parts = cookies[i].split('=');
+ var cookie = parts.slice(1).join('=');
+
+ if (!this.json && cookie.charAt(0) === '"') {
+ cookie = cookie.slice(1, -1);
+ }
+
+ try {
+ var name = parts[0].replace(rdecode, decodeURIComponent);
+ cookie = converter.read ?
+ converter.read(cookie, name) : converter(cookie, name) ||
+ cookie.replace(rdecode, decodeURIComponent);
+
+ if (this.json) {
+ try {
+ cookie = JSON.parse(cookie);
+ } catch (e) {}
+ }
+
+ if (key === name) {
+ result = cookie;
+ break;
+ }
+
+ if (!key) {
+ result[name] = cookie;
+ }
+ } catch (e) {}
+ }
+
+ return result;
+ }
+
+ api.set = api;
+ api.get = function (key) {
+ return api.call(api, key);
+ };
+ api.getJSON = function () {
+ return api.apply({
+ json: true
+ }, [].slice.call(arguments));
+ };
+ api.defaults = {};
+
+ api.remove = function (key, attributes) {
+ api(key, '', extend(attributes, {
+ expires: -1
+ }));
+ };
+
+ api.withConverter = init;
+
+ return api;
+ }
+
+ return init(function () {});
+}));
diff --git a/scripts/src/main-nav.js b/scripts/src/main-nav.js
new file mode 100644
index 0000000..fa6f25a
--- /dev/null
+++ b/scripts/src/main-nav.js
@@ -0,0 +1,71 @@
+function hideOnClickOutsided(element, btn) {
+ // given a menu element and btn, hide the menu
+ // whenever the click is not on either the element
+ // or the btn the opened it
+ const outsideClickListener = event => {
+ if (!element.contains(event.target) && (event.target.id != btn)) { // or use: event.target.closest(selector) === null
+ if (isVisible(element)) {
+ element.classList.remove('active')
+ removeClickListener()
+ }
+ }
+ }
+
+ const removeClickListener = () => {
+ document.removeEventListener('click', outsideClickListener)
+ }
+ document.addEventListener('click', outsideClickListener)
+}
+const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ) // source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js
+
+//----------------------------------------
+//Initialize main menu bar with progressive enhancements
+//----------------------------------------------
+// Account Menu
+var account_a = document.getElementById("account-menu");
+var account_div = document.getElementById("user-menu");
+//Add button function
+account_a.addEventListener('click', function(e){
+ e.preventDefault();
+ account_div.classList.toggle('active')
+ account_div.focus();
+ hideOnClickOutsided(account_div, account_a.id);
+}, false);
+
+// Notebooks Menu
+var notebook_a = document.getElementById("notebook-menu-link");
+var notebook_div = document.getElementById("notebooks-menu");
+//Add button function
+notebook_a.addEventListener('click', function(e){
+ e.preventDefault();
+ notebook_div.classList.toggle('active')
+ notebook_div.focus();
+ hideOnClickOutsided(notebook_div, notebook_a.id);
+}, false);
+
+
+//function buildNotebookMenu () {
+// var data = JSON.parse(this.responseText);
+// var div = document.getElementById("notebooks-menu");
+// var ul = document.createElement("ul");
+// ul.classList.add("vertical","list-style-none");
+// div.appendChild(ul);
+// for(var i in data) {
+// var li = document.createElement("li");
+// var a = document.createElement("a");
+// a.setAttribute("href", data[i]['json_absolute_url']);
+// a.innerHTML = data[i]['name'];
+// li.append(a);
+// ul.append(li);
+// }
+// var li = document.createElement("li");
+// var a = document.createElement("a");
+// a.setAttribute("href", '/user/{{user.username}}/notebooks/');
+// a.innerHTML = "View all"
+// li.append(a);
+// ul.append(li);
+//}
+//
+//
+//// getJSON("{%url 'notebook-api-list' %}", buildNotebookMenu);
+
diff --git a/scripts/overlay.js b/scripts/src/overlay.js
index b40d911..b40d911 100644
--- a/scripts/overlay.js
+++ b/scripts/src/overlay.js
diff --git a/scripts/util.js b/scripts/src/util.js
index 99a5ef3..3a4efc4 100644
--- a/scripts/util.js
+++ b/scripts/src/util.js
@@ -1,21 +1,43 @@
+function getJSON(url, callback) {
+ var request = new XMLHttpRequest();
+ request.addEventListener("load", callback);
+ request.open('GET', url, true);
+ request.onload = function() {
+ if (request.status >= 200 && request.status < 400) {
+ //console.log(request.responseText);
+ } else {
+ console.log("server error");
+ }
+ };
+ request.onerror = function() {
+ console.log("error on request");
+ };
+ request.send();
+}
+
function edit_note(btn, title, qcontainer, quill, url){
- console.log(editing);
- var formElement = document.querySelector("form");
- if (editing === false) {
+ var formElement = document.getElementById("note-edit-form");
+ if (window.editing === false) {
title.setAttribute("contenteditable", true);
title.classList.add('highlight')
qcontainer.classList.remove('inactive')
quill.enable(true);
btn.innerHTML = "Save"
- editing = true;
+ btn.classList.add("save");
+ window.editing = true;
+ window.titlecontents = title.innerHTML
} else {
- if (window.quillchange === true) {
+ if (window.quillchange === true || window.titlecontents != title.innerHTML) {
var form_note_title = document.getElementById('id_title');
var note_html = document.getElementById('id_body_html');
+ var note_text = document.getElementById('id_body_text');
var note_qjson = document.getElementById('id_body_qjson');
- form_note_title.value = title.innerHTML;
+ var new_title = document.getElementById('id_title');
+ new_title.value = title.innerHTML;
note_html.innerHTML = quill.root.innerHTML;
+ note_text.innerHTML = quill.getText();
note_qjson.innerHTML = JSON.stringify(quill.getContents());
+ console.log(note_text);
var request = new XMLHttpRequest();
request.open("PATCH", url);
var csrftoken = Cookies.get('csrftoken');
@@ -39,6 +61,7 @@ function edit_note(btn, title, qcontainer, quill, url){
qcontainer.classList.add('inactive');
quill.enable(false);
btn.innerHTML = "Edit"
+ btn.classList.remove("save");
document.body.focus();
editing = false;
}