mirror of
https://github.com/pds-nest/nest.git
synced 2025-02-16 12:43:58 +00:00
💥 Refactor even more...
This commit is contained in:
parent
c9cf2a1142
commit
919cbefd0f
12 changed files with 244 additions and 239 deletions
|
@ -2,7 +2,7 @@ import React from "react"
|
||||||
import BoxFull from "../base/BoxFull"
|
import BoxFull from "../base/BoxFull"
|
||||||
import useRepositoryViewer from "../../hooks/useRepositoryViewer"
|
import useRepositoryViewer from "../../hooks/useRepositoryViewer"
|
||||||
import useStrings from "../../hooks/useStrings"
|
import useStrings from "../../hooks/useStrings"
|
||||||
import { ContainsFilter } from "../../utils/Filter"
|
import { FilterContains } from "../../utils/Filter"
|
||||||
import FormInlineText from "./FormInlineText"
|
import FormInlineText from "./FormInlineText"
|
||||||
import { faFont } from "@fortawesome/free-solid-svg-icons"
|
import { faFont } from "@fortawesome/free-solid-svg-icons"
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||||
|
@ -13,7 +13,7 @@ export default function BoxFilterContains({ ...props }) {
|
||||||
const { appendFilter } = useRepositoryViewer()
|
const { appendFilter } = useRepositoryViewer()
|
||||||
|
|
||||||
const submit = value => {
|
const submit = value => {
|
||||||
appendFilter(new ContainsFilter(false, value))
|
appendFilter(new FilterContains(false, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add this string
|
// TODO: add this string
|
||||||
|
|
|
@ -3,7 +3,7 @@ import BoxFull from "../base/BoxFull"
|
||||||
import { faClock, faHashtag } from "@fortawesome/free-solid-svg-icons"
|
import { faClock, faHashtag } from "@fortawesome/free-solid-svg-icons"
|
||||||
import useRepositoryViewer from "../../hooks/useRepositoryViewer"
|
import useRepositoryViewer from "../../hooks/useRepositoryViewer"
|
||||||
import useStrings from "../../hooks/useStrings"
|
import useStrings from "../../hooks/useStrings"
|
||||||
import { AfterDatetimeFilter } from "../../utils/Filter"
|
import { FilterInsideTimeRay } from "../../utils/Filter"
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||||
import FormInlineBADatetime from "./FormInlineBADatetime"
|
import FormInlineBADatetime from "./FormInlineBADatetime"
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ export default function BoxFilterDatetime({ ...props }) {
|
||||||
const { appendFilter } = useRepositoryViewer()
|
const { appendFilter } = useRepositoryViewer()
|
||||||
|
|
||||||
const submit = ({ date, isBefore }) => {
|
const submit = ({ date, isBefore }) => {
|
||||||
appendFilter(new AfterDatetimeFilter(isBefore, date))
|
appendFilter(new FilterInsideTimeRay(isBefore, date))
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -5,7 +5,7 @@ import useRepositoryViewer from "../../hooks/useRepositoryViewer"
|
||||||
import useStrings from "../../hooks/useStrings"
|
import useStrings from "../../hooks/useStrings"
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||||
import { faLocationArrow, faPlus } from "@fortawesome/free-solid-svg-icons"
|
import { faLocationArrow, faPlus } from "@fortawesome/free-solid-svg-icons"
|
||||||
import { HasPlaceFilter } from "../../utils/Filter"
|
import { FilterWithPlace } from "../../utils/Filter"
|
||||||
import ButtonIconOnly from "../base/ButtonIconOnly"
|
import ButtonIconOnly from "../base/ButtonIconOnly"
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ export default function BoxFilterHasPlace({ ...props }) {
|
||||||
const { appendFilter } = useRepositoryViewer()
|
const { appendFilter } = useRepositoryViewer()
|
||||||
|
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
appendFilter(new HasPlaceFilter(false))
|
appendFilter(new FilterWithPlace(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: translate this
|
// TODO: translate this
|
||||||
|
|
|
@ -3,7 +3,7 @@ import BoxFull from "../base/BoxFull"
|
||||||
import { faClock } from "@fortawesome/free-solid-svg-icons"
|
import { faClock } from "@fortawesome/free-solid-svg-icons"
|
||||||
import useRepositoryViewer from "../../hooks/useRepositoryViewer"
|
import useRepositoryViewer from "../../hooks/useRepositoryViewer"
|
||||||
import useStrings from "../../hooks/useStrings"
|
import useStrings from "../../hooks/useStrings"
|
||||||
import { HashtagFilter } from "../../utils/Filter"
|
import { FilterHashtag } from "../../utils/Filter"
|
||||||
import FormInlineHashtag from "./FormInlineHashtag"
|
import FormInlineHashtag from "./FormInlineHashtag"
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ export default function BoxFilterHashtag({ ...props }) {
|
||||||
const { appendFilter } = useRepositoryViewer()
|
const { appendFilter } = useRepositoryViewer()
|
||||||
|
|
||||||
const submit = value => {
|
const submit = value => {
|
||||||
appendFilter(new HashtagFilter(false, value))
|
appendFilter(new FilterHashtag(false, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -6,7 +6,7 @@ import useStrings from "../../hooks/useStrings"
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||||
import { faMapPin } from "@fortawesome/free-solid-svg-icons"
|
import { faMapPin } from "@fortawesome/free-solid-svg-icons"
|
||||||
import FormInlineLocation from "./FormInlineLocation"
|
import FormInlineLocation from "./FormInlineLocation"
|
||||||
import { LocationRadiusFilter } from "../../utils/Filter"
|
import { FilterInsideMapArea } from "../../utils/Filter"
|
||||||
|
|
||||||
|
|
||||||
export default function BoxFilterLocation({ ...props }) {
|
export default function BoxFilterLocation({ ...props }) {
|
||||||
|
@ -15,7 +15,7 @@ export default function BoxFilterLocation({ ...props }) {
|
||||||
const { appendFilter, mapViewHook } = useRepositoryViewer()
|
const { appendFilter, mapViewHook } = useRepositoryViewer()
|
||||||
|
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
appendFilter(new LocationRadiusFilter(false, mapViewHook.center, mapViewHook.radius))
|
appendFilter(new FilterInsideMapArea(false, mapViewHook.center, mapViewHook.radius))
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -3,7 +3,7 @@ import BoxFull from "../base/BoxFull"
|
||||||
import { faAt } from "@fortawesome/free-solid-svg-icons"
|
import { faAt } from "@fortawesome/free-solid-svg-icons"
|
||||||
import useRepositoryViewer from "../../hooks/useRepositoryViewer"
|
import useRepositoryViewer from "../../hooks/useRepositoryViewer"
|
||||||
import useStrings from "../../hooks/useStrings"
|
import useStrings from "../../hooks/useStrings"
|
||||||
import { UserFilter } from "../../utils/Filter"
|
import { FilterPoster } from "../../utils/Filter"
|
||||||
import FormInlineUser from "./FormInlineUser"
|
import FormInlineUser from "./FormInlineUser"
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ export default function BoxFilterUser({ ...props }) {
|
||||||
const { appendFilter } = useRepositoryViewer()
|
const { appendFilter } = useRepositoryViewer()
|
||||||
|
|
||||||
const submit = value => {
|
const submit = value => {
|
||||||
appendFilter(new UserFilter(false, value))
|
appendFilter(new FilterPoster(false, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -4,7 +4,7 @@ import ContextLanguage from "../../contexts/ContextLanguage"
|
||||||
import BoxFull from "../base/BoxFull"
|
import BoxFull from "../base/BoxFull"
|
||||||
import Empty from "./Empty"
|
import Empty from "./Empty"
|
||||||
import ContextRepositoryViewer from "../../contexts/ContextRepositoryViewer"
|
import ContextRepositoryViewer from "../../contexts/ContextRepositoryViewer"
|
||||||
import { ContainsFilter } from "../../utils/Filter"
|
import { FilterContains } from "../../utils/Filter"
|
||||||
|
|
||||||
|
|
||||||
export default function BoxVisualizationWordcloud({ ...props }) {
|
export default function BoxVisualizationWordcloud({ ...props }) {
|
||||||
|
@ -20,7 +20,7 @@ export default function BoxVisualizationWordcloud({ ...props }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const onWordClick = word => {
|
const onWordClick = word => {
|
||||||
appendFilter(new ContainsFilter(false, word.text))
|
appendFilter(new FilterContains(false, word.text))
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
222
nest_frontend/objects/Filter.js
Normal file
222
nest_frontend/objects/Filter.js
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
import {
|
||||||
|
faAt,
|
||||||
|
faClock,
|
||||||
|
faFilter,
|
||||||
|
faFont,
|
||||||
|
faHashtag,
|
||||||
|
faLocationArrow,
|
||||||
|
faMapMarkerAlt,
|
||||||
|
faMapPin,
|
||||||
|
} from "@fortawesome/free-solid-svg-icons"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A filter applicable in the Analysis mode.
|
||||||
|
*/
|
||||||
|
export class Filter {
|
||||||
|
negate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param negate - If the filter output should be reversed.
|
||||||
|
*/
|
||||||
|
constructor(negate = false) {
|
||||||
|
this.negate = negate
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a tweet passed through the filter or not, without applying `negate`.
|
||||||
|
*
|
||||||
|
* @param tweet - The tweet to check.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
check(tweet) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a tweet passed through the filter or not, applying `negate`.
|
||||||
|
*
|
||||||
|
* @param tweet - The tweet to check.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
exec(tweet) {
|
||||||
|
return Boolean(this.check(tweet) ^ this.negate)
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
return {
|
||||||
|
color: "Grey",
|
||||||
|
icon: faFilter,
|
||||||
|
children: this.negate ? "False" : "True"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a tweet contains a string.
|
||||||
|
*/
|
||||||
|
export class FilterContains extends Filter {
|
||||||
|
string
|
||||||
|
|
||||||
|
constructor(word, negate = false) {
|
||||||
|
super(negate)
|
||||||
|
this.string = word.toLowerCase().trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
check(tweet) {
|
||||||
|
return tweet.content?.toLowerCase().includes(this.string)
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
return {
|
||||||
|
color: "Grey",
|
||||||
|
icon: faFont,
|
||||||
|
children: this.string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a tweet contains an hashtag.
|
||||||
|
*/
|
||||||
|
export class FilterHashtag extends FilterContains {
|
||||||
|
hashtag
|
||||||
|
|
||||||
|
constructor(hashtag, negate = false) {
|
||||||
|
super(negate, `#${hashtag}`)
|
||||||
|
this.hashtag = hashtag
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
return {
|
||||||
|
color: "Grey",
|
||||||
|
icon: faHashtag,
|
||||||
|
children: this.hashtag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a tweet was posted by a certain user.
|
||||||
|
*/
|
||||||
|
export class FilterPoster extends Filter {
|
||||||
|
poster
|
||||||
|
|
||||||
|
constructor(poster, negate = false) {
|
||||||
|
super(negate)
|
||||||
|
this.poster = poster
|
||||||
|
}
|
||||||
|
|
||||||
|
check(tweet) {
|
||||||
|
return tweet.poster.toLowerCase() === this.poster.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
return {
|
||||||
|
color: "Green",
|
||||||
|
icon: faAt,
|
||||||
|
children: this.poster
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a tweet contains `location` metadata.
|
||||||
|
*/
|
||||||
|
export class FilterWithLocation extends Filter {
|
||||||
|
constructor(negate = false) {
|
||||||
|
super(negate)
|
||||||
|
}
|
||||||
|
|
||||||
|
check(tweet) {
|
||||||
|
return Boolean(tweet["location"])
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
return {
|
||||||
|
color: "Red",
|
||||||
|
icon: faLocationArrow,
|
||||||
|
children: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a tweet contains `place` metadata.
|
||||||
|
*/
|
||||||
|
export class FilterWithPlace extends Filter {
|
||||||
|
constructor(negate = false) {
|
||||||
|
super(negate)
|
||||||
|
}
|
||||||
|
|
||||||
|
check(tweet) {
|
||||||
|
return Boolean(tweet["place"])
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
return {
|
||||||
|
color: "Red",
|
||||||
|
icon: faMapMarkerAlt,
|
||||||
|
children: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a tweet's `location` is inside a {@link MapArea}.
|
||||||
|
*/
|
||||||
|
export class FilterInsideMapArea extends FilterWithLocation {
|
||||||
|
mapArea
|
||||||
|
|
||||||
|
constructor(mapArea, negate = false) {
|
||||||
|
super(negate)
|
||||||
|
this.mapArea = mapArea
|
||||||
|
}
|
||||||
|
|
||||||
|
check(tweet) {
|
||||||
|
if(!super.check(tweet)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.mapArea.includes(tweet.location)
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
return {
|
||||||
|
color: "Red",
|
||||||
|
icon: faLocationArrow,
|
||||||
|
children: this.mapArea.toHumanString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a tweet's `post_time` is inside a {@link TimeRay}.
|
||||||
|
*/
|
||||||
|
export class FilterInsideTimeRay extends Filter {
|
||||||
|
timeRay
|
||||||
|
|
||||||
|
constructor(timeRay, negate = false) {
|
||||||
|
super(negate)
|
||||||
|
this.timeRay = timeRay
|
||||||
|
}
|
||||||
|
|
||||||
|
check(tweet) {
|
||||||
|
return this.datetime < new Date(tweet["insert_time"])
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
return {
|
||||||
|
color: "Yellow",
|
||||||
|
icon: faClock,
|
||||||
|
children: this.timeRay.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,7 +36,7 @@ export default class MapArea {
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
toString() {
|
toString() {
|
||||||
return `${this.radius} ${this.center.toString()}`
|
return `< ${this.radius} ${this.center.toString()}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,9 +47,9 @@ export default class MapArea {
|
||||||
toHumanString() {
|
toHumanString() {
|
||||||
if(this.radius >= 2000) {
|
if(this.radius >= 2000) {
|
||||||
const kmRadius = Math.round(this.radius / 1000)
|
const kmRadius = Math.round(this.radius / 1000)
|
||||||
return `${kmRadius}km ${this.center.toHumanString()}`
|
return `< ${kmRadius}km ${this.center.toHumanString()}`
|
||||||
}
|
}
|
||||||
return `${this.radius}m ${this.center.toHumanString()}`
|
return `< ${this.radius}m ${this.center.toHumanString()}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,5 +9,5 @@ test("MapArea can be constructed", () => {
|
||||||
|
|
||||||
test("MapArea can be rendered to a spec-compatible string", () => {
|
test("MapArea can be rendered to a spec-compatible string", () => {
|
||||||
const mapArea = new MapArea(1000, new Coordinates(0.0, 0.0))
|
const mapArea = new MapArea(1000, new Coordinates(0.0, 0.0))
|
||||||
expect(mapArea.toString()).toBe("1000 0.0000000 0.0000000")
|
expect(mapArea.toString()).toBe("< 1000 0.0000000 0.0000000")
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,4 +21,8 @@ export default class TimeRay {
|
||||||
toString() {
|
toString() {
|
||||||
return `${this.isBefore ? "<" : ">"} ${this.date.toISOString()}`
|
return `${this.isBefore ? "<" : ">"} ${this.date.toISOString()}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
includes(date) {
|
||||||
|
return Boolean((this.date > date) ^ this.isBefore)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,221 +0,0 @@
|
||||||
import { Location } from "./location"
|
|
||||||
import {
|
|
||||||
faAt,
|
|
||||||
faClock,
|
|
||||||
faFilter,
|
|
||||||
faFont,
|
|
||||||
faHashtag,
|
|
||||||
faLocationArrow,
|
|
||||||
faMapMarkerAlt,
|
|
||||||
faMapPin,
|
|
||||||
} from "@fortawesome/free-solid-svg-icons"
|
|
||||||
|
|
||||||
|
|
||||||
export class Filter {
|
|
||||||
negate
|
|
||||||
|
|
||||||
constructor(negate) {
|
|
||||||
this.negate = negate
|
|
||||||
}
|
|
||||||
|
|
||||||
check(tweet) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
exec(tweet) {
|
|
||||||
return this.check(tweet) ^ this.negate
|
|
||||||
}
|
|
||||||
|
|
||||||
color() {
|
|
||||||
return "Grey"
|
|
||||||
}
|
|
||||||
|
|
||||||
icon() {
|
|
||||||
return faFilter
|
|
||||||
}
|
|
||||||
|
|
||||||
text() {
|
|
||||||
return this.negate ? "False" : "True"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class ContainsFilter extends Filter {
|
|
||||||
word
|
|
||||||
|
|
||||||
constructor(negate, word) {
|
|
||||||
super(negate)
|
|
||||||
this.word = word.toLowerCase().trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
check(tweet) {
|
|
||||||
return tweet.content?.toLowerCase().includes(this.word)
|
|
||||||
}
|
|
||||||
|
|
||||||
color() {
|
|
||||||
return "Grey"
|
|
||||||
}
|
|
||||||
|
|
||||||
icon() {
|
|
||||||
return faFont
|
|
||||||
}
|
|
||||||
|
|
||||||
text() {
|
|
||||||
return this.word
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class HashtagFilter extends ContainsFilter {
|
|
||||||
hashtag
|
|
||||||
|
|
||||||
constructor(negate, hashtag) {
|
|
||||||
super(negate, `#${hashtag}`)
|
|
||||||
this.hashtag = hashtag
|
|
||||||
}
|
|
||||||
|
|
||||||
icon() {
|
|
||||||
return faHashtag
|
|
||||||
}
|
|
||||||
|
|
||||||
text() {
|
|
||||||
return this.hashtag
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class UserFilter extends Filter {
|
|
||||||
user
|
|
||||||
|
|
||||||
constructor(negate, user) {
|
|
||||||
super(negate)
|
|
||||||
this.user = user.toLowerCase().trim().replace(/^@/, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
check(tweet) {
|
|
||||||
return tweet.poster.toLowerCase() === this.user
|
|
||||||
}
|
|
||||||
|
|
||||||
color() {
|
|
||||||
return "Green"
|
|
||||||
}
|
|
||||||
|
|
||||||
icon() {
|
|
||||||
return faAt
|
|
||||||
}
|
|
||||||
|
|
||||||
text() {
|
|
||||||
return this.user
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class HasLocationFilter extends Filter {
|
|
||||||
constructor(negate) {
|
|
||||||
super(negate)
|
|
||||||
}
|
|
||||||
|
|
||||||
check(tweet) {
|
|
||||||
return Boolean(tweet["location"])
|
|
||||||
}
|
|
||||||
|
|
||||||
color() {
|
|
||||||
return "Red"
|
|
||||||
}
|
|
||||||
|
|
||||||
icon() {
|
|
||||||
return faMapMarkerAlt
|
|
||||||
}
|
|
||||||
|
|
||||||
text() {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class HasPlaceFilter extends Filter {
|
|
||||||
constructor(negate) {
|
|
||||||
super(negate)
|
|
||||||
}
|
|
||||||
|
|
||||||
check(tweet) {
|
|
||||||
return Boolean(tweet["place"])
|
|
||||||
}
|
|
||||||
|
|
||||||
color() {
|
|
||||||
return "Red"
|
|
||||||
}
|
|
||||||
|
|
||||||
icon() {
|
|
||||||
return faLocationArrow
|
|
||||||
}
|
|
||||||
|
|
||||||
text() {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class LocationRadiusFilter extends HasLocationFilter {
|
|
||||||
center
|
|
||||||
radius
|
|
||||||
|
|
||||||
constructor(negate, center, radius) {
|
|
||||||
super(negate)
|
|
||||||
this.center = center
|
|
||||||
this.radius = radius
|
|
||||||
}
|
|
||||||
|
|
||||||
check(tweet) {
|
|
||||||
if(!super.check(tweet)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Maths is hard
|
|
||||||
const location = Location.fromTweet(tweet)
|
|
||||||
const latDiff = Math.abs(location.lat - this.center.lat)
|
|
||||||
const lngDiff = Math.abs(location.lng - this.center.lng)
|
|
||||||
const squaredDistance = Math.pow(latDiff, 2) + Math.pow(lngDiff, 2)
|
|
||||||
const squaredRadius = Math.pow(this.radius, 2)
|
|
||||||
|
|
||||||
return squaredDistance < squaredRadius
|
|
||||||
}
|
|
||||||
|
|
||||||
color() {
|
|
||||||
return "Red"
|
|
||||||
}
|
|
||||||
|
|
||||||
icon() {
|
|
||||||
return faMapPin
|
|
||||||
}
|
|
||||||
|
|
||||||
text() {
|
|
||||||
return `< ${this.radius}m ${this.center.lat.toFixed(3)} ${this.center.lng.toFixed(3)}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class AfterDatetimeFilter extends Filter {
|
|
||||||
datetime
|
|
||||||
|
|
||||||
constructor(negate, datetime) {
|
|
||||||
super(negate)
|
|
||||||
this.datetime = datetime
|
|
||||||
}
|
|
||||||
|
|
||||||
check(tweet) {
|
|
||||||
return this.datetime < new Date(tweet["insert_time"])
|
|
||||||
}
|
|
||||||
|
|
||||||
color() {
|
|
||||||
return "Yellow"
|
|
||||||
}
|
|
||||||
|
|
||||||
icon() {
|
|
||||||
return faClock
|
|
||||||
}
|
|
||||||
|
|
||||||
text() {
|
|
||||||
return `${this.negate ? "<" : ">"} ${this.datetime.toISOString()}`
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue