From 4974eb58480f413c67f5f6e8fac430186eda2b62 Mon Sep 17 00:00:00 2001 From: luxagraf Date: Thu, 29 Nov 2018 16:57:26 -0600 Subject: uploading all recent changes ahead of sys upgrade --- .gitignore | 3 + README.md | 3 + apps/accounts/models.py | 9 +- apps/accounts/views.py | 4 +- apps/notes/forms.py | 11 +- apps/notes/models.py | 4 + apps/notes/serializers.py | 4 +- apps/notes/urls.py | 6 + apps/notes/views.py | 62 ++++++- apps/utils/util.py | 5 +- config/base_urls.py | 13 +- config/settings.py | 4 +- design/sass/_forms.scss | 34 ++++ design/sass/_global.scss | 17 +- design/sass/_header.scss | 44 +++++ design/sass/_notes.scss | 269 ++++++++++++++++++++++++---- design/templates/base.html | 39 +++- design/templates/notes/notebook_create.html | 46 +++++ design/templates/notes/notebook_detail.html | 49 +++++ design/templates/notes/notes_detail.html | 38 +++- design/templates/notes/notes_list.html | 34 +++- design/templates/notes/notes_listold.html | 9 + design/templates/sell.html | 6 + scripts/gulpfile.js | 17 ++ scripts/overlay.js | 253 -------------------------- scripts/package.json | 20 +++ scripts/src/js.cookie.js | 165 +++++++++++++++++ scripts/src/main-nav.js | 71 ++++++++ scripts/src/overlay.js | 253 ++++++++++++++++++++++++++ scripts/src/util.js | 107 +++++++++++ scripts/util.js | 84 --------- 31 files changed, 1281 insertions(+), 402 deletions(-) create mode 100644 design/templates/notes/notebook_create.html create mode 100644 design/templates/notes/notebook_detail.html create mode 100644 design/templates/notes/notes_listold.html create mode 100644 design/templates/sell.html create mode 100644 scripts/gulpfile.js delete mode 100644 scripts/overlay.js create mode 100644 scripts/package.json create mode 100644 scripts/src/js.cookie.js create mode 100644 scripts/src/main-nav.js create mode 100644 scripts/src/overlay.js create mode 100644 scripts/src/util.js delete mode 100644 scripts/util.js 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 +
Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY
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'/tagged/', NoteTagView.as_view(), name='note-tag',), + path(r'/notebooks/', NotebookDetailView.as_view(), name='notebook-detail',), + path(r'/notebooks/', NotebookListView.as_view(), name='notebook-list',), path(r'/', NoteDetailView.as_view(), name='note-detail',), path(r'/', 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'', PageDetailView.as_view(), name="pages"), #path(r'//', 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 + +*/ + +.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 @@
@@ -29,8 +37,23 @@ @@ -38,12 +61,12 @@
- {%endcomment%} {% block content %} {% endblock %}
@@ -65,9 +88,11 @@ {% block jsinclude %}{%endblock%} 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 %} + +{% endblock %} +{% block content %} +
+
+
+{% csrf_token %} +{{ form.non_field_errors }} +{% for field in form %} +
+{{field.label_tag}} +{{field}} +{% if field.errors %}{{field.errors}}{% endif %} +
+{% endfor %} +

+
+ +
+ +
+
+
+{% 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 %} +
+
+ {%comment%} +
+ + {% csrf_token %} + {{ form.non_field_errors }} + {% for field in form %} +
+ {{field.label_tag}} + {{field}} + {% if field.errors %}{{field.errors}}{% endif %} +
+ {% endfor %} +

+
+ {%endcomment%} +{{object}} + +
+ +
+
+
+{% 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 @@
- -
+
+ tags: +
    {% for tag in object.tags.all %} +
  • + {{tag}} +
  • + {%endfor%}
+
+ notebook: + {{object.notebook.name}} +
+
+

{{object.date_created|date:"M d, Y"}}

- {% if object.url %}

SourceArchive

{% endif %} + {% if object.url %}

SourceArchive

{% endif %}
+

{{object.title}}

{% if object.body_html %}{{object.body_html|safe}}{%else%}{{object.body_text}}{%endif%}
{% csrf_token %} @@ -26,8 +38,11 @@
+
+
{% endblock %} {% block jsinclude %} + {% endblock %} 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 %}
-

Notes

-
+ + +
+
{% 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 %} +
+

Notes

+
    {% for obj in object_list %} +
  • {{obj}}
  • + {% endfor %}
+
+{% 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 %} +
+

TK Notes

+
+{% 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/overlay.js b/scripts/overlay.js deleted file mode 100644 index b40d911..0000000 --- a/scripts/overlay.js +++ /dev/null @@ -1,253 +0,0 @@ -'use strict'; -/** - * @name Novicell overlay - * @desc Simple script that opens an overlay / modal with some content form either a selector or an URL - * @author Danni Larsen (DLA), Michael Sølvsteen (MSL), Signe Helbo Poulsen (SHP), Emil Skytte Ankersen (EAN) - * @example novicell.overlay.create({ 'selector': SELECTOR, 'url': URL, 'class':'CLASSNAME', 'onCreate': FUNCTIONNAME, 'onLoaded': FUNCTIONNAME, 'onDestroy': FUNCTIONNAME }); - * @requires none - */ - -var novicell = novicell || {}; - -novicell.overlay = novicell.overlay || new function () { - var self = this; - var options = {}; - var overlayElem; - var overlayContainer; - var overlayContent; - var backdrop; - var content; - var onCreate; - var onLoaded; - var onDestroy; - var isVideo = false; - - this.create = function (opts) { - var self = this; - // Set global options - options = opts; - - // Call onCreate callback - if (typeof options.onCreate === 'function') { - options.onCreate(); - } - - // Remove existing overlays - self.destroy(); - - // Check if content comes from a DOM selector - if (options.hasOwnProperty('selector') && options.selector !== null) { - var element = document.querySelector(options.selector); - - if (element) { - content = element.innerHTML; - constructOverlay(); - } else { - console.warn('novicell.overlay: element does not exist. Please provide a valid selector for use in document.querySelector.'); - return; - } - } - - // Check if content comes from a HTML element - else if (options.hasOwnProperty('element') && options.element !== null) { - var element = options.element; - - if (element) { - content = element.innerHTML; - constructOverlay(); - } else { - console.warn('novicell.overlay: element does not exist. Please provide a valid DOM element.'); - return; - } - } - - // Or if content comes from an ID - else if (options.hasOwnProperty('videoId')) { - if (options.videoId !== null) { - var src = ''; - isVideo = true; - - if(options.type == 'vimeo') { - src = 'https://player.vimeo.com/video/' + options.videoId + '?autoplay=' + options.autoplay; - } - else if(options.type == 'youtube') { - src = 'https://www.youtube.com/embed/' + options.videoId + '?autoplay=' + options.autoplay + '&rel=0'; - } - else { - return; - } - - var iframe = document.createElement('iframe'); - iframe.setAttribute('src', src); - iframe.setAttribute('frameborder', 0); - iframe.setAttribute('allowfullscreen', ''); - iframe.setAttribute('width', '100%'); - iframe.setAttribute('height', '100%'); - - content = iframe.outerHTML; - - constructOverlay(); - } else { - console.warn('novicell.overlay: video-id is empty. Please provide a video-id for use in video embed code (we support only Vimeo and YouTube).'); - return; - } - } - // If nothing is working, send error to los consolé - else { - console.error('novicell.overlay: no content to display! Please set a selector or a url to load.') - return; - } - }; - - this.destroy = function () { - if(document.querySelector('#js-novi-overlay')) { - // Remove elements - overlayElem.parentElement.removeChild(overlayElem); - backdrop.parentElement.removeChild(backdrop); - - // Stop listening for close overlay events - document.removeEventListener('keyup', self.destroy); - - // Remove class on body - document.documentElement.classList.remove('no-scroll', 'novi-overlay--open'); - - // Reset video variable - isVideo = false; - - // Call onDestroy callback - if (typeof options.onDestroy === 'function') { - options.onDestroy(); - } - } - }; - - function constructOverlay() { - // Create backdrop - setupBackdrop(); - - // Create the overlay - setupOverlay(); - - // Create content for overlay - setupOverlayContainer(); - - // Create close button - setupCloseButton(); - - // Add class to body-element - document.documentElement.classList.add('no-scroll'); - - // Call onLoaded callback - if (typeof options.onLoaded === 'function') { - options.onLoaded(); - } - }; - - function setupBackdrop() { - // Create the backdrop - backdrop = document.createElement('div'); - backdrop.classList.add('novi-backdrop'); - backdrop.id = 'js-novi-backdrop'; - - backdrop.addEventListener('click', function(e){ - if(e.target.classList.contains('novi-overlay') || e.target.classList.contains('novi-overlay__container')) { - self.destroy(); - } - }); - - // Add backdrop to overlay element - document.querySelector('body').appendChild(backdrop); - }; - - /* - * Helper functions for HTML elements - */ - function setupOverlay() { - // Create the overlay - overlayElem = document.createElement('div'); - overlayElem.classList.add('novi-overlay'); - overlayElem.id = 'js-novi-overlay'; - - // Set class for the overlay, if set in options - if (options.hasOwnProperty('class')) { - overlayElem.classList.add(options.class); - } - - // Add overlay to overlay element - // document.querySelector('body').appendChild(overlayElem); - backdrop.appendChild(overlayElem); - }; - - function setupOverlayContainer() { - // Create content for overlay - overlayContainer = document.createElement('div'); - overlayContainer.classList.add('novi-overlay__container'); - - // Create scroll element - overlayContent = document.createElement('div'); - overlayContent.classList.add('novi-overlay__content'); - - if(isVideo) { - overlayContent.classList.add('novi-overlay__content--video') - } - - // Set content - overlayContent.innerHTML = content; - overlayContainer.appendChild(overlayContent); - - // Add overlayContainer to overlay element - overlayElem.appendChild(overlayContainer); - }; - - function setupCloseButton() { - // Create the button - var btnClose = document.createElement('button'); - btnClose.classList.add('novi-overlay-close', 'button--close'); - btnClose.type = 'button'; - btnClose.id = 'js-novi-overlay-close'; - - // Add eventlistener for button click - btnClose.addEventListener('click', self.destroy); - - // Add eventlistener for esc key - document.addEventListener('keydown', function (e) { - if (e.keyCode === 27) { - self.destroy(); - } - }); - - // Add close button to overlay element - overlayContent.appendChild(btnClose); - }; - - /* - * Helper functions for getting content - */ - function get(url) { - // Return a new promise. - return new Promise(function (resolve, reject) { - // Do the usual XHR stuff - var req = new XMLHttpRequest(); - req.open('GET', url); - - req.onload = function () { - if (req.status >= 200 && req.status < 400) { - // Success!! - resolve(req.response); - } else { - // Error!! - reject(Error(req.statusText)); - } - }; - - // Handle network errors - req.onerror = function () { - reject(Error("Network Error")); - }; - - // Make the request - req.send(); - }); - }; - -}(); 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/src/overlay.js b/scripts/src/overlay.js new file mode 100644 index 0000000..b40d911 --- /dev/null +++ b/scripts/src/overlay.js @@ -0,0 +1,253 @@ +'use strict'; +/** + * @name Novicell overlay + * @desc Simple script that opens an overlay / modal with some content form either a selector or an URL + * @author Danni Larsen (DLA), Michael Sølvsteen (MSL), Signe Helbo Poulsen (SHP), Emil Skytte Ankersen (EAN) + * @example novicell.overlay.create({ 'selector': SELECTOR, 'url': URL, 'class':'CLASSNAME', 'onCreate': FUNCTIONNAME, 'onLoaded': FUNCTIONNAME, 'onDestroy': FUNCTIONNAME }); + * @requires none + */ + +var novicell = novicell || {}; + +novicell.overlay = novicell.overlay || new function () { + var self = this; + var options = {}; + var overlayElem; + var overlayContainer; + var overlayContent; + var backdrop; + var content; + var onCreate; + var onLoaded; + var onDestroy; + var isVideo = false; + + this.create = function (opts) { + var self = this; + // Set global options + options = opts; + + // Call onCreate callback + if (typeof options.onCreate === 'function') { + options.onCreate(); + } + + // Remove existing overlays + self.destroy(); + + // Check if content comes from a DOM selector + if (options.hasOwnProperty('selector') && options.selector !== null) { + var element = document.querySelector(options.selector); + + if (element) { + content = element.innerHTML; + constructOverlay(); + } else { + console.warn('novicell.overlay: element does not exist. Please provide a valid selector for use in document.querySelector.'); + return; + } + } + + // Check if content comes from a HTML element + else if (options.hasOwnProperty('element') && options.element !== null) { + var element = options.element; + + if (element) { + content = element.innerHTML; + constructOverlay(); + } else { + console.warn('novicell.overlay: element does not exist. Please provide a valid DOM element.'); + return; + } + } + + // Or if content comes from an ID + else if (options.hasOwnProperty('videoId')) { + if (options.videoId !== null) { + var src = ''; + isVideo = true; + + if(options.type == 'vimeo') { + src = 'https://player.vimeo.com/video/' + options.videoId + '?autoplay=' + options.autoplay; + } + else if(options.type == 'youtube') { + src = 'https://www.youtube.com/embed/' + options.videoId + '?autoplay=' + options.autoplay + '&rel=0'; + } + else { + return; + } + + var iframe = document.createElement('iframe'); + iframe.setAttribute('src', src); + iframe.setAttribute('frameborder', 0); + iframe.setAttribute('allowfullscreen', ''); + iframe.setAttribute('width', '100%'); + iframe.setAttribute('height', '100%'); + + content = iframe.outerHTML; + + constructOverlay(); + } else { + console.warn('novicell.overlay: video-id is empty. Please provide a video-id for use in video embed code (we support only Vimeo and YouTube).'); + return; + } + } + // If nothing is working, send error to los consolé + else { + console.error('novicell.overlay: no content to display! Please set a selector or a url to load.') + return; + } + }; + + this.destroy = function () { + if(document.querySelector('#js-novi-overlay')) { + // Remove elements + overlayElem.parentElement.removeChild(overlayElem); + backdrop.parentElement.removeChild(backdrop); + + // Stop listening for close overlay events + document.removeEventListener('keyup', self.destroy); + + // Remove class on body + document.documentElement.classList.remove('no-scroll', 'novi-overlay--open'); + + // Reset video variable + isVideo = false; + + // Call onDestroy callback + if (typeof options.onDestroy === 'function') { + options.onDestroy(); + } + } + }; + + function constructOverlay() { + // Create backdrop + setupBackdrop(); + + // Create the overlay + setupOverlay(); + + // Create content for overlay + setupOverlayContainer(); + + // Create close button + setupCloseButton(); + + // Add class to body-element + document.documentElement.classList.add('no-scroll'); + + // Call onLoaded callback + if (typeof options.onLoaded === 'function') { + options.onLoaded(); + } + }; + + function setupBackdrop() { + // Create the backdrop + backdrop = document.createElement('div'); + backdrop.classList.add('novi-backdrop'); + backdrop.id = 'js-novi-backdrop'; + + backdrop.addEventListener('click', function(e){ + if(e.target.classList.contains('novi-overlay') || e.target.classList.contains('novi-overlay__container')) { + self.destroy(); + } + }); + + // Add backdrop to overlay element + document.querySelector('body').appendChild(backdrop); + }; + + /* + * Helper functions for HTML elements + */ + function setupOverlay() { + // Create the overlay + overlayElem = document.createElement('div'); + overlayElem.classList.add('novi-overlay'); + overlayElem.id = 'js-novi-overlay'; + + // Set class for the overlay, if set in options + if (options.hasOwnProperty('class')) { + overlayElem.classList.add(options.class); + } + + // Add overlay to overlay element + // document.querySelector('body').appendChild(overlayElem); + backdrop.appendChild(overlayElem); + }; + + function setupOverlayContainer() { + // Create content for overlay + overlayContainer = document.createElement('div'); + overlayContainer.classList.add('novi-overlay__container'); + + // Create scroll element + overlayContent = document.createElement('div'); + overlayContent.classList.add('novi-overlay__content'); + + if(isVideo) { + overlayContent.classList.add('novi-overlay__content--video') + } + + // Set content + overlayContent.innerHTML = content; + overlayContainer.appendChild(overlayContent); + + // Add overlayContainer to overlay element + overlayElem.appendChild(overlayContainer); + }; + + function setupCloseButton() { + // Create the button + var btnClose = document.createElement('button'); + btnClose.classList.add('novi-overlay-close', 'button--close'); + btnClose.type = 'button'; + btnClose.id = 'js-novi-overlay-close'; + + // Add eventlistener for button click + btnClose.addEventListener('click', self.destroy); + + // Add eventlistener for esc key + document.addEventListener('keydown', function (e) { + if (e.keyCode === 27) { + self.destroy(); + } + }); + + // Add close button to overlay element + overlayContent.appendChild(btnClose); + }; + + /* + * Helper functions for getting content + */ + function get(url) { + // Return a new promise. + return new Promise(function (resolve, reject) { + // Do the usual XHR stuff + var req = new XMLHttpRequest(); + req.open('GET', url); + + req.onload = function () { + if (req.status >= 200 && req.status < 400) { + // Success!! + resolve(req.response); + } else { + // Error!! + reject(Error(req.statusText)); + } + }; + + // Handle network errors + req.onerror = function () { + reject(Error("Network Error")); + }; + + // Make the request + req.send(); + }); + }; + +}(); diff --git a/scripts/src/util.js b/scripts/src/util.js new file mode 100644 index 0000000..3a4efc4 --- /dev/null +++ b/scripts/src/util.js @@ -0,0 +1,107 @@ +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){ + 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" + btn.classList.add("save"); + window.editing = true; + window.titlecontents = title.innerHTML + } else { + 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'); + 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'); + request.setRequestHeader("X-CSRFToken", csrftoken) + request.onload = function() { + if (request.status >= 200 && request.status < 400) { + console.log(request); + window.quillchange = false; + } else { + console.log(request); + console.log("server error"); + } + }; + request.onerror = function() { + console.log("error on request"); + }; + request.send(new FormData(formElement)); + } + title.setAttribute("contenteditable", false); + title.classList.remove('highlight') + qcontainer.classList.add('inactive'); + quill.enable(false); + btn.innerHTML = "Edit" + btn.classList.remove("save"); + document.body.focus(); + editing = false; + } + return false; +} + + +function get_login_form() { + var request = new XMLHttpRequest(); + request.open('GET', '/login/', true); + request.onload = function() { + if (request.status >= 200 && request.status < 400) { + } else { + console.log("server error"); + } + }; + request.onerror = function() { + console.log("error on request"); + }; + request.send(); +} + +//Global init for Quill +function initQuill(el) { + window.quill = new Quill(el, { + modules: { + syntax: true, // Include syntax module + toolbar: [ + [{ header: [1, 2, 3, 4, false] }], + ['bold', 'italic', 'underline', 'blockquote'], + [{ 'list': 'bullet'}, { 'list': 'ordered'},{ 'list': 'check'} ], + ['link', 'code-block', 'image', 'video', 'formula',], + [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme + [{ 'font': [] }], + ] + }, + theme: 'snow', + enable: false + }); + window.quill.on('text-change', function() { + window.quillchange = true; + }); +} diff --git a/scripts/util.js b/scripts/util.js deleted file mode 100644 index 99a5ef3..0000000 --- a/scripts/util.js +++ /dev/null @@ -1,84 +0,0 @@ -function edit_note(btn, title, qcontainer, quill, url){ - console.log(editing); - var formElement = document.querySelector("form"); - if (editing === false) { - title.setAttribute("contenteditable", true); - title.classList.add('highlight') - qcontainer.classList.remove('inactive') - quill.enable(true); - btn.innerHTML = "Save" - editing = true; - } else { - if (window.quillchange === true) { - var form_note_title = document.getElementById('id_title'); - var note_html = document.getElementById('id_body_html'); - var note_qjson = document.getElementById('id_body_qjson'); - form_note_title.value = title.innerHTML; - note_html.innerHTML = quill.root.innerHTML; - note_qjson.innerHTML = JSON.stringify(quill.getContents()); - var request = new XMLHttpRequest(); - request.open("PATCH", url); - var csrftoken = Cookies.get('csrftoken'); - request.setRequestHeader("X-CSRFToken", csrftoken) - request.onload = function() { - if (request.status >= 200 && request.status < 400) { - console.log(request); - window.quillchange = false; - } else { - console.log(request); - console.log("server error"); - } - }; - request.onerror = function() { - console.log("error on request"); - }; - request.send(new FormData(formElement)); - } - title.setAttribute("contenteditable", false); - title.classList.remove('highlight') - qcontainer.classList.add('inactive'); - quill.enable(false); - btn.innerHTML = "Edit" - document.body.focus(); - editing = false; - } - return false; -} - - -function get_login_form() { - var request = new XMLHttpRequest(); - request.open('GET', '/login/', true); - request.onload = function() { - if (request.status >= 200 && request.status < 400) { - } else { - console.log("server error"); - } - }; - request.onerror = function() { - console.log("error on request"); - }; - request.send(); -} - -//Global init for Quill -function initQuill(el) { - window.quill = new Quill(el, { - modules: { - syntax: true, // Include syntax module - toolbar: [ - [{ header: [1, 2, 3, 4, false] }], - ['bold', 'italic', 'underline', 'blockquote'], - [{ 'list': 'bullet'}, { 'list': 'ordered'},{ 'list': 'check'} ], - ['link', 'code-block', 'image', 'video', 'formula',], - [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme - [{ 'font': [] }], - ] - }, - theme: 'snow', - enable: false - }); - window.quill.on('text-change', function() { - window.quillchange = true; - }); -} -- cgit v1.2.3-70-g09d2