Skip to content

Commit

Permalink
:dab:
Browse files Browse the repository at this point in the history
It's working, but will be subject to style changes and potentially more settings to further customize your experience!
  • Loading branch information
TheCyberRonin committed Apr 25, 2019
1 parent 7e2b352 commit 4fe604a
Show file tree
Hide file tree
Showing 7 changed files with 303 additions and 0 deletions.
8 changes: 8 additions & 0 deletions KitsuAPI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const { http } = require('powercord/webpack');

module.exports = {
searchAnime (title) {
const url = `https://kitsu.io/api/edge/anime?filter[text]=${encodeURIComponent(title)}&page[limit]=5`;
return http.get(url).then(r => JSON.parse(r.text));
}
};
14 changes: 14 additions & 0 deletions Settings.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const { React } = require('powercord/webpack');
const { SwitchItem } = require('powercord/components/settings');

module.exports = ({ getSetting, toggleSetting }) => (
<div>
<SwitchItem
note='Filters out NSFW Anime in the search.'
value={getSetting('nsfwFilter', true)}
onChange={() => toggleSetting('nsfwFilter')}
>
Filter NSFW
</SwitchItem>
</div>
);
7 changes: 7 additions & 0 deletions commands/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require('fs')
.readdirSync(__dirname)
.filter(file => file !== 'index.js')
.forEach(filename => {
const moduleName = filename.split('.')[0];
exports[moduleName] = require(`${__dirname}/${filename}`);
});
117 changes: 117 additions & 0 deletions components/AnimeModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const { React } = require('powercord/webpack');
const { Button, Icon } = require('powercord/components');
const { Modal } = require('powercord/components/modal');
const { TextInput } = require('powercord/components/settings');
const KitsuAPI = require('../KitsuAPI');

class AnimeResult extends React.Component {
constructor () {
super();
this.state = { small: true };
}

handleClick () {
const { small } = this.state;
this.setState({ small: !small });
}

render () {
const { small } = this.state;
const { item } = this.props;
let height, cutoff, imgHeight, title, airingStatus;
const vid = item.youtubeVideoId ? <iframe height="450" src={`https://www.youtube.com/embed/${item.youtubeVideoId}`}></iframe> : '';
if (small) {
height = '100px';
cutoff = 350;
imgHeight = '100px';
title = item.titles.en;
airingStatus = '';
} else {
height = vid === '' ? '250px' : '700px';
cutoff = 1000;
imgHeight = '250px';
title = `${item.titles.en || ''} ${item.titles.ja_jp || ''}${item.titles.en_jp ? ' (' + item.titles.en_jp + ')' : ''}`;
airingStatus = <span className="anime-modal-result-airing">{item.status === 'current' ? 'Currently Airing' : 'Finished Airing'}</span>;
}
const synopsis = item.synopsis.length > cutoff ? `${item.synopsis.slice(0, cutoff - 6)}[...]` : item.synopsis;
const img = item.posterImage.medium ? <img height={imgHeight} className='anime-modal-result-image' src={item.posterImage.medium} /> : '';
return (
<div
className='anime-modal-result'
onClick={() => this.handleClick() }
style={{ height }}
>
<div style={{ display: 'flex' }}>
{img}
<div className='anime-modal-result-details'>
<span className='anime-modal-result-title'>{title}</span>
<span className='anime-modal-result-synopsis'>{synopsis}</span>
<div className='anime-modal-result-tags'>
<span className='anime-modal-result-tag'>{item.showType}</span>
<span className='anime-modal-result-tv-rating'><Icon className="anime-modal-result-rating-icon" name="Movie" />{item.ageRating || 'NR'}</span>
<span className='anime-modal-result-rating'><Icon className="anime-modal-result-rating-icon" name="People" />{item.averageRating}%</span>
{airingStatus}
</div>
</div>
</div>
{!small ? vid : ''}
</div>
);
}
}

module.exports = class AnimeModal extends React.Component {
constructor (props) {
super(props);
this.state = { entries: [],
textValue: ''
};
}

setText (t) {
this.setState({ textValue: t });
}

handleSearch () {
KitsuAPI.searchAnime(this.state.textValue).then((resp) => {
this.setState({ entries: resp.data });
});
}

render () {
const { entries } = this.state;
const animeResultList = [];
entries.forEach(animeResult => {
if (this.props.getSetting('nsfwFilter', true) && !animeResult.attributes.nsfw) {
animeResultList.push(<AnimeResult className="anime-result" item={animeResult.attributes}/>);
}
});
return (
<Modal size={Modal.Sizes.LARGE}>
<Modal.Header>
<span className='anime-modal-header'>
Anime Search
</span>
</Modal.Header>
<Modal.Content>
<div className='anime-modal-search'>
<TextInput
onChange={t => this.setText(t)}
>
Title
</TextInput>
<Button
onClick={() => this.handleSearch()}
>
Search
</Button>
</div>

<div className='anime-modal-results'>
{animeResultList}
</div>
</Modal.Content>
</Modal>
);
}
};
47 changes: 47 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const { Tooltip } = require('powercord/components');
const { Plugin } = require('powercord/entities');
const { open: openModal } = require('powercord/modal');
const { inject, uninject } = require('powercord/injector');
const { React, getModuleByDisplayName } = require('powercord/webpack');

const { resolve } = require('path');

const commands = require('./commands');
const AnimeModal = require('./components/AnimeModal');
const Settings = require('./Settings');

module.exports = class Anime extends Plugin {
async startPlugin () {
this.loadCSS(resolve(__dirname, 'style.scss'));
this._injectModal();
this.registerSettings('anime', 'Anime Search', (props) =>
React.createElement(Settings, {
...props
})
);

Object.values(commands).forEach(command =>
this.registerCommand(command.command, command.aliases || [], command.description, command.usage, command.func)
);
}

pluginWillUnload () {
uninject('anime-headerbar');
}

async _injectModal () {
const HeaderBarContainer = await getModuleByDisplayName('HeaderBarContainer');
inject('anime-headerbar', HeaderBarContainer.prototype, 'renderToolbar', (args, res) => {
res.props.children.push(
React.createElement(Tooltip, {
text: 'Anime lookup',
position: 'bottom'
}, React.createElement('div', {
className: 'anime-header-icon-s',
onClick: () => openModal(() => React.createElement(this.settings.connectStore(AnimeModal)))
}))
);
return res;
});
}
};
7 changes: 7 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "Anime",
"version": "1.0.0",
"description": "Anime lookup inside of Powercord",
"author": "CyberRonin",
"license": "MIT"
}
103 changes: 103 additions & 0 deletions style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
.anime-header-icon {
&-s, &-a {
cursor: pointer;
height: 24px;
margin: 0 8px;
width: 24px;
opacity: .6;

&:hover {
opacity: .8;
}
}

&-a {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 255 255'%3E%3Cpath fill='%23E75E45' d='M179.6,64.3c-6.8-2.5-14.1-4.1-21.8-4.4c-12.7-0.6-24.8,2.2-35.4,7.6c-0.6,0.3-1.3,0.6-2,1v36.4 c0,0.5,0,2.4-0.3,4c-0.7,3.7-2.9,7-6,9.1c-2.6,1.8-5.6,2.6-8.8,2.5c-0.6,0-1.3-0.1-1.9-0.2c-1.6-0.3-3.3-0.9-3.8-1.1 c-1.4-0.5-21.8-8.4-31.6-12.2c-1.2-0.5-2.2-0.9-3-1.2c-11.7,9.9-24,21.7-35.5,35.6c-0.1,0.1-0.6,0.7-0.7,0.8 c-1.5,2.1-1.6,5.1,0,7.4c1.2,1.7,3.1,2.7,5,2.8c1.3,0.1,2.7-0.3,3.9-1.1c0.1-0.1,0.2-0.2,0.4-0.3c12.2-8.8,25.6-15.9,39.8-21.6 c1-0.5,2.2-0.8,3.3-0.7c1.6,0.1,3.1,0.7,4.3,1.9c2.3,2.3,2.4,6,0.5,8.5c-0.8,1.2-1.5,2.4-2.2,3.6c-7.6,12.4-13.7,25.9-18.3,40 c-0.1,0.4-0.2,0.7-0.3,1.1v0.1c-0.4,1.7-0.1,3.5,1,5c1.2,1.7,3.1,2.7,5.1,2.8c1.4,0.1,2.7-0.3,3.9-1.1c0.5-0.4,1-0.8,1.4-1.3 c0.1-0.2,0.3-0.4,0.4-0.6c5-7.1,10.5-13.8,16.4-20c26.3-28.2,61.2-48.1,100.3-55.9c0.3-0.1,0.6-0.1,0.9-0.1c2.2,0.1,3.9,2,3.8,4.2 c-0.1,1.9-1.4,3.3-3.2,3.7c-36.3,7.7-101.7,50.8-78.8,113.4c0.4,1,0.7,1.6,1.2,2.5c1.2,1.7,3.1,2.7,5,2.8c1.1,0,4.2-0.3,6.1-3.7 c3.7-7,10.7-14.8,30.9-23.2c56.3-23.3,65.6-56.6,66.6-77.7v-1.2C227.1,102.1,207.6,74.7,179.6,64.3L179.6,64.3z M123.1,229.3 c-5.2-15.5-4.7-30.5,1.4-44.8c11.7,18.9,32.1,20.5,32.1,20.5C135.7,213.6,127.5,222.3,123.1,229.3z'%2F%3E%3Cpath fill='%23E75E45' d='M28,66.4c0.1,0.2,0.3,0.4,0.4,0.5c5.3,7.2,11.3,13.5,17.8,19.1c0.1,0.1,0.2,0.1,0.2,0.2 c4.2,3.6,12.2,8.8,18,10.9c0,0,36.1,13.9,38,14.7c0.7,0.3,1.7,0.6,2.2,0.7c1.6,0.3,3.3,0,4.8-1s2.4-2.5,2.7-4.1 c0.1-0.6,0.2-1.6,0.2-2.3V64.3c0.1-6.2-1.9-15.6-3.7-20.8c0-0.1-0.1-0.2-0.1-0.3c-2.8-8.1-6.6-16-11.4-23.5l-0.3-0.6L96.7,19 c-2-2.8-6-3.5-8.9-1.5c-0.5,0.3-0.8,0.7-1.2,1.1c-0.3,0.4-0.5,0.7-0.8,1.1c-6.4,9.3-9,20.6-7.3,31.7c-3.3,1.7-6.8,4-7.2,4.3 s-3.9,2.7-6.6,5.2c-9.7-5.5-21.3-7.2-32.2-4.6c-0.4,0.1-0.9,0.2-1.3,0.3c-0.5,0.2-1,0.4-1.4,0.7c-2.9,2-3.7,5.9-1.8,8.9 C28,66.2,28,66.4,28,66.4z M91.5,26.3c3.4,5.7,6.3,11.6,8.6,17.8c-4.6,0.8-9.1,2-13.5,3.6C86,40.2,87.7,32.8,91.5,26.3z M58.4,67.1c-3.2,3.5-5.9,7.3-8.3,11.3c-4.9-4.3-9.4-9.2-13.5-14.4C44.1,62.7,51.6,63.8,58.4,67.1z'%2F%3E%3C%2Fsvg%3E"); }

&-s {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 255 255'%3E%3Cpath fill='%23E75E45' d='M179.6,64.3c-6.8-2.5-14.1-4.1-21.8-4.4c-12.7-0.6-24.8,2.2-35.4,7.6c-0.6,0.3-1.3,0.6-2,1v36.4 c0,0.5,0,2.4-0.3,4c-0.7,3.7-2.9,7-6,9.1c-2.6,1.8-5.6,2.6-8.8,2.5c-0.6,0-1.3-0.1-1.9-0.2c-1.6-0.3-3.3-0.9-3.8-1.1 c-1.4-0.5-21.8-8.4-31.6-12.2c-1.2-0.5-2.2-0.9-3-1.2c-11.7,9.9-24,21.7-35.5,35.6c-0.1,0.1-0.6,0.7-0.7,0.8 c-1.5,2.1-1.6,5.1,0,7.4c1.2,1.7,3.1,2.7,5,2.8c1.3,0.1,2.7-0.3,3.9-1.1c0.1-0.1,0.2-0.2,0.4-0.3c12.2-8.8,25.6-15.9,39.8-21.6 c1-0.5,2.2-0.8,3.3-0.7c1.6,0.1,3.1,0.7,4.3,1.9c2.3,2.3,2.4,6,0.5,8.5c-0.8,1.2-1.5,2.4-2.2,3.6c-7.6,12.4-13.7,25.9-18.3,40 c-0.1,0.4-0.2,0.7-0.3,1.1v0.1c-0.4,1.7-0.1,3.5,1,5c1.2,1.7,3.1,2.7,5.1,2.8c1.4,0.1,2.7-0.3,3.9-1.1c0.5-0.4,1-0.8,1.4-1.3 c0.1-0.2,0.3-0.4,0.4-0.6c5-7.1,10.5-13.8,16.4-20c26.3-28.2,61.2-48.1,100.3-55.9c0.3-0.1,0.6-0.1,0.9-0.1c2.2,0.1,3.9,2,3.8,4.2 c-0.1,1.9-1.4,3.3-3.2,3.7c-36.3,7.7-101.7,50.8-78.8,113.4c0.4,1,0.7,1.6,1.2,2.5c1.2,1.7,3.1,2.7,5,2.8c1.1,0,4.2-0.3,6.1-3.7 c3.7-7,10.7-14.8,30.9-23.2c56.3-23.3,65.6-56.6,66.6-77.7v-1.2C227.1,102.1,207.6,74.7,179.6,64.3L179.6,64.3z M123.1,229.3 c-5.2-15.5-4.7-30.5,1.4-44.8c11.7,18.9,32.1,20.5,32.1,20.5C135.7,213.6,127.5,222.3,123.1,229.3z'%2F%3E%3Cpath fill='%23E75E45' d='M28,66.4c0.1,0.2,0.3,0.4,0.4,0.5c5.3,7.2,11.3,13.5,17.8,19.1c0.1,0.1,0.2,0.1,0.2,0.2 c4.2,3.6,12.2,8.8,18,10.9c0,0,36.1,13.9,38,14.7c0.7,0.3,1.7,0.6,2.2,0.7c1.6,0.3,3.3,0,4.8-1s2.4-2.5,2.7-4.1 c0.1-0.6,0.2-1.6,0.2-2.3V64.3c0.1-6.2-1.9-15.6-3.7-20.8c0-0.1-0.1-0.2-0.1-0.3c-2.8-8.1-6.6-16-11.4-23.5l-0.3-0.6L96.7,19 c-2-2.8-6-3.5-8.9-1.5c-0.5,0.3-0.8,0.7-1.2,1.1c-0.3,0.4-0.5,0.7-0.8,1.1c-6.4,9.3-9,20.6-7.3,31.7c-3.3,1.7-6.8,4-7.2,4.3 s-3.9,2.7-6.6,5.2c-9.7-5.5-21.3-7.2-32.2-4.6c-0.4,0.1-0.9,0.2-1.3,0.3c-0.5,0.2-1,0.4-1.4,0.7c-2.9,2-3.7,5.9-1.8,8.9 C28,66.2,28,66.4,28,66.4z M91.5,26.3c3.4,5.7,6.3,11.6,8.6,17.8c-4.6,0.8-9.1,2-13.5,3.6C86,40.2,87.7,32.8,91.5,26.3z M58.4,67.1c-3.2,3.5-5.9,7.3-8.3,11.3c-4.9-4.3-9.4-9.2-13.5-14.4C44.1,62.7,51.6,63.8,58.4,67.1z'%2F%3E%3C%2Fsvg%3E"); }
}

.anime-modal {
&-search {
margin-top: 20px;
display: flex;
align-items: center;
position: sticky;
top: 20px;
background-color: rgba(54, 57, 63, .9);
> div {
flex: 1;

+ button {
margin-left: 15px;
}
}

.pc-input {
height: 32px;
}

.pc-divider {
display: none;
}
}
&-header {
color: white;
font-weight: bold;
text-transform: uppercase;
}
&-results {
display: flex;
flex-direction: column;
}
&-result {
display: flex;
flex-direction: column;
padding: 4px;
border: 1px solid #2f3136;
border-radius: 4px;
margin-top: 5px;
margin-bottom: 5px;
color: white;

&-image {
border-radius: 4px;
}
&-details {
margin-left: 5px;
display: flex;
flex-direction: column;
}
&-tags {
display: flex;
justify-content: space-evenly;
align-items: center;
height: 100%;
}
&-title {
margin-bottom: 5px;
font-size: 1.1em;
}
&-tag {
padding: 4px;
background-color: #7289DA;
border-radius: 4px;
}
&-rating, &-tv-rating {
display: flex;
align-items: center;

&-icon {
height: 20px;
width: 20px;
margin-right: 5px;
}
}
}
&-result:hover {
background-color: #2f3136;
cursor: pointer;
}
}

0 comments on commit 4fe604a

Please sign in to comment.