UNPKG

11 kBJavaScriptView Raw
1/*
2 * Copyright 2017 Palantir Technologies, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import * as React from "react";
17import { MenuItem2 } from "@blueprintjs/popover2";
18/** Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top */
19export const TOP_100_FILMS = [
20 { title: "The Shawshank Redemption", year: 1994 },
21 { title: "The Godfather", year: 1972 },
22 { title: "The Godfather: Part II", year: 1974 },
23 { title: "The Dark Knight", year: 2008 },
24 { title: "12 Angry Men", year: 1957 },
25 { title: "Schindler's List", year: 1993 },
26 { title: "Pulp Fiction", year: 1994 },
27 { title: "The Lord of the Rings: The Return of the King", year: 2003 },
28 { title: "The Good, the Bad and the Ugly", year: 1966 },
29 { title: "Fight Club", year: 1999 },
30 { title: "The Lord of the Rings: The Fellowship of the Ring", year: 2001 },
31 { title: "Star Wars: Episode V - The Empire Strikes Back", year: 1980 },
32 { title: "Forrest Gump", year: 1994 },
33 { title: "Inception", year: 2010 },
34 { title: "The Lord of the Rings: The Two Towers", year: 2002 },
35 { title: "One Flew Over the Cuckoo's Nest", year: 1975 },
36 { title: "Goodfellas", year: 1990 },
37 { title: "The Matrix", year: 1999 },
38 { title: "Seven Samurai", year: 1954 },
39 { title: "Star Wars: Episode IV - A New Hope", year: 1977 },
40 { title: "City of God", year: 2002 },
41 { title: "Se7en", year: 1995 },
42 { title: "The Silence of the Lambs", year: 1991 },
43 { title: "It's a Wonderful Life", year: 1946 },
44 { title: "Life Is Beautiful", year: 1997 },
45 { title: "The Usual Suspects", year: 1995 },
46 { title: "Léon: The Professional", year: 1994 },
47 { title: "Spirited Away", year: 2001 },
48 { title: "Saving Private Ryan", year: 1998 },
49 { title: "Once Upon a Time in the West", year: 1968 },
50 { title: "American History X", year: 1998 },
51 { title: "Interstellar", year: 2014 },
52 { title: "Casablanca", year: 1942 },
53 { title: "City Lights", year: 1931 },
54 { title: "Psycho", year: 1960 },
55 { title: "The Green Mile", year: 1999 },
56 { title: "The Intouchables", year: 2011 },
57 { title: "Modern Times", year: 1936 },
58 { title: "Raiders of the Lost Ark", year: 1981 },
59 { title: "Rear Window", year: 1954 },
60 { title: "The Pianist", year: 2002 },
61 { title: "The Departed", year: 2006 },
62 { title: "Terminator 2: Judgment Day", year: 1991 },
63 { title: "Back to the Future", year: 1985 },
64 { title: "Whiplash", year: 2014 },
65 { title: "Gladiator", year: 2000 },
66 { title: "Memento", year: 2000 },
67 { title: "The Prestige", year: 2006 },
68 { title: "The Lion King", year: 1994 },
69 { title: "Apocalypse Now", year: 1979 },
70 { title: "Alien", year: 1979 },
71 { title: "Sunset Boulevard", year: 1950 },
72 { title: "Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb", year: 1964 },
73 { title: "The Great Dictator", year: 1940 },
74 { title: "Cinema Paradiso", year: 1988 },
75 { title: "The Lives of Others", year: 2006 },
76 { title: "Grave of the Fireflies", year: 1988 },
77 { title: "Paths of Glory", year: 1957 },
78 { title: "Django Unchained", year: 2012 },
79 { title: "The Shining", year: 1980 },
80 { title: "WALL·E", year: 2008 },
81 { title: "American Beauty", year: 1999 },
82 { title: "The Dark Knight Rises", year: 2012 },
83 { title: "Princess Mononoke", year: 1997 },
84 { title: "Aliens", year: 1986 },
85 { title: "Oldboy", year: 2003 },
86 { title: "Once Upon a Time in America", year: 1984 },
87 { title: "Witness for the Prosecution", year: 1957 },
88 { title: "Das Boot", year: 1981 },
89 { title: "Citizen Kane", year: 1941 },
90 { title: "North by Northwest", year: 1959 },
91 { title: "Vertigo", year: 1958 },
92 { title: "Star Wars: Episode VI - Return of the Jedi", year: 1983 },
93 { title: "Reservoir Dogs", year: 1992 },
94 { title: "Braveheart", year: 1995 },
95 { title: "M", year: 1931 },
96 { title: "Requiem for a Dream", year: 2000 },
97 { title: "Amélie", year: 2001 },
98 { title: "A Clockwork Orange", year: 1971 },
99 { title: "Like Stars on Earth", year: 2007 },
100 { title: "Taxi Driver", year: 1976 },
101 { title: "Lawrence of Arabia", year: 1962 },
102 { title: "Double Indemnity", year: 1944 },
103 { title: "Eternal Sunshine of the Spotless Mind", year: 2004 },
104 { title: "Amadeus", year: 1984 },
105 { title: "To Kill a Mockingbird", year: 1962 },
106 { title: "Toy Story 3", year: 2010 },
107 { title: "Logan", year: 2017 },
108 { title: "Full Metal Jacket", year: 1987 },
109 { title: "Dangal", year: 2016 },
110 { title: "The Sting", year: 1973 },
111 { title: "2001: A Space Odyssey", year: 1968 },
112 { title: "Singin' in the Rain", year: 1952 },
113 { title: "Toy Story", year: 1995 },
114 { title: "Bicycle Thieves", year: 1948 },
115 { title: "The Kid", year: 1921 },
116 { title: "Inglourious Basterds", year: 2009 },
117 { title: "Snatch", year: 2000 },
118 { title: "3 Idiots", year: 2009 },
119 { title: "Monty Python and the Holy Grail", year: 1975 },
120].map((f, index) => ({ ...f, rank: index + 1 }));
121/**
122 * Takes the same arguments as `ItemRenderer<Film>`, but returns the common menu item
123 * props for that item instead of the rendered element itself. This is useful for implementing
124 * custom item renderers.
125 */
126export function getFilmItemProps(film, { handleClick, handleFocus, modifiers, ref, query }) {
127 return {
128 active: modifiers.active,
129 disabled: modifiers.disabled,
130 elementRef: ref,
131 key: film.rank,
132 label: film.year.toString(),
133 onClick: handleClick,
134 onFocus: handleFocus,
135 roleStructure: "listoption",
136 text: highlightText(`${film.rank}. ${film.title}`, query),
137 };
138}
139/**
140 * Simple film item renderer _without_ support for "selected" appearance.
141 */
142export const renderFilm = (film, props) => {
143 if (!props.modifiers.matchesPredicate) {
144 return null;
145 }
146 return React.createElement(MenuItem2, { ...getFilmItemProps(film, props) });
147};
148/**
149 * Renders a menu item to create a single film from a given query string.
150 */
151export const renderCreateFilmMenuItem = (query, active, handleClick) => (React.createElement(MenuItem2, { icon: "add", text: `Create "${query}"`, roleStructure: "listoption", active: active, onClick: handleClick, shouldDismissPopover: false }));
152/**
153 * Renders a menu item to create one or more films from a given query string.
154 */
155export const renderCreateFilmsMenuItem = (query, active, handleClick) => (React.createElement(MenuItem2, { icon: "add", text: `Create ${printReadableList(query)}`, roleStructure: "listoption", active: active, onClick: handleClick, shouldDismissPopover: false }));
156/**
157 * Given a user-provided list of strings separated by commas, this helper function parses the list and
158 * returns a more readable version of it.
159 *
160 * For example, the input 'a, b, c' becomes '"a", "b", and "c"'.
161 */
162function printReadableList(query) {
163 return query
164 .split(", ")
165 .map((title, index, titles) => {
166 const separator = index > 0 ? (index === titles.length - 1 ? " and " : ", ") : "";
167 return `${separator}"${title}"`;
168 })
169 .join("");
170}
171export const filterFilm = (query, film, _index, exactMatch) => {
172 const normalizedTitle = film.title.toLowerCase();
173 const normalizedQuery = query.toLowerCase();
174 if (exactMatch) {
175 return normalizedTitle === normalizedQuery;
176 }
177 else {
178 return `${film.rank}. ${normalizedTitle} ${film.year}`.indexOf(normalizedQuery) >= 0;
179 }
180};
181function highlightText(text, query) {
182 let lastIndex = 0;
183 const words = query
184 .split(/\s+/)
185 .filter(word => word.length > 0)
186 .map(escapeRegExpChars);
187 if (words.length === 0) {
188 return [text];
189 }
190 const regexp = new RegExp(words.join("|"), "gi");
191 const tokens = [];
192 while (true) {
193 const match = regexp.exec(text);
194 if (!match) {
195 break;
196 }
197 const length = match[0].length;
198 const before = text.slice(lastIndex, regexp.lastIndex - length);
199 if (before.length > 0) {
200 tokens.push(before);
201 }
202 lastIndex = regexp.lastIndex;
203 tokens.push(React.createElement("strong", { key: lastIndex }, match[0]));
204 }
205 const rest = text.slice(lastIndex);
206 if (rest.length > 0) {
207 tokens.push(rest);
208 }
209 return tokens;
210}
211function escapeRegExpChars(text) {
212 return text.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
213}
214export function createFilm(title) {
215 return {
216 rank: 100 + Math.floor(Math.random() * 100 + 1),
217 title,
218 year: new Date().getFullYear(),
219 };
220}
221export function createFilms(query) {
222 const titles = query.split(", ");
223 return titles.map((title, index) => ({
224 rank: 100 + Math.floor(Math.random() * 100 + index),
225 title,
226 year: new Date().getFullYear(),
227 }));
228}
229export function areFilmsEqual(filmA, filmB) {
230 // Compare only the titles (ignoring case) just for simplicity.
231 return filmA.title.toLowerCase() === filmB.title.toLowerCase();
232}
233export function doesFilmEqualQuery(film, query) {
234 return film.title.toLowerCase() === query.toLowerCase();
235}
236export function arrayContainsFilm(films, filmToFind) {
237 return films.some((film) => film.title === filmToFind.title);
238}
239export function addFilmToArray(films, filmToAdd) {
240 return [...films, filmToAdd];
241}
242export function deleteFilmFromArray(films, filmToDelete) {
243 return films.filter(film => film !== filmToDelete);
244}
245export function maybeAddCreatedFilmToArrays(items, createdItems, film) {
246 const isNewlyCreatedItem = !arrayContainsFilm(items, film);
247 return {
248 createdItems: isNewlyCreatedItem ? addFilmToArray(createdItems, film) : createdItems,
249 // Add a created film to `items` so that the film can be deselected.
250 items: isNewlyCreatedItem ? addFilmToArray(items, film) : items,
251 };
252}
253export function maybeDeleteCreatedFilmFromArrays(items, createdItems, film) {
254 const wasItemCreatedByUser = arrayContainsFilm(createdItems, film);
255 // Delete the item if the user manually created it.
256 return {
257 createdItems: wasItemCreatedByUser ? deleteFilmFromArray(createdItems, film) : createdItems,
258 items: wasItemCreatedByUser ? deleteFilmFromArray(items, film) : items,
259 };
260}
261//# sourceMappingURL=films.js.map
\No newline at end of file