diff --git a/app/controllers/api/v2/search_controller.rb b/app/controllers/api/v2/search_controller.rb new file mode 100644 index 000000000..2e91d68ee --- /dev/null +++ b/app/controllers/api/v2/search_controller.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class Api::V2::SearchController < Api::V1::SearchController + def index + @search = Search.new(search) + render json: @search, serializer: REST::V2::SearchSerializer + end +end diff --git a/app/javascript/mastodon/actions/search.js b/app/javascript/mastodon/actions/search.js index 882c1709e..b670d25c3 100644 --- a/app/javascript/mastodon/actions/search.js +++ b/app/javascript/mastodon/actions/search.js @@ -33,7 +33,7 @@ export function submitSearch() { dispatch(fetchSearchRequest()); - api(getState).get('/api/v1/search', { + api(getState).get('/api/v2/search', { params: { q: value, resolve: true, diff --git a/app/javascript/mastodon/features/compose/components/search_results.js b/app/javascript/mastodon/features/compose/components/search_results.js index f2655c14d..445bf27bb 100644 --- a/app/javascript/mastodon/features/compose/components/search_results.js +++ b/app/javascript/mastodon/features/compose/components/search_results.js @@ -16,6 +16,28 @@ const shortNumberFormat = number => { } }; +const renderHashtag = hashtag => ( +
+
+ + #{hashtag.get('name')} + + + {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']))} }} /> +
+ +
+ {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']))} +
+ +
+ day.get('uses')).toArray()}> + + +
+
+); + export default class SearchResults extends ImmutablePureComponent { static propTypes = { @@ -44,27 +66,7 @@ export default class SearchResults extends ImmutablePureComponent { - {trends && trends.map(hashtag => ( -
-
- - #{hashtag.get('name')} - - - {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']))} }} /> -
- -
- {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']))} -
- -
- day.get('uses')).toArray()}> - - -
-
- ))} + {trends && trends.map(hashtag => renderHashtag(hashtag))} ); @@ -74,7 +76,7 @@ export default class SearchResults extends ImmutablePureComponent { count += results.get('accounts').size; accounts = (
-
+
{results.get('accounts').map(accountId => )}
@@ -85,7 +87,7 @@ export default class SearchResults extends ImmutablePureComponent { count += results.get('statuses').size; statuses = (
-
+
{results.get('statuses').map(statusId => )}
@@ -96,13 +98,9 @@ export default class SearchResults extends ImmutablePureComponent { count += results.get('hashtags').size; hashtags = (
-
+
- {results.get('hashtags').map(hashtag => ( - - {hashtag} - - ))} + {results.get('hashtags').map(hashtag => renderHashtag(hashtag))}
); } diff --git a/app/javascript/mastodon/reducers/search.js b/app/javascript/mastodon/reducers/search.js index 56fd7226b..4758defb1 100644 --- a/app/javascript/mastodon/reducers/search.js +++ b/app/javascript/mastodon/reducers/search.js @@ -9,7 +9,7 @@ import { COMPOSE_REPLY, COMPOSE_DIRECT, } from '../actions/compose'; -import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; +import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; const initialState = ImmutableMap({ value: '', @@ -39,7 +39,7 @@ export default function search(state = initialState, action) { return state.set('results', ImmutableMap({ accounts: ImmutableList(action.results.accounts.map(item => item.id)), statuses: ImmutableList(action.results.statuses.map(item => item.id)), - hashtags: ImmutableList(action.results.hashtags), + hashtags: fromJS(action.results.hashtags), })).set('submitted', true); default: return state; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index a2a18b5a0..c93d8e86a 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -3284,6 +3284,15 @@ a.status-card { } .search__icon { + &::-moz-focus-inner { + border: 0; + } + + &::-moz-focus-inner, + &:focus { + outline: 0 !important; + } + .fa { position: absolute; top: 10px; @@ -3333,7 +3342,6 @@ a.status-card { .search-results__header { color: $dark-text-color; background: lighten($ui-base-color, 2%); - border-bottom: 1px solid darken($ui-base-color, 4%); padding: 15px; font-weight: 500; font-size: 16px; @@ -3346,33 +3354,21 @@ a.status-card { } .search-results__section { - margin-bottom: 20px; + margin-bottom: 5px; h5 { - position: relative; - - &::before { - content: ""; - display: block; - position: absolute; - left: 0; - right: 0; - top: 50%; - width: 100%; - height: 0; - border-top: 1px solid lighten($ui-base-color, 8%); - } + background: darken($ui-base-color, 4%); + border-bottom: 1px solid lighten($ui-base-color, 8%); + cursor: default; + display: flex; + padding: 15px; + font-weight: 500; + font-size: 16px; + color: $dark-text-color; - span { + .fa { display: inline-block; - background: $ui-base-color; - color: $darker-text-color; - font-size: 14px; - font-weight: 500; - padding: 10px; - position: relative; - z-index: 1; - cursor: default; + margin-right: 5px; } } diff --git a/app/serializers/rest/v2/search_serializer.rb b/app/serializers/rest/v2/search_serializer.rb new file mode 100644 index 000000000..cdb6b3a53 --- /dev/null +++ b/app/serializers/rest/v2/search_serializer.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class REST::V2::SearchSerializer < ActiveModel::Serializer + has_many :accounts, serializer: REST::AccountSerializer + has_many :statuses, serializer: REST::StatusSerializer + has_many :hashtags, serializer: REST::TagSerializer +end diff --git a/config/routes.rb b/config/routes.rb index 2fcb885ed..31e90e2ff 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -315,6 +315,10 @@ Rails.application.routes.draw do end end + namespace :v2 do + get '/search', to: 'search#index', as: :search + end + namespace :web do resource :settings, only: [:update] resource :embed, only: [:create]