mirror of
				https://gitlab.com/Alamantus/Readlebee.git
				synced 2025-11-03 17:57:03 +01:00 
			
		
		
		
	Add search icon; move search bar to /search
This commit is contained in:
		
							parent
							
								
									8e9f74a901
								
							
						
					
					
						commit
						eab60fe159
					
				
					 17 changed files with 104 additions and 74 deletions
				
			
		| 
						 | 
				
			
			@ -19,6 +19,15 @@ Font license info
 | 
			
		|||
   Homepage:  http://typicons.com/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Iconic
 | 
			
		||||
 | 
			
		||||
   Copyright (C) 2012 by P.J. Onori
 | 
			
		||||
 | 
			
		||||
   Author:    P.J. Onori
 | 
			
		||||
   License:   SIL (http://scripts.sil.org/OFL)
 | 
			
		||||
   Homepage:  http://somerandomdude.com/work/iconic/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Fontelico
 | 
			
		||||
 | 
			
		||||
   Copyright (C) 2012 by Fontello project
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								app/fonts/fontello/css/icons-codes.css
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								app/fonts/fontello/css/icons-codes.css
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
.icon-reload:before { content: '\e806'; } /* '' */
 | 
			
		||||
.icon-check:before { content: '\e807'; } /* '' */
 | 
			
		||||
.icon-plus:before { content: '\e808'; } /* '' */
 | 
			
		||||
.icon-search:before { content: '\e809'; } /* '' */
 | 
			
		||||
.icon-loading:before { content: '\e839'; } /* '' */
 | 
			
		||||
.icon-external:before { content: '\f08e'; } /* '' */
 | 
			
		||||
.icon-star-half:before { content: '\f123'; } /* '' */
 | 
			
		||||
							
								
								
									
										13
									
								
								app/fonts/fontello/css/icons-embedded.css
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								app/fonts/fontello/css/icons-embedded.css
									
										
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								app/fonts/fontello/css/icons-ie7-codes.css
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								app/fonts/fontello/css/icons-ie7-codes.css
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
.icon-reload { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-check { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-search { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-loading { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-external { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-star-half { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
							
								
								
									
										1
									
								
								app/fonts/fontello/css/icons-ie7.css
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								app/fonts/fontello/css/icons-ie7.css
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -19,6 +19,7 @@
 | 
			
		|||
.icon-reload { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-check { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-search { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-loading { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-external { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
.icon-star-half { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
 | 
			
		||||
							
								
								
									
										15
									
								
								app/fonts/fontello/css/icons.css
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								app/fonts/fontello/css/icons.css
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
@font-face {
 | 
			
		||||
  font-family: 'icons';
 | 
			
		||||
  src: url('../font/icons.eot?91391620');
 | 
			
		||||
  src: url('../font/icons.eot?91391620#iefix') format('embedded-opentype'),
 | 
			
		||||
       url('../font/icons.woff2?91391620') format('woff2'),
 | 
			
		||||
       url('../font/icons.woff?91391620') format('woff'),
 | 
			
		||||
       url('../font/icons.ttf?91391620') format('truetype'),
 | 
			
		||||
       url('../font/icons.svg?91391620#icons') format('svg');
 | 
			
		||||
  src: url('../font/icons.eot?3055787');
 | 
			
		||||
  src: url('../font/icons.eot?3055787#iefix') format('embedded-opentype'),
 | 
			
		||||
       url('../font/icons.woff2?3055787') format('woff2'),
 | 
			
		||||
       url('../font/icons.woff?3055787') format('woff'),
 | 
			
		||||
       url('../font/icons.ttf?3055787') format('truetype'),
 | 
			
		||||
       url('../font/icons.svg?3055787#icons') format('svg');
 | 
			
		||||
  font-weight: normal;
 | 
			
		||||
  font-style: normal;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +15,7 @@
 | 
			
		|||
@media screen and (-webkit-min-device-pixel-ratio:0) {
 | 
			
		||||
  @font-face {
 | 
			
		||||
    font-family: 'icons';
 | 
			
		||||
    src: url('../font/icons.svg?91391620#icons') format('svg');
 | 
			
		||||
    src: url('../font/icons.svg?3055787#icons') format('svg');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			@ -64,6 +64,7 @@
 | 
			
		|||
.icon-reload:before { content: '\e806'; } /* '' */
 | 
			
		||||
.icon-check:before { content: '\e807'; } /* '' */
 | 
			
		||||
.icon-plus:before { content: '\e808'; } /* '' */
 | 
			
		||||
.icon-search:before { content: '\e809'; } /* '' */
 | 
			
		||||
.icon-loading:before { content: '\e839'; } /* '' */
 | 
			
		||||
.icon-external:before { content: '\f08e'; } /* '' */
 | 
			
		||||
.icon-star-half:before { content: '\f123'; } /* '' */
 | 
			
		||||
| 
						 | 
				
			
			@ -229,11 +229,11 @@ body {
 | 
			
		|||
}
 | 
			
		||||
@font-face {
 | 
			
		||||
      font-family: 'icons';
 | 
			
		||||
      src: url('./font/icons.eot?91427620');
 | 
			
		||||
      src: url('./font/icons.eot?91427620#iefix') format('embedded-opentype'),
 | 
			
		||||
           url('./font/icons.woff?91427620') format('woff'),
 | 
			
		||||
           url('./font/icons.ttf?91427620') format('truetype'),
 | 
			
		||||
           url('./font/icons.svg?91427620#icons') format('svg');
 | 
			
		||||
      src: url('./font/icons.eot?21491342');
 | 
			
		||||
      src: url('./font/icons.eot?21491342#iefix') format('embedded-opentype'),
 | 
			
		||||
           url('./font/icons.woff?21491342') format('woff'),
 | 
			
		||||
           url('./font/icons.ttf?21491342') format('truetype'),
 | 
			
		||||
           url('./font/icons.svg?21491342#icons') format('svg');
 | 
			
		||||
      font-weight: normal;
 | 
			
		||||
      font-style: normal;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -311,8 +311,11 @@ body {
 | 
			
		|||
      </div>
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="the-icons span3" title="Code: 0xe808"><i class="demo-icon icon-plus"></i> <span class="i-name">icon-plus</span><span class="i-code">0xe808</span></div>
 | 
			
		||||
        <div class="the-icons span3" title="Code: 0xe809"><i class="demo-icon icon-search"></i> <span class="i-name">icon-search</span><span class="i-code">0xe809</span></div>
 | 
			
		||||
        <div class="the-icons span3" title="Code: 0xe839"><i class="demo-icon icon-loading animate-spin"></i> <span class="i-name">icon-loading</span><span class="i-code">0xe839</span></div>
 | 
			
		||||
        <div class="the-icons span3" title="Code: 0xf08e"><i class="demo-icon icon-external"></i> <span class="i-name">icon-external</span><span class="i-code">0xf08e</span></div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="the-icons span3" title="Code: 0xf123"><i class="demo-icon icon-star-half"></i> <span class="i-name">icon-star-half</span><span class="i-code">0xf123</span></div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -24,6 +24,8 @@
 | 
			
		|||
 | 
			
		||||
<glyph glyph-name="plus" unicode="" d="M729 454q44 0 74-31t31-73-31-73-74-30l-208 3 0-212q0-43-30-73t-75-31-73 31-30 73l3 212-212-3q-44 0-74 30t-30 73 30 73 74 31l212 0-3 209q0 42 30 73t73 31 75-31 30-73l0-209 208 0z" horiz-adv-x="834" />
 | 
			
		||||
 | 
			
		||||
<glyph glyph-name="search" unicode="" d="M335 246l25-25q-28-28-85-86t-73-74l-27 27q16 15 74 73t86 85z m245 551q136 0 234-97t97-234-97-234-234-96q-64 0-123 24l-255-257-184 185 256 255q-26 63-26 123 0 137 98 234t234 97z m0-551q91 0 155 64t64 156-64 155-155 64-156-64-64-155 64-156 156-64z" horiz-adv-x="928" />
 | 
			
		||||
 | 
			
		||||
<glyph glyph-name="loading" unicode="" d="M855 9c-189-190-520-172-705 13-190 190-200 494-28 695 11 13 21 26 35 34 36 23 85 18 117-13 30-31 35-76 16-112-5-9-9-15-16-22-140-151-145-379-8-516 153-153 407-121 542 34 106 122 142 297 77 451-83 198-305 291-510 222l0 1c236 82 492-24 588-252 71-167 37-355-72-493-11-15-23-29-36-42z" horiz-adv-x="1000" />
 | 
			
		||||
 | 
			
		||||
<glyph glyph-name="external" unicode="" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
		 Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 5 KiB  | 
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -77,6 +77,12 @@
 | 
			
		|||
      "css": "reload",
 | 
			
		||||
      "code": 59398,
 | 
			
		||||
      "src": "fontawesome"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "uid": "c6344a6ed148da12354cc90705287696",
 | 
			
		||||
      "css": "search",
 | 
			
		||||
      "code": 59401,
 | 
			
		||||
      "src": "iconic"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
  "name": "English",
 | 
			
		||||
  "locale": "en",
 | 
			
		||||
  "global": {
 | 
			
		||||
    "searchbar_placeholder": "Search for Books",
 | 
			
		||||
    "menu_search": "Search for Books",
 | 
			
		||||
    "menu_login": "Log In",
 | 
			
		||||
    "menu_logout": "Log Out",
 | 
			
		||||
    "footer_repo": "Repo",
 | 
			
		||||
| 
						 | 
				
			
			@ -35,8 +35,9 @@
 | 
			
		|||
  },
 | 
			
		||||
  "search": {
 | 
			
		||||
    "header": "Search",
 | 
			
		||||
    "placeholder": "Search for Books",
 | 
			
		||||
    "button_text": "Search",
 | 
			
		||||
    "loading": "Loading...",
 | 
			
		||||
    "results_header": "Results for:",
 | 
			
		||||
    "no_results": "None Found",
 | 
			
		||||
    "no_results_suggestion": "If you're expecting book data, go and help fill out the Inventaire database!",
 | 
			
		||||
    "people_header": "People",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,14 +18,7 @@ export const globalView = (state, emit, i18n, view) => {
 | 
			
		|||
      <label for="navMenu" class="burger pseudo button">${'\u2261'}</label>
 | 
			
		||||
    
 | 
			
		||||
      <div class="menu">
 | 
			
		||||
        <label style="display: inline-block;">
 | 
			
		||||
          <input type="text" name="search"
 | 
			
		||||
            placeholder=${i18n.__('global.searchbar_placeholder')}
 | 
			
		||||
            onchange=${e => {
 | 
			
		||||
              emit('pushState', '/search?for=' + encodeURIComponent(e.target.value.trim()));
 | 
			
		||||
            }}
 | 
			
		||||
          >
 | 
			
		||||
        </label>
 | 
			
		||||
        <a href="/search" class="pseudo button"><i class="icon-search" aria-label=${i18n.__('global.menu_search')}></i></a>
 | 
			
		||||
        <a href="/login" class="pseudo button">${i18n.__('global.menu_login')}</a>
 | 
			
		||||
        <a href="/logout" class="pseudo button">${i18n.__('global.menu_logout')}</a>
 | 
			
		||||
      </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,8 +5,8 @@ export class SearchController extends ViewController {
 | 
			
		|||
    // 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, i18n, 'search', {
 | 
			
		||||
      lastSearch: undefined,
 | 
			
		||||
      done: false,
 | 
			
		||||
      lastSearch: '',
 | 
			
		||||
      done: true,
 | 
			
		||||
      results: {
 | 
			
		||||
        humans: [],
 | 
			
		||||
        series: [],
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +34,10 @@ export class SearchController extends ViewController {
 | 
			
		|||
    return this.appState.query.hasOwnProperty('for') && this.appState.query.for.trim() !== '';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get queryIsNew() {
 | 
			
		||||
    return this.state.lastSearch !== this.appState.query.for.trim();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get openModal() {
 | 
			
		||||
    return this.state.openModal;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,58 +8,65 @@ export const searchView = (state, emit, i18n) => {
 | 
			
		|||
  const controller = new SearchController(state, emit, i18n);
 | 
			
		||||
  const { __ } = controller.i18n;
 | 
			
		||||
 | 
			
		||||
  if (controller.state.lastSearch !== state.query.for) {
 | 
			
		||||
  if (controller.hasQuery && controller.queryIsNew) {
 | 
			
		||||
    controller.search();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 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`<section>
 | 
			
		||||
      <h1 class="title">${__('search.header')}</h1>
 | 
			
		||||
      
 | 
			
		||||
      <article>
 | 
			
		||||
        <div class="flex">
 | 
			
		||||
          <div class="two-third-700">
 | 
			
		||||
            <h2>
 | 
			
		||||
              ${controller.doneSearching
 | 
			
		||||
                ? html`<span>${__('search.results_header')}</span> <code>${controller.state.lastSearch}</code>`
 | 
			
		||||
                : html`<span>${__('search.loading')}</span>`
 | 
			
		||||
              }
 | 
			
		||||
            </h2>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="one-third-700">
 | 
			
		||||
          ${controller.doneSearching
 | 
			
		||||
            ? html`<span class="pull-right" data-tooltip=${__('interaction.reload')}>
 | 
			
		||||
              <button class="pseudo" onclick=${() => controller.search()}>
 | 
			
		||||
                <i class="icon-reload"></i>
 | 
			
		||||
              </button>
 | 
			
		||||
            </span>`
 | 
			
		||||
            : html`<i class="icon-loading animate-spin"></i>`
 | 
			
		||||
          }
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    html`<h1 class="title">${__('search.header')}</h1>`,
 | 
			
		||||
 | 
			
		||||
        ${!controller.doneSearching || controller.results.works < 1
 | 
			
		||||
          ? [
 | 
			
		||||
            html`<h3>${__('search.no_results')}</h3>`,
 | 
			
		||||
            html`<a class="button" href="https://wiki.inventaire.io/wiki/How-to-contribute" target="_blank">
 | 
			
		||||
              ${__('search.no_results_suggestion')}
 | 
			
		||||
            </a>`
 | 
			
		||||
          ]
 | 
			
		||||
          : controller.results.works.map(result => {
 | 
			
		||||
            return html`<div class="flex search-result">
 | 
			
		||||
              <div class="two-third-800 half-500">
 | 
			
		||||
                <h3 class="title">${result.name}</h3>
 | 
			
		||||
                ${result.description ? html`<h4 class="subtitle">${result.description}</h4>` : null}
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="third-800 half-500">
 | 
			
		||||
                ${resultDetails(controller, result, emit)}
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>`;
 | 
			
		||||
          })
 | 
			
		||||
    html`<section class="flex">
 | 
			
		||||
        <label class="three-fourth">
 | 
			
		||||
          <input type="text" name="search"
 | 
			
		||||
            aria-label=${i18n.__('search.placeholder')}
 | 
			
		||||
            placeholder=${i18n.__('search.placeholder')}
 | 
			
		||||
            value=${controller.state.lastSearch}
 | 
			
		||||
            onchange=${e => {
 | 
			
		||||
              emit('pushState', '/search?for=' + encodeURIComponent(e.target.value.trim()));
 | 
			
		||||
            }}
 | 
			
		||||
            ${!controller.doneSearching ? 'disabled' : null}
 | 
			
		||||
          >
 | 
			
		||||
        </label>
 | 
			
		||||
        <button class="fourth" style="margin-top:0;height:2.1em;" onclick=${() => controller.search()} ${!controller.doneSearching ? 'disabled' : null}>
 | 
			
		||||
          ${!controller.doneSearching
 | 
			
		||||
            ? html`<i class="icon-loading animate-spin"></i>`
 | 
			
		||||
            : __('search.button_text')
 | 
			
		||||
          }
 | 
			
		||||
        </button>
 | 
			
		||||
      </section>`,
 | 
			
		||||
 | 
			
		||||
    html`<section>
 | 
			
		||||
    </section>`,
 | 
			
		||||
      
 | 
			
		||||
    html`<section>
 | 
			
		||||
      <h2>
 | 
			
		||||
        ${controller.hasQuery && !controller.doneSearching
 | 
			
		||||
          ? html`<span>${__('search.loading')}</span> <i class="icon-loading animate-spin"></i>`
 | 
			
		||||
          : null
 | 
			
		||||
        }
 | 
			
		||||
      </article>
 | 
			
		||||
      </h2>
 | 
			
		||||
 | 
			
		||||
      ${controller.hasQuery && controller.doneSearching && controller.results.works < 1
 | 
			
		||||
        ? [
 | 
			
		||||
          html`<h3>${__('search.no_results')}</h3>`,
 | 
			
		||||
          html`<a class="button" href="https://wiki.inventaire.io/wiki/How-to-contribute" target="_blank">
 | 
			
		||||
            ${__('search.no_results_suggestion')}
 | 
			
		||||
          </a>`
 | 
			
		||||
        ]
 | 
			
		||||
        : controller.results.works.map(result => {
 | 
			
		||||
          return html`<article class="flex search-result">
 | 
			
		||||
            <header class="two-third-800 half-500">
 | 
			
		||||
              <h3 class="title">${result.name}</h3>
 | 
			
		||||
              ${result.description ? html`<h4 class="subtitle">${result.description}</h4>` : null}
 | 
			
		||||
            </header>
 | 
			
		||||
            <footer class="third-800 half-500">
 | 
			
		||||
              ${resultDetails(controller, result, emit)}
 | 
			
		||||
            </footer>
 | 
			
		||||
          </article>`;
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    </section>`,
 | 
			
		||||
  ];
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue