Fixed zoomIn/Out slider in editBook + now you can view books offline. click on a book on your home page

This commit is contained in:
Sagi Dayan 2020-06-04 19:07:34 -04:00
parent c75afd74f9
commit 3364adbe31
14 changed files with 219 additions and 24 deletions

View file

@ -0,0 +1,33 @@
'use strict'
/** @typedef {import('@adonisjs/framework/src/Request')} Request */
/** @typedef {import('@adonisjs/framework/src/Response')} Response */
/** @typedef {import('@adonisjs/framework/src/View')} View */
class BookCallPageAuth {
/**
* @param {object} ctx
* @param {Request} ctx.request
* @param {Function} next
*/
async handle(ctx, next) {
const {request, auth, response, book, call} = ctx;
// call next to advance the request
const user = auth.user;
if (book.user_id) {
// Belongs to a user. Check if the book user has a connection with this
// user
if (book.user_id === user.id) {
await next();
} else if (call.parent_id === user.id || call.guest_id === user.id) {
await next();
} else {
response.status(403);
response.send({code: 403, message: 'Book is private'});
}
} else {
await next();
}
}
}
module.exports = BookCallPageAuth

View file

@ -2,8 +2,7 @@
/** @typedef {import('@adonisjs/framework/src/Request')} Request */
/** @typedef {import('@adonisjs/framework/src/Response')} Response */
/** @typedef {import('@adonisjs/framework/src/View')} View */
const Book = use('App/Models/Book');
const UserChildUtils = use('App/Utils/UserChildUtils');
class BookPageAuth {
/**
* @param {object} ctx
@ -11,7 +10,7 @@ class BookPageAuth {
* @param {Function} next
*/
async handle(ctx, next) {
const {request, auth, response, book, call} = ctx;
const {request, auth, response, book} = ctx;
// call next to advance the request
const user = auth.user;
if (book.user_id) {
@ -19,8 +18,6 @@ class BookPageAuth {
// user
if (book.user_id === user.id) {
await next();
} else if (call.parent_id === user.id || call.guest_id === user.id) {
await next();
} else {
response.status(403);
response.send({code: 403, message: 'Book is private'});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -8118,9 +8118,6 @@ video {
border-radius: 8px;
color: white; }
.book-thumb.page-preview {
flex-basis: unset; }
.book-stitch-preview-left::before {
content: '';
height: 100%;

View file

@ -505,7 +505,7 @@ video{
}
}
.book-thumb.page-preview{
flex-basis: unset;
// flex-basis: unset;
}
.book-stitch-preview-left{
&::before{

View file

@ -15,6 +15,7 @@ import Settings from "../views/settings.vue";
import Call from "../views/call.vue";
import ChildProfile from "../views/child_profile.vue";
import EditBook from "../views/edit_book.vue";
import BookOfflineViewer from "../views/BookOfflineViewer.vue";
// Call Views
import CallLobby from "../views/call_views/Lobby.vue";
@ -35,6 +36,10 @@ const routes: RouteConfig[] = [
path: "/create/book",
component: EditBook
},
{
path: "/book/:id",
component: BookOfflineViewer
},
{
path: "/call/:id",
component: Call,

View file

@ -0,0 +1,137 @@
<template>
<div class="is-fullwidth is-fullheight-container p-l-lg p-r-lg">
<Loading v-if="loading" />
<div :class="`is-fullheight-container ${flipbookRef ? '' : 'is-transparent'}`" v-else>
<div class="book-view m-sm m-r-md">
<div
class="go-left m-r-sm"
style="display: inline-block; align-items: center; position: absolute; left:0px; top:0px"
>
<button
class="button book-flip-buttons"
:disabled="!canFlipLeft"
@click="onLeftClicked()"
>
<i class="fa fa-fw fa-arrow-left"></i>
</button>
</div>
<flipbook
class="flipbook"
:pages="pages"
:forwardDirection="book.ltr ? 'right': 'left'"
:zooms="null"
:enabled="true"
@on-mounted="bookMounted()"
ref="flipbook"
v-slot="flipbook"
>
<!-- @flip-left-start="onFlip('left')" -->
<!-- @flip-right-start="onFlip('right')" -->
<div class="page-progress has-text-centered m-b-none">
<p>Page {{ flipbook.page }} of {{ flipbook.numPages }}</p>
</div>
</flipbook>
<div
class="go-right m-l-sm"
style="display: inline-block; align-items: center; position: absolute; right:0px; top:0px"
>
<button
class="button book-flip-buttons"
:disabled="!canFlipRight"
@click="onRightClicked()"
>
<i class="fa fa-fw fa-arrow-right"></i>
</button>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { mapGetters, mapActions } from "vuex";
import Flipbook from "../components/flipbook/flipbook.cjs.js";
import Loading from "../../shared/components/Loading/Loading.vue";
export default {
name: "BookOfflineViewer",
components: {
Flipbook,
Loading
},
created() {
const bookId = Number(this.$route.params.id);
if (!this.user || !bookId) {
this.$router.replace({ path: `/` });
}
this.user.books.forEach(b => {
if (this.book) return;
if (b.id === bookId) {
console.log("Found Book");
this.book = b;
}
});
if (!this.book) {
this.notify({ message: "Book Not Found!", level: "danger" });
this.$router.replace({ path: `/` });
} else {
// create pages
// /u/books/:bookId/page/:pageNumber
const pages = [null];
for (let i = 1; i < this.book.pages + 1; i++) {
pages.push(`/u/books/${bookId}/page/${i}`);
}
this.pages = pages;
this.loading = false;
}
},
methods: {
bookMounted() {
console.log("Book Mounted!");
if (this.$refs.flipbook) {
console.log("Found!");
this.flipbookRef = true;
// this.$refs.flipbook.onResize();
// console.log("resized");
} else {
console.log("Still Null!!");
}
},
onLeftClicked() {
this.$refs.flipbook.flipLeft();
},
onRightClicked() {
this.$refs.flipbook.flipRight();
},
...mapActions(["notify"])
},
computed: {
canFlipLeft() {
return this.flipbookRef && this.$refs.flipbook.canFlipLeft;
},
canFlipRight() {
return this.flipbookRef && this.$refs.flipbook.canFlipRight;
},
...mapGetters(["user"])
},
data() {
return {
loading: true,
book: <IBook>null,
pages: <string[]>[],
flipbookRef: null
};
}
};
interface IBook {
id: number;
pages: number;
user_id?: number;
title: string;
ltr: boolean;
created_at: string;
}
</script>

View file

@ -199,7 +199,7 @@
<div class="book-text">
<div>Previouse Page</div>
</div>
<div class="book-cover">
<div class="book-cover is-flex">
<img
:src="pages[currentPage - 1] ? pages[currentPage - 1].base64: ''"
/>
@ -245,30 +245,33 @@
<input
type="range"
min="0"
max="1000"
:max="DEFAULT_ZOOM*2"
v-model="pageZoom"
:disabled="!pages[currentPage].imageLoaded"
ref="zoomRangeSlider"
@mouseup="blurZoomSlider()"
/>
<div class="is-flex is-justify-between">
<button
type="button"
class="button is-rounded is-outlined is-small"
:disabled="!pages[currentPage].imageLoaded"
@click="pageZoom-=2"
:disabled="!pages[currentPage].imageLoaded || pageZoom <= 0"
@click="zoom(false)"
>
<i class="fa fa-fw fa-minus"></i>
</button>
<button
type="button"
class="button is-rounded is-outlined is-small"
:disabled="!pages[currentPage].imageLoaded"
@click="pageZoom+=2"
:disabled="!pages[currentPage].imageLoaded || pageZoom >= DEFAULT_ZOOM * 2"
@click="zoom(true)"
>
<i class="fa fa-fw fa-plus"></i>
</button>
</div>
</div>
<div class="rotations is-flex is-justify-between m-b-lg">
<label class="label">Rotate Image</label>
<button
class="button"
@click="onRotateClicked(false)"
@ -382,7 +385,7 @@ import Services from "../../services";
const DEFAULT_PAGE_WIDTH = 350;
const DEFAULT_PAGE_HEIGHT = 350;
const DEFAULT_ZOOM = 500;
const DEFAULT_ZOOM = 250;
const MIME_TYPE = "image/jpeg";
const COMPRESSION_RATE = 0.4;
export default {
@ -448,6 +451,7 @@ export default {
const page = this.pages[this.currentPage];
console.log(newVal, oldVal);
const delta = Math.abs(newVal - oldVal);
if (!page.croppa.zoomOut) return;
if (newVal < oldVal) {
//zoomOut
for (let i = delta; i > 0; i--) page.croppa.zoomOut();
@ -657,6 +661,16 @@ export default {
onRightClicked() {
this.$refs.flipbook.flipRight();
return true;
},
zoom(zoomIn: boolean) {
const amount = zoomIn ? 2 : -2;
this.pageZoom = Number(this.pageZoom) + amount;
},
blurZoomSlider() {
const slider: HTMLInputElement = this.$refs.zoomRangeSlider;
if (slider) {
slider.blur();
}
}
},
computed: {
@ -703,7 +717,8 @@ export default {
uploading: false,
errors: {},
DEFAULT_PAGE_WIDTH,
DEFAULT_PAGE_HEIGHT
DEFAULT_PAGE_HEIGHT,
DEFAULT_ZOOM
};
}
};

View file

@ -139,7 +139,12 @@
<i class="fa fa-fw fa-book"></i> My Books
</h2>
<div class="is-flex m-b-md is-justify-centered has-wrap">
<div class="book-thumb m-l-md" v-for="book in user.books" :key="book.id">
<div
class="book-thumb enabled m-l-md"
v-for="book in user.books"
:key="book.id"
@click="goToBook(book)"
>
<div class="book-cover">
<figure class="image is-2by3 m-a">
<img :src="`/u/books/${book.id}/thumbnail`" />
@ -246,6 +251,9 @@ export default {
goChildProfile(connection) {
this.$router.push({ path: `/child/${connection.id}` });
},
goToBook(book) {
this.$router.push({ path: `/book/${book.id}` });
},
async onChildCreated(child) {
this.loading = true;
await this.getUser();

View file

@ -42,6 +42,7 @@ const globalMiddleware =
auth: 'Adonis/Middleware/Auth',
guest: 'Adonis/Middleware/AllowGuestOnly',
adminAuth: 'App/Middleware/AdminAuth',
BookCallPageAuth: 'App/Middleware/BookCallPageAuth',
BookPageAuth: 'App/Middleware/BookPageAuth',
BookContext: 'App/Middleware/BookContext',
CallContext: 'App/Middleware/CallContext',

View file

@ -61,7 +61,9 @@ Route
.get(
'/u/call/:callId/books/:bookId/page/:pageNumber',
'BookApiController.getPage')
.middleware(['auth', 'BookContext', 'CallContext', 'BookPageAuth']);
.middleware(['auth', 'BookContext', 'CallContext', 'BookCallPageAuth']);
Route.get('/u/books/:bookId/page/:pageNumber', 'BookApiController.getPage')
.middleware(['auth', 'BookContext', 'BookPageAuth']);
/**
* Public book thumbnail
*/