Addition of new filters for event search

Open Event has an event search provided but it lacked two of the userful filters which will make searching for an event for a user easier than the current ecosystem. In this blog post, I describe how I implemented filtering of events on the basis of CFP status and Ticket Type. About the issue Addition of these two filters were subparts of improving the browse events page better. The browse events page currently functions in an optimal way but these improvements make it even better. How the filters are added For adding these two filters, it was required that the request sent to server to filter the event must contain ticket type and cfp so that the results from the server can be received. To achieve this, the frontend code needed the following changes: Passing of request variable into sidebar component present in app/templates/explore.hbs and addition of a clear filter for the same in the same file.e startDate=start_date endDate=end_date location=location ticket_type=ticket_type} {{explore/side-bar model=model category=category sub_category=sub_category event_type=event_type startDate=start_date endDate=end_date location=location ticket_type=ticket_type}}{{#if filters.ticket_type}}  <div class="ui mini label">    {{ticket_type}}    <a role="button" {{action 'clearFilter' 'ticket_type'}}>      <i class="icon close"></i>    </a>  </div>{{/if}} Adding UI for both the filters in app/templates/components/explore/side-bar.hbs. Accordion UI is used to achieve this.   <div class="item">    {{#ui-accordion}}      <span class="title">        <i class="dropdown icon"></i>        {{t 'Ticket Type' }}      </span>      <div class="content menu">        <a href="#"          class="link item {{if (eq ticket_type 'free') 'active'}}"          {{action 'selectTicketType' 'free'}}>          {{t 'Free'}}        </a>        <a href="#"          class="link item {{if (eq ticket_type 'paid') 'active'}}"          {{action 'selectTicketType' 'paid'}}>          {{t 'Paid'}}        </a>      </div>    {{/ui-accordion}}  </div> Editing the routes (app/routes/explore.js) to make sure if the request has new filter parameter then it should be sent to server. if (params.ticket_type) {      filterOptions.push({        name : 'tickets',        op   : 'any',        val  : {          name : 'type',          op   : 'eq',          val  : params.ticket_type        }      });    } Addition of new request parameter in the controller (app/controllers/explore.js) queryParams  : ['category', 'sub_category', 'event_type', 'start_date', 'end_date', 'location', 'ticket_type'],ticket_type  : null,if (filterType === 'ticket_type') {  this.set('ticket_type', null);} Editing the sidebar component to set the value of request parameter when the user interacts with the filter. hideClearFilters: computed('category', 'sub_category', 'event_type', 'startDate', 'endDate', 'location', 'ticket_type', function() {    return !(this.category || this.sub_category || this.event_type || this.startDate || this.endDate || this.location || this.ticket_type !== null);}),selectTicketType(ticketType) {  this.set('ticket_type', ticketType === this.ticket_type ? null : ticketType);},this.set('ticket_type', null); Sidebar after the addition of filters. Resources: Issue: https://github.com/fossasia/open-event-frontend/issues/3098Pull Requests: Ticket Type: https://github.com/fossasia/open-event-frontend/pull/3158CFS: https://github.com/fossasia/open-event-frontend/pull/3144 Specifying Query Params: https://guides.emberjs.com/release/routing/query-params/ UI Resources for the feature: https://semantic-org.github.io/Semantic-UI-Ember/#/modules/accordion

Continue ReadingAddition of new filters for event search

Feeds Moderation in loklak Media Wall

Loklak Media Wall provides client side filters for entities received from loklak status.json API like blocking feeds from a particular user, removing duplicate feeds, hiding a particular feed post for moderating feeds. To implement it, we need pure functions which remove the requested type of feeds and returns a new array of feeds. Moreover, the original set of data must also be stored in an array so that if filters are removed, the requested data is provided to the user In this blog, I would be explaining how I implemented client side filters to filter out a particular type of feeds and provide the user with a cleaner data as requested. Types of filters There are four client-side filters currently provided by Loklak media wall: Profanity Filter: Checks for the feeds that might be offensive and removes it. Remove Duplicate: Removes duplicate feeds and the retweets from the original feeds Hide Feed: Removes a particular feed from the feeds Block User: Blocks a User and removes all the feeds from the particular user It is also important to ensure that on pagination, new feeds are filtered out based on the previous user requested moderation. Flow Chart The flow chart explains how different entities received from the server is filtered and how original set of entities is maintained so that if the user removes the filter, the original filtered entities are recovered. Working Profanity Filter To avoid any obscene language used in the feed status to be shown up on media wall and providing a rather clean data, profanity filter can be used. For this filter, loklak search.json APIs provide a field classifier_profanity which states if there is some swear word is used in the status. We can check for the value of this field and filter out the feed accordingly. export function profanityFilter(feeds: ApiResponseResult[]): ApiResponseResult[] { const filteredFeeds: ApiResponseResult[] = []; feeds.forEach((feed) => { if ( feed.classifier_language !== null && feed.classifier_profanity !== undefined ) { if (feed.classifier_profanity !== 'sex' &&  feed.classifier_profanity !== 'swear') { filteredFeeds.push(feed); } } else { filteredFeeds.push(feed); } }); return filteredFeeds || feeds; } Here, we check if the classifier_profanity field is either not ‘swear’ or ‘sex’ which clearly classifies the feeds and we can push the status accordingly. Moreover, if no classifier_profanity field is provided for a particular field, we can push the feed in the filtered feeds. Remove Duplicate Remove duplicate filter removes the tweets that are either retweets or even copy of some feed and return just one original feed. We need to compare field id_str which is the status id of the feed and remove the duplicate feeds. For this filter, we need to create a map and compare feeds on map object and remove the duplicate feeds iteratively and return the array of feeds with unique elements. export function removeDuplicateCheck(feeds: ApiResponseResult[]): ApiResponseResult[] { const map = { }; const filteredFeeds: ApiResponseResult[] = []; const newFeeds: ApiResponseResult[] = feeds; let v: string; for (let a = 0; a < feeds.length; a++) { v…

Continue ReadingFeeds Moderation in loklak Media Wall

Implementing Tracks Filter in Open Event Webapp using the side track name list

Event Websites generated by Open Event Webapp may contain a large number of sessions presented by different speakers. The Sessions are divided into the different group based on their type of track. For example, few sessions may belong to Database Track, few may belong to Machine Learning Track and so on. It is natural that the user may want to filter the visible sessions on the basis of tracks. Before we implemented the tracks filter using the track names list, we had a sub navbar on the tracks page for jumping to the different tracks of the event on a particular day. Below are the screenshots of that feature. On Clicking the Design, Art, Community Track But, it was not an elegant solution. We already had a track names list present on the side of the page which remained unused. A better idea was to use this side track names list to filter the sessions. Other event management sites like http://sched.org follow the same idea. The relevant issue for it is here and the major work can be seen in this Pull Request. Below is the screenshot of the unused side track names list. The end behavior should be something like this, the user clicks on a track and only sessions belonging to the track should be visible and the rest be hidden. There should also be a button for clearing the applied filter and reverting the page back to its default view. Let’s jump to the implementation part. First, we make the side track name list and make the individual tracks clickable. <div class="track-names col-md-3 col-sm-3"> {{#tracknames}} <div class="track-info"> <span style="background-color: {{color}};" class="titlecolor"></span> <span class="track-name" style="cursor: pointer">{{title}} </span> </div> {{/tracknames}} </div> Now we need to write a function for handling the user click event on the track name. Before writing the function, we need to see the basic structure of the tracks page. The divs with the class date-filter contain all the sessions scheduled on a given day. Inside that div, we have another div with class tracks-filter which contains the name of the track and all the sessions of that track are inside the div with class room-filter. Below is a relevant block of code from the tracks.hbs file <div class="date-filter"> // Contains all the sessions present in a single day <div class="track-filter row"> // Contains all the sessions of a single track <div class="row"> // Contains the name of the track <h5 class="text">{{caption}}</h4> </div> <div class="room-filter" id="{{session_id}}"> // Contain the information about the session </div> </div> </div> We iterate over all the date-filter divs and check all the track-filter divs inside it. We extract the name of the track and compare it to the name of the track which the user selected. If both of them are same, then we show that track div and all the sessions inside it. If the names don’t match, then we hide that track div and all the content inside it. We also keep a variable named flag and set it to 0 initially. If the user selected track is present on a given day, we set the flag to 1. Based on it, we decide whether to display that particular day or not. If the flag is set, we display the date-filter div of that…

Continue ReadingImplementing Tracks Filter in Open Event Webapp using the side track name list