-
-
-
- book-tracker
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index 2be2c2d..0000000
--- a/src/index.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import choo from 'choo';
-
-import { viewManager } from './views/manager';
-
-const app = choo();
-
-if (process.env.NODE_ENV !== 'production') {
- // Only runs in development and will be stripped from production build.
- app.use(require('choo-devtools')()); // Exposes `choo` to the console for debugging!
-}
-
-// App state and emitters
-app.use((state, emitter) => {
- // Default state variables
- state.currentView = 'home';
- state.viewStates = {};
-
- // Listeners
- emitter.on('DOMContentLoaded', () => {
- // Emitter listeners
- emitter.on('render', callback => {
- // This is a dirty hack to get the callback to call *after* re-rendering.
- if (callback && typeof callback === "function") {
- setTimeout(() => {
- callback();
- }, 50);
- }
- });
-
- emitter.on('changeView', newView => {
- // Change the view and call render. Makes it easier to call within views.
- state.currentView = newView;
- emitter.emit('render', () => {});
- });
- });
-});
-
-// For the main screen, pass the viewManager function in viewManager.js,
-// which is given the app's state from above and the emitter.emit method that
-// triggers the app's emitter listeners.
-app.route('/', viewManager);
-app.route('/:page', viewManager);
-app.route('/404', viewManager);
-
-app.mount('body'); // Overwrite the `` tag with the content of the Choo app
\ No newline at end of file
diff --git a/src/views/controller.js b/src/views/controller.js
deleted file mode 100644
index e422f26..0000000
--- a/src/views/controller.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export class ViewController {
- constructor(state, viewName, defaultState = {}) {
- // Store the global app state so it's accessible but out of the way.
- this.appState = state;
-
- // Give this view its own state within the appState.
- if (!this.appState.viewStates.hasOwnProperty(viewName)) {
- this.appState.viewStates[viewName] = defaultState;
- }
- this.state = this.appState.viewStates[viewName];
- }
-}
\ No newline at end of file
diff --git a/src/views/home/controller.js b/src/views/home/controller.js
deleted file mode 100644
index e47c963..0000000
--- a/src/views/home/controller.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import { ViewController } from '../controller';
-
-export class HomeController extends ViewController {
- constructor(state) {
- // Super passes state, view name, and default state to ViewController,
- // which stores state in this.appState and the view controller's state to this.state
- super(state, 'home', {
- messages: [
- 'hello',
- 'test',
- 'yay',
- ],
- });
-
- // If using controller methods in an input's onchange or onclick instance,
- // either bind the class's 'this' instance to the method first...
- // or use `onclick=${() => controller.submit()}` to maintain the 'this' of the class instead.
- }
-
- get messages() {
- return [...this.state.messages];
- }
-}
\ No newline at end of file
diff --git a/src/views/home/index.js b/src/views/home/index.js
deleted file mode 100644
index 8052518..0000000
--- a/src/views/home/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import html from 'choo/html';
-
-import './styles.scss'; // Creates a separate CSS file, but allows better code splitting.
-// We'll see if code splitting is worth it in the end or if we should combine everything into `src/index.scss`
-import { HomeController } from './controller'; // The controller for this view, where processing should happen.
-
-// This is the view function that is exported and used in the view manager.
-export const homeView = (state, emit) => {
- const controller = new HomeController(state);
-
- // Returning an array in a view allows non-shared parent HTML elements.
- // This one doesn't have the problem right now, but it's good to remember.
- return [
- html`
-
`;
- })}
-
- `,
- ];
-}
\ No newline at end of file
diff --git a/src/views/home/styles.scss b/src/views/home/styles.scss
deleted file mode 100644
index e92a2b3..0000000
--- a/src/views/home/styles.scss
+++ /dev/null
@@ -1,8 +0,0 @@
-.test {
- background-color: #dddddd;
- padding: 10px;
-
- p {
- border: 1px solid #444444;
- }
-}
\ No newline at end of file
diff --git a/src/views/manager.js b/src/views/manager.js
deleted file mode 100644
index 63c88ec..0000000
--- a/src/views/manager.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import html from 'choo/html';
-
-import { homeView } from './home';
-import { searchView } from './search';
-
-export const viewManager = (state, emit) => {
- // In viewManager all we are doing is checking the app's state
- // and passing the state and emit to the relevant view.
- let htmlContent = html`
loading
`;
- switch (state.params.page) {
- case 'home':
- default: {
- htmlContent = homeView(state, emit);
- break;
- }
- case 'search': {
- htmlContent = searchView(state, emit);
- break;
- }
- }
-
- // Create a wrapper for view content that includes global header/footer
- let view = html`
-
-
-
-
-
- ${htmlContent}
-
-`;
-
- return view;
-}
\ No newline at end of file
diff --git a/src/views/search/controller.js b/src/views/search/controller.js
deleted file mode 100644
index 35bdb0c..0000000
--- a/src/views/search/controller.js
+++ /dev/null
@@ -1,206 +0,0 @@
-import { ViewController } from '../controller';
-
-export class SearchController extends ViewController {
- constructor(state) {
- // Super passes state, view name, and default state to ViewController,
- // which stores state in this.appState and the view controller's state to this.state
- super(state, 'search', {
- done: false,
- results: [],
- });
-
- // If using controller methods in an input's onchange or onclick instance,
- // either bind the class's 'this' instance to the method first...
- // or use `onclick=${() => controller.submit()}` to maintain the 'this' of the class instead.
- }
-
- get results() {
- return [...this.state.results];
- }
-
- get hasQuery() {
- return this.appState.query.hasOwnProperty('for') && this.appState.query.for.trim() !== '';
- }
-
- /**
- * Query a MediaWiki api.php instance with the given options
- */
- mediaWikiQuery(endpoint, options) {
- /**
- * Create a uniquely-named callback that will process the JSONP results
- */
- var createCallback = function (k) {
- var i = 1;
- var callbackName;
- do {
- callbackName = 'searchCallback' + i;
- i = i + 1;
- } while (window[callbackName])
- window[callbackName] = k;
- return callbackName;
- }
-
- /**
- * Flatten an object into a URL query string.
- * For example: { foo: 'bar', baz: 42 } becomes 'foo=bar&baz=42'
- */
- var queryStr = function (options) {
- var query = [];
- for (var i in options) {
- if (options.hasOwnProperty(i)) {
- query.push(encodeURIComponent(i) + '=' + encodeURIComponent(options[i]));
- }
- }
- return query.join('&');
- }
-
- /**
- * Build a function that can be applied to a callback. The callback processes
- * the JSON results of the API call.
- */
- return function (k) {
- options.format = 'json';
- options.callback = createCallback(k);
- var script = document.createElement('script');
- script.id = 'searchResults';
- script.src = endpoint + '?' + queryStr(options);
- var head = document.getElementsByTagName('head')[0];
- head.appendChild(script);
- };
-
- }
-
- search(term) {
- const query = this.mediaWikiQuery('https://en.wikibooks.org/w/api.php', {
- action: 'query',
- list: 'search',
- // list: 'categorymembers',
- // cmtitle: 'Category:Subject:Books by subject/all books',
- srsearch: term,
- srprop: '',
- // pageids: 20308,
- // prop: 'categories|pageprops',
- });
- query(response => {
- console.log(response);
- const searchScript = document.getElementById('searchResults');
- searchScript.parentNode.removeChild(searchScript);
- for (let property in window) {
- if (property.includes('searchCallback')) {
- delete window[property];
- }
- }
-
- const bookResults = [];
- const pageids = response.query.search.map(item => item.pageid);
- const propsQuery = this.mediaWikiQuery('https://en.wikibooks.org/w/api.php', {
- action: 'query',
- pageids: pageids.join('|'),
- prop: 'categories|pageprops',
- });
- propsQuery(propsResponse => {
- console.log(propsResponse);
- for (let pageid in propsResponse.query.pages) {
- if (propsResponse.query.pages[pageid].hasOwnProperty('categories')) {
-
- }
- }
- });
- // this.state.results = results;
- this.state.done = true;
- });
-
- // return fetch(`https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${term}&format=json&callback=searchCallback`, {
- // method: 'GET',
- // mode: 'no-cors',
- // headers: new Headers(
- // {
- // "Accept": "text/plain"
- // }
- // ),
- // // body: JSON.stringify({
- // // action: 'opensearch',
- // // search: term,
- // // format: 'json',
- // // }),
- // })
- // .then(res => res.text())
- // .then(response => {
- // console.log(response);
- // // if (response.hasOwnProperty('docs')) {
- // // // Format the response into usable objects
- // // const docs = response.docs.map(doc => {
- // // return {
- // // title: doc.title_suggest.trim(),
- // // authors: doc.hasOwnProperty('author_name') ? doc.author_name.map(name => name.trim()) : [],
- // // cover: doc.hasOwnProperty('cover_i') ? `//covers.openlibrary.org/b/id/${doc.cover_i}-S.jpg` : false,
- // // };
- // // });
-
- // // // Filter out duplicate items with the same title and author
- // // const results = docs.filter((doc, index, allDocs) => {
- // // return typeof allDocs.find((filterResult, filterIndex) => {
- // // return index !== filterIndex && filterResult.title === doc.title
- // // && JSON.stringify(filterResult.authors) === JSON.stringify(doc.authors);
- // // }) === 'undefined';
- // // }).map(result => {
- // // // Find any duplicates in case they have different cover data
- // // const duplicates = docs.filter(doc => {
- // // return doc.title.toLowerCase() === result.title.toLowerCase() && JSON.stringify(doc.authors) === JSON.stringify(result.authors);
- // // });
- // // result.covers = [];
- // // duplicates.forEach(duplicate => {
- // // if (duplicate.cover !== false) {
- // // result.covers.push(duplicate.cover);
- // // }
- // // });
- // // return result;
- // // });
-
- // // this.state.results = results;
- // this.state.done = true;
- // // }
- // });
- }
-
- searchOpenLibrary(term) {
- this.state.done = false;
- return fetch('http://openlibrary.org/search.json?q=' + encodeURIComponent(term))
- .then(res => res.json())
- .then(response => {
- if (response.hasOwnProperty('docs')) {
- // Format the response into usable objects
- const docs = response.docs.map(doc => {
- return {
- title: doc.title_suggest.trim(),
- authors: doc.hasOwnProperty('author_name') ? doc.author_name.map(name => name.trim()) : [],
- cover: doc.hasOwnProperty('cover_i') ? `//covers.openlibrary.org/b/id/${doc.cover_i}-S.jpg` : false,
- };
- });
-
- // Filter out duplicate items with the same title and author
- const results = docs.filter((doc, index, allDocs) => {
- return typeof allDocs.find((filterResult, filterIndex) => {
- return index !== filterIndex && filterResult.title === doc.title
- && JSON.stringify(filterResult.authors) === JSON.stringify(doc.authors);
- }) === 'undefined';
- }).map(result => {
- // Find any duplicates in case they have different cover data
- const duplicates = docs.filter(doc => {
- return doc.title.toLowerCase() === result.title.toLowerCase() && JSON.stringify(doc.authors) === JSON.stringify(result.authors);
- });
- result.covers = [];
- duplicates.forEach(duplicate => {
- if (duplicate.cover !== false) {
- result.covers.push(duplicate.cover);
- }
- });
- return result;
- });
-
- this.state.results = results;
- this.state.done = true;
- }
- });
- }
-}
\ No newline at end of file
diff --git a/src/views/search/index.js b/src/views/search/index.js
deleted file mode 100644
index c668fe8..0000000
--- a/src/views/search/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import html from 'choo/html';
-
-// We'll see if code splitting is worth it in the end or if we should combine everything into `src/index.scss`
-import { SearchController } from './controller'; // The controller for this view, where processing should happen.
-
-// This is the view function that is exported and used in the view manager.
-export const searchView = (state, emit) => {
- const controller = new SearchController(state);
-
- if (!controller.state.done && controller.hasQuery) {
- controller.searchOpenLibrary(state.query.for).then(() => {
- emit('render');
- });
- }
-
- // Returning an array in a view allows non-shared parent HTML elements.
- // This one doesn't have the problem right now, but it's good to remember.
- return [
- html`
-