diff --git a/.env.template b/.env.template index 18fb16abe..646ded6a1 100644 --- a/.env.template +++ b/.env.template @@ -19,7 +19,7 @@ POSTGRES_DB=djangodb # Users can set a amount of time after which the shopping list is refreshed when they are in viewing mode # This is the minimum interval users can set. Setting this to low will allow users to refresh very frequently which # might cause high load on the server. (Technically they can obviously refresh as often as they want with their own scripts) -SHOPPING_MIN_AUTOSYNC_INTERVAL=5000 +SHOPPING_MIN_AUTOSYNC_INTERVAL=5 # Serve mediafiles directly using gunicorn. Basically everyone recommends not doing this. Please use any of the examples # provided that include an additional nxginx container to handle media file serving. diff --git a/.idea/dictionaries/vabene1111_PC.xml b/.idea/dictionaries/vabene1111_PC.xml index 13cb1b328..cfd8a9e64 100644 --- a/.idea/dictionaries/vabene1111_PC.xml +++ b/.idea/dictionaries/vabene1111_PC.xml @@ -1,6 +1,7 @@ + autosync csrftoken gunicorn ical diff --git a/cookbook/serializer.py b/cookbook/serializer.py index e4e6643e3..761e50152 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -213,6 +213,12 @@ class ShoppingListEntrySerializer(WritableNestedModelSerializer): read_only_fields = ('id',) +class ShoppingListEntryCheckedSerializer(serializers.ModelSerializer): + class Meta: + model = ShoppingListEntry + fields = ('id', 'checked') + + class ShoppingListSerializer(WritableNestedModelSerializer): recipes = ShoppingListRecipeSerializer(many=True, allow_null=True) entries = ShoppingListEntrySerializer(many=True, allow_null=True) @@ -223,6 +229,15 @@ class ShoppingListSerializer(WritableNestedModelSerializer): read_only_fields = ('id',) +class ShoppingListAutoSyncSerializer(WritableNestedModelSerializer): + entries = ShoppingListEntryCheckedSerializer(many=True, allow_null=True) + + class Meta: + model = ShoppingList + fields = ('id', 'entries',) + read_only_fields = ('id',) + + class ShareLinkSerializer(serializers.ModelSerializer): class Meta: model = ShareLink diff --git a/cookbook/templates/shopping_list.html b/cookbook/templates/shopping_list.html index 6c6f67fd2..615b27190 100644 --- a/cookbook/templates/shopping_list.html +++ b/cookbook/templates/shopping_list.html @@ -296,7 +296,7 @@ {% if request.user.userpreference.shopping_auto_sync > 0 %} setInterval(() => { - this.loadShoppingList() + this.loadShoppingList(true) }, {{ request.user.userpreference.shopping_auto_sync }} * 1000 ) {% endif %} }, @@ -318,11 +318,22 @@ solid: true }) }, - loadShoppingList: function () { + loadShoppingList: function (autosync = false) { + this.$http.get("{% url 'api:shoppinglist-detail' shopping_list_id %}" + ((autosync) ? '?autosync=true' : '')).then((response) => { + if (!autosync) { + this.shopping_list = response.body + this.loading = false + } else { + let check_map = {} + for (let e of response.body.entries) { + check_map[e.id] = {checked: e.checked} + } + + for (let se of this.shopping_list.entries) { + se.checked = check_map[se.id].checked + } + } - this.$http.get("{% url 'api:shoppinglist-detail' shopping_list_id %}").then((response) => { - this.shopping_list = response.body - this.loading = false }).catch((err) => { console.log(err) this.makeToast('{% trans 'Error' %}', '{% trans 'There was an error loading a resource!' %}' + err.bodyText, 'danger') diff --git a/cookbook/views/api.py b/cookbook/views/api.py index c8707e76b..0f09d6722 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -32,7 +32,8 @@ from cookbook.models import Recipe, Sync, Storage, CookLog, MealPlan, MealType, from cookbook.provider.dropbox import Dropbox from cookbook.provider.nextcloud import Nextcloud from cookbook.serializer import MealPlanSerializer, MealTypeSerializer, RecipeSerializer, ViewLogSerializer, UserNameSerializer, UserPreferenceSerializer, RecipeBookSerializer, IngredientSerializer, FoodSerializer, StepSerializer, \ - KeywordSerializer, RecipeImageSerializer, StorageSerializer, SyncSerializer, SyncLogSerializer, UnitSerializer, ShoppingListSerializer, ShoppingListRecipeSerializer, ShoppingListEntrySerializer + KeywordSerializer, RecipeImageSerializer, StorageSerializer, SyncSerializer, SyncLogSerializer, UnitSerializer, ShoppingListSerializer, ShoppingListRecipeSerializer, ShoppingListEntrySerializer, ShoppingListEntryCheckedSerializer, \ + ShoppingListAutoSyncSerializer class UserNameViewSet(viewsets.ReadOnlyModelViewSet): @@ -265,6 +266,12 @@ class ShoppingListViewSet(viewsets.ModelViewSet): queryset = self.queryset.filter(created_by=self.request.user).all() return queryset + def get_serializer_class(self): + autosync = self.request.query_params.get('autosync', None) + if autosync: + return ShoppingListAutoSyncSerializer + return self.serializer_class + class ViewLogViewSet(viewsets.ModelViewSet): queryset = ViewLog.objects.all()