Skip to content

Commit

Permalink
Merge branch 'search'
Browse files Browse the repository at this point in the history
  • Loading branch information
elzup committed Oct 29, 2017
2 parents 305c7e9 + 8b6254c commit d9047ec
Show file tree
Hide file tree
Showing 45 changed files with 556 additions and 155 deletions.
3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "react-app"
}
1 change: 1 addition & 0 deletions .storybook/head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" />
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,16 @@
"@storybook/addon-actions": "^3.2.12",
"@storybook/addon-links": "^3.2.12",
"@storybook/react": "^3.2.12",
"babel-eslint": "^7.2.3",
"enzyme": "^3.0.0",
"enzyme-adapter-react-16": "^1.0.0",
"enzyme-to-json": "^3.0.1",
"eslint": "^4.1.1",
"eslint-config-react-app": "^2.0.1",
"eslint-plugin-flowtype": "^2.34.1",
"eslint-plugin-import": "^2.6.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.1.0",
"flow-bin": "^0.56.0",
"husky": "^0.14.3",
"lint-staged": "^4.3.0",
Expand Down
7 changes: 7 additions & 0 deletions src/.imports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
excludes: ['node_modules/**/test/**'],
aliases: {
$: 'third-party-libs/jquery',
_: 'third-party-libs/underscore',
},
}
28 changes: 19 additions & 9 deletions src/api/client.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// @flow

import camelcaseKeys from 'camelcase-keys'
import _ from 'lodash'
import { normalizeStories } from './normalize'
import request from 'superagent'
import _ from 'lodash'

import type {
Story,
Blog,
Tag,
QueryParams,
PageInfo,
Screen,
Expand All @@ -22,14 +23,12 @@ const UseHeader = {
}

const host =
process.env.NODE_ENV == 'development'
process.env.NODE_ENV === 'development'
? // ? 'http://localhost:3001'
'https://ssconnect.elzup.com'
: 'https://ssconnect.elzup.com'
const TIMEOUT = 1000

const requestHeaders = _.values(UseHeader).join(', ')

const baseHeaders = {
'Content-Type': 'application/json',
}
Expand All @@ -44,6 +43,10 @@ function permitQuery(screen: Screen): QueryParams {
const { page, tag, q } = screen
return { page, tag, q }
}
case 'profile': {
const { page, tag, q } = screen
return { page, tag, q }
}
default: {
// NOTE: Why can remove?
return { page: 0, tag: '', q: '' }
Expand All @@ -69,11 +72,7 @@ export async function getStories(
.set(baseHeaders)
const res = await new Promise((resolve, reject) => {
storiesRequest.end((err, res) => {
if (err) {
reject(err)
} else {
resolve(res)
}
resolve(err || res)
})
})

Expand All @@ -93,3 +92,14 @@ function getPageInfo(res: any): PageInfo {
prev: parseInt(res.headers[UseHeader.prev], 10) || false,
}
}

export async function getTags(timeout: number = TIMEOUT): Promise<Tag[]> {
const tagsRequest = request.get(host + '/v1/tags').set(baseHeaders)
const res = await new Promise((resolve, reject) => {
tagsRequest.end((err, res) => {
resolve(err || res)
})
})

return _.values(camelcaseKeys(res.body, { deep: true }))
}
41 changes: 31 additions & 10 deletions src/components/BottomBar/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @flow
import * as React from 'react'
import FontAwesome from 'react-fontawesome'
import _ from 'lodash'
import styled from 'styled-components'

import {
Expand All @@ -24,23 +23,45 @@ const Wrapper = styled.div`
width: 100%;
`

function typeConsts(screen: Screen): { iconName: string, label: string } {
switch (screen.type) {
case 'new': {
return {
iconName: 'home',
label: '新着',
}
}
case 'search': {
return {
iconName: 'search',
label: '検索',
}
}
case 'profile': {
return {
iconName: 'tag',
label: screen.q,
}
}
default: {
return {
iconName: '',
label: '',
}
}
}
}

const BottomBar = ({ screens, switchTab, system }: Props) => (
<Wrapper>
<BottomNavigation selectedIndex={system.selectedTab}>
{screens.map(s => {
let icon = <FontAwesome name="home" size="2x" />
let label = '新着'
switch (s.type) {
case 'search': {
icon = <FontAwesome name="search" size="2x" />
label = s.q
}
}
const { iconName, label } = typeConsts(s)
return (
<BottomNavigationItem
key={s.id}
label={label}
icon={icon}
icon={<FontAwesome name={iconName} size="2x" />}
onClick={() => switchTab(s.id)}
/>
)
Expand Down
6 changes: 1 addition & 5 deletions src/components/LoadingIndicator/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
// @flow
import * as React from 'react'
import type { Screen, System } from '../../types'
import FontAwesome from 'react-fontawesome'
import LinearProgress from 'material-ui/LinearProgress'

export type Props = {}

const LoadingIndicator = ({ }: Props) => (
<LinearProgress mode="indeterminate" />
)
const LoadingIndicator = () => <LinearProgress mode="indeterminate" />

export default LoadingIndicator
11 changes: 3 additions & 8 deletions src/components/PagingBar/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
// @flow
import * as React from 'react'
import FontAwesome from 'react-fontawesome'
import _ from 'lodash'
import styled from 'styled-components'
import Slider from 'material-ui/Slider'
import FlatButton from 'material-ui/FlatButton'

import type { Screen, System, PageInfo } from '../../types'
import type { ScreenLoaded } from '../../types'

export type Props = {
screen: Screen,
screen: ScreenLoaded,
pageChange: Function,
}

Expand All @@ -34,14 +32,11 @@ class Component extends React.Component<Props, State> {
constructor(props: Props) {
super(props)
this.state = {
page: props.screen.loaded ? props.screen.pageInfo.page : 0,
page: props.screen.pageInfo.page,
}
}
render() {
const { screen, pageChange } = this.props
if (!screen.loaded) {
return null
}
const { pageInfo } = screen
return (
<Wrapper>
Expand Down
121 changes: 121 additions & 0 deletions src/components/SearchForm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// @flow
import * as React from 'react'
import TextField from 'material-ui/TextField'
import RaisedButton from 'material-ui/RaisedButton'
import { List, ListItem } from 'material-ui/List'
import FontAwesome from 'react-fontawesome'
import styled from 'styled-components'
import type { Tag } from '../../types'

export type Props = {
tags: Tag[],
searchSubmit: Function,
}

type State = {
qText: string,
tagText: string,
}

const Wrapper = styled.div`
padding: 10px;
`

const Inputs = styled.div`
width: 70%;
`

const Row = styled.div`
display: flex;
justify-content: space-between;
`

const IconWrap = styled.div`
margin: 15px auto;
width: 2em;
`

class Component extends React.Component<Props, State> {
constructor(props: Props) {
super(props)
this.state = {
qText: '',
tagText: '',
}
}
render() {
const { props, state } = this
const filteredTags = props.tags.filter(
tag => tag.name.indexOf(state.tagText) !== -1,
)
return (
<Wrapper>
<Row>
<Inputs>
<Row>
<IconWrap>
<FontAwesome name="search" />
</IconWrap>
<TextField
hintText="キーワード・作品・キャラ"
value={state.qText}
onChange={(event: Object, newValue: string) => {
this.setState({
qText: newValue,
})
}}
/>
</Row>
<Row>
<IconWrap>
<FontAwesome name="tag" />
</IconWrap>
<TextField
hintText="タグ"
value={state.tagText}
onChange={(event: Object, newValue: string) => {
console.log(newValue)
this.setState({
tagText: newValue,
})
}}
/>
</Row>
</Inputs>
<RaisedButton
style={{ margin: 5, height: 50, width: 50 }}
label="検索"
onClick={() => {
props.searchSubmit(state.qText, state.tagText)
}}
/>
</Row>
<p>タグ数:{props.tags.length}</p>
<p>絞り込み:{filteredTags.length}</p>
<List>
{filteredTags.map(tag => {
// HACKME
const selected = tag.name === state.tagText
return (
<ListItem
key={tag.id}
rightIcon={
<FontAwesome
name={selected ? 'times-circle-o' : 'circle-thin'}
/>
}
primaryText={tag.name}
onClick={() => {
this.setState({ tagText: selected ? '' : tag.name })
}}
secondaryText="..."
/>
)
})}
</List>
</Wrapper>
)
}
}

export default Component
1 change: 0 additions & 1 deletion src/components/StoryCell/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as React from 'react'
import type { ArticleComp } from '../../types'
import styled from 'styled-components'
import moment from 'moment'
moment.locale('ja')

export type Props = {
article: ArticleComp,
Expand Down
1 change: 0 additions & 1 deletion src/containers/ArticleById/reducer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @flow
import type { Action, Article } from '../../types'
import { Actions } from '../ArticlesContainer/actionTypes'
import { Actions as ArticleActions } from '../ArticlesContainer/actionTypes'

export type State = { [id: number]: Article }

Expand Down
1 change: 0 additions & 1 deletion src/containers/BlogById/reducer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @flow
import type { Action, Blog } from '../../types'
import { Actions } from '../BlogsContainer/actionTypes'
import { Actions as BlogActions } from '../BlogsContainer/actionTypes'

export type State = { [id: number]: Blog }

Expand Down
3 changes: 1 addition & 2 deletions src/containers/BottomBarContainer/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @flow
import * as React from 'react'
import { connect, type Connector } from 'react-redux'
import type { State, Screen } from '../../types'
import type { State } from '../../types'
import BottomBar, { type Props } from '../../components/BottomBar'
import { switchTab } from '../System/actions'
import _ from 'lodash'
Expand Down
13 changes: 11 additions & 2 deletions src/containers/ScreensContainer/actionTypes.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// @flow
import type { ScreenLoaded, Story, PageInfo } from '../../types'
import type { PageInfo } from '../../types'

export const LOADED_SCREEN_STORIES: 'ScreensContainer/LOADED_SCREEN_STORIES' =
'ScreensContainer/LOADED_SCREEN_STORIES'
export const PAGE_CHANGE: 'ScreensContainer/PAGE_CHANGE' =
'ScreensContainer/PAGE_CHANGE'
export const MAKE_SCREEN_PROFILE: 'ScreensContainer/MAKE_SCREEN_PROFILE' =
'ScreensContainer/MAKE_SCREEN_PROFILE'

export const Actions = {
LOADED_SCREEN_STORIES,
PAGE_CHANGE,
MAKE_SCREEN_PROFILE,
}

export type LoadedScreenStories = {
Expand All @@ -24,4 +27,10 @@ export type PageChange = {
newPage: number,
}

export type Action = LoadedScreenStories | PageChange
export type MakeScreenProfile = {
type: typeof MAKE_SCREEN_PROFILE,
q: string,
tag: string,
}

export type Action = LoadedScreenStories | PageChange | MakeScreenProfile
Loading

0 comments on commit d9047ec

Please sign in to comment.