Compare commits

..

63 commits

Author SHA1 Message Date
dependabot[bot]
b59950a2d1
Bump addressable from 2.5.2 to 2.8.0 (#1537)
Bumps [addressable](https://github.com/sporkmonger/addressable) from 2.5.2 to 2.8.0.
- [Release notes](https://github.com/sporkmonger/addressable/releases)
- [Changelog](https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sporkmonger/addressable/compare/addressable-2.5.2...addressable-2.8.0)

---
updated-dependencies:
- dependency-name: addressable
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 13:01:34 +01:00
dependabot[bot]
dbed87f837
Bump karma from 2.0.5 to 6.3.16 (#1544)
Bumps [karma](https://github.com/karma-runner/karma) from 2.0.5 to 6.3.16.
- [Release notes](https://github.com/karma-runner/karma/releases)
- [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma/compare/v2.0.5...v6.3.16)

---
updated-dependencies:
- dependency-name: karma
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 13:01:12 +01:00
Dishebh Bhayana
171c422b99 Update searchsettings.component.css (#1511) 2020-01-15 17:07:00 +01:00
Dishebh Bhayana
de4400a338 Updating the info-box (#1507)
* Update infobox.component.html

* Update styles.css
2020-01-15 15:49:07 +01:00
Dishebh Bhayana
9a37baeac8 Fixed some broken url (#1504)
* Update url_configuration.ts

* Update url_configuration.ts
2020-01-15 15:45:27 +01:00
Dishebh Bhayana
5f71e1785e Fixed some broken URLs (#1500)
* Update dropdown.component.html

* Update index.component.html

* Update footer-navbar.component.html
2020-01-08 23:39:27 +01:00
subhahu
1443ae7fb9 Fixing the bug
Update index.html
Update index.html
Fixing the bug
Merge remote-tracking branch 'origin/patch-23' into patch-23
2019-05-08 03:32:21 +05:30
Sakshee Jain
9be83ea290 fix #1485: make nav-bar color similar to Google (#1489) 2019-04-05 20:40:12 +05:30
Sakshee Jain
d2998f57c0 fix #1486: fix security vulnerabilities in the project (#1487) 2019-04-05 15:36:07 +05:30
subhahu
93a5eff519 Removing unused imports (#1472) 2019-03-27 20:29:47 +05:30
Raj Vaibhav Dubey
f998f2e7a5 Dropdown component refactored (#1367)
Dropdown Component has been refactored and some minor UI fixes have been done.
Also tests have been added for the basic skeleton of the dropdown component.

Fixes #1359
2019-03-22 11:35:15 +08:00
subhahu
3f2b860e2d Adding Resource prioritization ( increasing light house performance ) (#1425)
Update index.html
Update index.html
2019-03-22 11:35:04 +08:00
Prabhu Pant
4cfb87c2e8 Fix Dockerfile and docker doc (#1427) 2019-03-22 11:34:55 +08:00
Akshita Agarwalla
6212b90d35 Made some grammatical changes
Fixed some grammatical errors, re-framed some sentences and corrected the spelling of YaCy
2019-03-13 09:40:30 +05:30
Samagra Gupta
fd57cb46c4 On help page when hover on close button cursor is pointer (#1435)
* On help page when hover on close button cursor is pointer

* changed indentation
2019-03-08 12:39:29 +05:30
subhahu
8953eebedf Adding test for increasing the coverage (#1458)
Update speechtotext.component.spec.ts
Update speechtotext.component.spec.ts
Update speechtotext.component.spec.ts
Update speechtotext.component.spec.ts
Update speechtotext.component.spec.ts
Update speechtotext.component.spec.ts
Update speechtotext.component.spec.ts
Update speechtotext.component.spec.ts
Update speechtotext.component.spec.ts
2019-03-08 12:37:52 +05:30
Divyanshu Raj Srivastava
e6a0c4072e Changed shape of search-bar to curve shape (#1462)
* Changed shape of search-bar to curve shape

* Improved the corner of search-bar
2019-02-28 21:05:49 +05:30
samagragupta
cbb9a18b9a Removed fixed navbar for mobile 2019-02-13 07:03:02 +05:30
samagragupta
d3298db70d Search bar is fixed when scrolled 2019-02-13 07:03:02 +05:30
neeraj3029
e9f66ddfc0 type changed 2019-02-13 06:57:27 +05:30
neeraj3029
5d7e77aa51 refactored 2019-02-13 06:57:03 +05:30
subhahu
763b627426 Adding a lang attribute to the html element 2019-02-13 06:56:16 +05:30
subhahu
ed4dc86c79 Update about.component.html 2019-02-13 06:55:23 +05:30
subhahu
f4a6fa3f67 Update about.component.html
Update about.component.html
Update about.component.html
Update about.component.html
Update about.component.html
Update about.component.html
Update about.component.html
Update about.component.html
Update about.component.html
Update about.component.html
2019-02-13 06:55:23 +05:30
Sangatdas
99df7d6466 Update dropdown.css
To hide overflow along x-axis in the dropdown to give UI effect similar to that of Google Search
2019-02-13 06:53:12 +05:30
humble_D
5221a578dd Fixes #1317: Reducers and Actions cleaned (#1318) 2019-01-27 14:33:49 +01:00
humble_D
2691fd63e9 Fixes #1327: Contact componnet refactored (#1328) 2019-01-27 14:33:34 +01:00
Shreyansh Dwivedi
c6de390e12 Refactors Theme Component and added tests for coverage 2019-01-22 05:04:48 +05:30
subhahu
11c1b88dad Fixing not found result page
Update results.component.ts
Update results.component.ts
Update results.component.html
Update results.component.html
2019-01-22 04:57:18 +05:30
subhahu
74ab79e0e0 Adding rel="noopener" for fixing cross-link links 2019-01-22 04:56:26 +05:30
Valentin Bercaru
bd28928203 Fix #1388 : did you mean content is now clickable 2019-01-22 04:54:51 +05:30
Shreyansh Dwivedi
c2586a5bdb Added sidebar for Privacy page and tests to increase coverage 2019-01-14 21:43:52 +05:30
Shreyansh Dwivedi
005e042120 Added sidebar menu on Terms page and tests to increase coverage 2019-01-14 21:40:44 +05:30
subhahu
655259f389 Fixing the susper logo alignment and its container
Fixing alignment for all screen sizes
Fixing width of div
Update index.component.html
Update index.component.css
Update index.component.html
Update index.component.css
Update index.component.css
Update index.component.css
Update index.component.css
2019-01-14 21:34:45 +05:30
neeraj3029
60019dd3a7 depth field only accepts numbers 2019-01-14 21:33:05 +05:30
neeraj3029
b76b6dc625 cursor chnages to hover 2019-01-14 21:29:00 +05:30
Shreyansh Dwivedi
1b2fc9f636 Refactored Help Component and Added tests for increasing coverage 2019-01-10 01:25:41 +05:30
Shreyansh Dwivedi
181b848931 Added share link and made styles changes to infobox-share-popup (#1349) 2019-01-04 22:36:46 +01:00
subhahu
2df849dff2 fixing (#1351)
Update contact.component.ts
Update contact.component.html
2019-01-04 22:36:27 +01:00
Raj Vaibhav Dubey
4c4b598174 Tests Added (#1278)
* Tests Added

Some of the tests for the files have been added

* Tests Added

Some of the tests for the newly added functions have been added
2019-01-04 22:33:26 +01:00
Shreyansh Dwivedi
cee3bc03a4 Fixed UI of Advanced Search Page 2018-12-30 12:08:08 +05:30
Samagra Gupta
875c1e8f6b Analytics border lie inside the window (#1346) 2018-12-29 19:32:23 +05:30
Prateek Gogia
a0d1a93113 Fixed clear search issue #1230
Fixed double quotes to single quotes

Fixed reference for navbar html

Fixed spacing issues in constructor scope

Fixed clear search issue #1230
2018-12-28 01:12:04 +05:30
Shreyansh Dwivedi
40df5645a8 Made active theme button different from others 2018-12-26 18:53:11 +05:30
Shreyansh Dwivedi
c4cf69e031 changes title according to search 2018-12-22 07:41:57 +05:30
AakashMallik
efaa062310 Fixes #1322: About component refactored and cleaned up 2018-12-22 07:40:01 +05:30
Shreyansh Dwivedi
4da663f06b Added/Updated tests 2018-12-22 01:17:30 +05:30
AakashMallik
7efa87c353 Fixes #1310: Travis issue fixed 2018-12-20 04:30:03 +05:30
Prabhu Pant
59481bb3e8 Fixes #1242 corrections in crawl job page (#1243) 2018-12-18 14:03:15 +01:00
SHUBHAM KUMAR
c6901e142f Fix 1268 - Fix overlapping Help Section with footer (#1271)
* Updated Badgeyay's icon (#1203)

The badgeyay's icon on susper.com has been updated.

Fixes #1201

* "Commit "
2018-12-18 14:02:54 +01:00
subhahu
931eb2777b Fixing the hovering and visited color of links (#1293)
* Changing color of hovering , Visited link 

Ignoring the overriden of tags of hover and visited

* Changing color
2018-12-18 14:01:39 +01:00
subhahu
2de0a243b9 Fixing About page css (#1298) 2018-12-18 14:01:26 +01:00
humble_D
77af9f3c59 Fixse #1306: Removed redundant package delarations (#1307) 2018-12-18 14:01:05 +01:00
humble_D
e7bee72685 Fixes #1308: Refactor app.modules.ts (#1309) 2018-12-18 14:00:48 +01:00
humble_D
e8177c25da Loading animation added to result component (#1204) 2018-12-18 14:00:32 +01:00
Shreyansh Dwivedi
f548aea2a3 Fixed minor link and ui issues 2018-12-14 15:11:12 +05:30
subhahu
33d0ec5df4 Update README.md 2018-12-14 05:01:00 +05:30
subhahu
758a1c6f13 Susper logo Addition 2018-12-14 05:01:00 +05:30
rajvaibhavdubey
4ee488487a New Design of about component
The design of the about component has been changed

Fixes #1221
2018-12-12 23:34:53 +05:30
Shreyansh Dwivedi
8c909d3bb6 Fixed a typo in the contact form 2018-12-11 22:57:42 +05:30
Shreyansh Dwivedi
2b529f9c12 Fixed formatting of code 2018-12-11 22:57:42 +05:30
Shreyansh Dwivedi
fdbcf22c8e Fixed linting issue 2018-12-11 22:57:42 +05:30
Shreyansh Dwivedi
6bb8b139fd Fixed validations in Contact form 2018-12-11 22:57:42 +05:30
87 changed files with 10017 additions and 6636 deletions

View file

@ -1,4 +1,4 @@
FROM node:boron
FROM node:8
MAINTAINER Mario Behling <mb@mariobehling.de>
RUN mkdir -p /usr/src/app
@ -8,7 +8,7 @@ RUN apt-get update && apt-get clean && rm -rf /var/lib/apt/lists/*
# install deps
RUN apt-get install curl
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash
RUN apt-get install -y --no-install-recommends nodejs && apt-get clean -y
# copy requirements
@ -17,13 +17,13 @@ COPY app.json /usr/src/app/
COPY tslint.json /usr/src/app/
COPY angular-cli.json /usr/src/app/
# Bundle app source
COPY . /usr/src/app
# install requirements
RUN npm install -g @angular/cli@latest
RUN npm install
# Bundle app source
COPY . /usr/src/app
EXPOSE 4200
CMD ["ng", "serve"]

View file

@ -6,8 +6,8 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
coffee-script (2.4.1)
coffee-script-source
execjs
@ -19,20 +19,35 @@ GEM
commonmarker (0.17.13)
ruby-enum (~> 0.5)
concurrent-ruby (1.0.5)
dnsruby (1.61.2)
addressable (~> 2.5)
dnsruby (1.61.7)
simpleidn (~> 0.1)
em-websocket (0.5.1)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
ethon (0.11.0)
ffi (>= 1.3.0)
ethon (0.14.0)
ffi (>= 1.15.0)
eventmachine (1.2.7)
excon (0.62.0)
excon (0.84.0)
execjs (2.7.0)
faraday (0.15.3)
faraday (1.5.1)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-patron (~> 1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
fastimage (2.1.4)
ffi (1.9.25)
ffi (1.15.3)
forwardable-extended (2.6.0)
gemoji (3.0.0)
github-pages (192)
@ -219,10 +234,11 @@ GEM
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.11.3)
multipart-post (2.0.0)
multipart-post (2.1.1)
nokogiri (1.8.5)
mini_portile2 (~> 2.3.0)
octokit (4.13.0)
octokit (4.21.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
parallel (1.12.1)
pathutil (0.16.1)
@ -232,7 +248,7 @@ GEM
commander (~> 4.3)
percy-client (~> 2.0)
thread (~> 0.2)
percy-client (2.0.0)
percy-client (2.0.4)
addressable
excon
faraday (>= 0.9)
@ -243,6 +259,7 @@ GEM
rouge (2.2.1)
ruby-enum (0.7.2)
i18n
ruby2_keywords (0.0.4)
ruby_dep (1.5.0)
rubyzip (1.2.2)
safe_yaml (1.0.4)
@ -251,17 +268,22 @@ GEM
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sawyer (0.8.1)
addressable (>= 2.3.5, < 2.6)
faraday (~> 0.8, < 1.0)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
simpleidn (0.2.1)
unf (~> 0.1.4)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread (0.2.2)
thread_safe (0.3.6)
typhoeus (1.3.0)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.4.0)
yell (2.0.7)
@ -269,7 +291,6 @@ PLATFORMS
ruby
DEPENDENCIES
eventmachine
fastimage
github-pages
html-proofer

View file

@ -1,4 +1,4 @@
# susper.com
![susper.com](src/assets/images/susper.svg)
master: [![Build Status](https://travis-ci.org/fossasia/susper.com.svg?branch=master)](https://travis-ci.org/fossasia/susper.com)
development: [![Build Status](https://travis-ci.org/fossasia/susper.com.svg?branch=development)](https://travis-ci.org/fossasia/susper.com)
@ -10,7 +10,7 @@ development: [![Build Status](https://travis-ci.org/fossasia/susper.com.svg?bran
[![Percentage of issues still open](http://isitmaintained.com/badge/open/fossasia/susper.com.svg)](http://isitmaintained.com/project/fossasia/susper.com "Percentage of issues still open")
Susper is a decentralized Search Engine that uses the peer to peer system yacy and Apache Solr to crawl and index search results.
Susper is a decentralized Search Engine that uses the peer to peer system YaCy and Apache Solr to crawl and index search results.
You can test the branches of susper here:
* Development branch: https://susper-dev.herokuapp.com
@ -22,7 +22,7 @@ Our chat channel is on gitter: https://gitter.im/fossasia/susper.com
## Components and Technology
This is a front-end for Susper running on Yacy server. The retrieval of search results is done using YaCy search API.
This is a front-end for Susper running on YaCy server. The retrieval of search results is done using YaCy search API.
* Solr and Javascript(JSON)
@ -30,7 +30,7 @@ Search results are displayed using Solr server which is embedded into YaCy. All
## Technology Stack
* HTML - Structure of the web page generated.
* Bootstrap-3.3.7 - Used for responsive design
* Bootstrap-3.3.7 - Used for responsive design.
* CSS - Styling options and details of the web page.
* Javascript(JSON) - Used to store information for deploying the application such as dependencies.
* Angular-4 - Structure for deployment of the web page.
@ -55,17 +55,17 @@ npm install -g @angular/cli@latest
* **Step 2:** Then cd into that cloned folder
* **Step 3:** Then execute the command: ```npm install```
* **Step 4:** Deploy locally by running this:```ng serve```
* **Step 5:** Go to [localhost:4200](http://localhost:4200) where the application will be running locally.
* **Step 5:** Go to [localhost:4200](http://localhost:4200) where the application will be running locally
### For deploying with [Github Pages](https://pages.github.com/):
With these very simple steps you can have susper deployed:
* **Step 1:** Fork susper repository and clone it to your desktop.
* **Step 1:** Fork susper repository and clone it to your desktop
* **Step 2:** Then checkout to your master branch `git checkout master`
* **Step 3:** Deploy by running this: ```ng build``` and then ```npm run deploy```
* **Step 4:** Visit `https://yourusername.github.io/susper` and you should see the Susper search running.
* **Step 5:** As you search you might see that it can't find anything, to resolve this, on search you will see there is a red shield on the search bar, click on it and allow to load unsafe scripts.
* **Step 6:** Reload and you will have a fully functioning Susper search deployed on GitHub pages.
* **Step 4:** Visit `https://yourusername.github.io/susper` and you should see the Susper search running
* **Step 5:** As you search you might see that it can't find anything, to resolve this, on search you will see there is a red shield on the search bar, click on it and allow to load unsafe scripts
* **Step 6:** Reload and you will have a fully functioning Susper search deployed on GitHub pages
### For deploying with [Surge](https://surge.sh/):
@ -87,7 +87,8 @@ This is an Open Source project and we would be happy to see contributors who rep
* When you're submitting a PR for a UI-related issue, it would be really awesome if you add a screenshot of your change or a link to a deployment where it can be tested out along with your PR. It makes it very easy for the reviewers and you'll also get reviews quicker.
**Feature Requests and Bug Reports**
* When you file a feature request or when you are submitting a bug report to the [issue tracker](https://github.com/fossasia/susper.com/issues), make sure you add steps to reproduce it. Especially if that bug is some weird/rare one.
* When you file a feature request or when you are submitting a bug, report to the [issue tracker] (https://github.com/fossasia/susper.com/issues)
* Make sure you add steps to reproduce it, especially if that bug is some weird/rare one.
**Join the development**
* Before you join development, please set up the project on your local machine, run it and go through the application completely. Press any button you can find and see where it leads to. Explore. (Don't worry ... Nothing will happen to the app or to you due to the exploring :wink:. Only thing that will happen is, you'll be more familiar with what is where and might even get some cool ideas on how to improve various aspects of the app.)
@ -98,7 +99,7 @@ Do read the [Open Source Developer Guide and Best Practices at FOSSASIA](https:/
## Issue and Branch Policy
Before making a pull request, please file an issue. So, other developers have the chance to give feedback or discuss details. Match every pull request with an issue please and add the issue number in description e.g. like "Fixes #123".
Before making a pull request, please file an issue so that other developers have the chance to give feedback or discuss details. Please match every pull request with an issue and add the issue number in description e.g. like "Fixes #123".
We have the following branches:
* **development**

View file

@ -17,4 +17,6 @@ git clone https://github.com/fossasia/susper.com.git && cd susper.com
* In the terminal window, run `docker build -t susper:latest .` to build susper.com's docker image. This process can take some time.
* After build is done, run `docker run -d -p 4200:4200 susper` to start the server.
* After build is done, run `docker run -d -p 4200:4200 susper:latest` to start the server.
* Navigate to [localhost:4200](http://localhost:4200/) in your browser to see Susper up and running.

View file

@ -15,7 +15,8 @@ module.exports = function (config) {
],
files: [
{ pattern: './src/test.ts', watched: false },
'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js'
'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.2/js/swiper.min.js'
],
preprocessors: {
'./src/test.ts': ['@angular/cli'],

11369
package-lock.json generated

File diff suppressed because it is too large Load diff

9
package.json Executable file → Normal file
View file

@ -16,10 +16,8 @@
"dependencies": {
"@angular/animations": "^4.3.6",
"@angular/cdk": "^2.0.0-beta.8",
"@angular/cli": "^1.1.0",
"@angular/common": "4.1.3",
"@angular/compiler": "4.1.3",
"@angular/compiler-cli": "4.1.3",
"@angular/core": "4.1.3",
"@angular/forms": "4.1.3",
"@angular/http": "4.1.3",
@ -33,6 +31,7 @@
"@ngrx/router-store": "^1.2.6",
"@ngrx/store": "^2.2.2",
"@ngrx/store-devtools": "^3.2.4",
"bootstrap": "^3.3.0",
"chart.js": "^2.6.0",
"codecov.io": "^0.1.6",
"core-js": "^2.4.1",
@ -46,10 +45,6 @@
"reselect": "^3.0.1",
"rxjs": "^5.5.6",
"ts-helpers": "^1.1.2",
"ts-node": "3.0.4",
"tslint": "^5.4.0",
"typescript": "~2.3.4",
"webdriver-manager": "12.0.6",
"zone.js": "^0.8.11"
},
"devDependencies": {
@ -65,7 +60,7 @@
"jasmine-core": "2.6.2",
"jasmine-spec-reporter": "4.1.0",
"jquery": "^3.2.1",
"karma": "^2.0.2",
"karma": "^6.3.16",
"karma-chrome-launcher": "^2.1.1",
"karma-cli": "^1.0.1",
"karma-coverage": "^1.1.1",

View file

@ -1,15 +1,3 @@
.banner {
width: 100%;
position: relative;
bottom: 0;
left: 0;
right: 0;
top: -10%;
overflow: hidden;
height:500px;
}
#about{
min-height:100vh;
position: relative;
@ -25,42 +13,16 @@ footer{
text-align: left;
}
.page-link {
padding-right: 0%;
color: #1a0dab;
}
.navbar-right {
border-top:none;
}
.image-banner {
position: relative;
overflow: hidden;
padding:0px;
}
.navbar-logo {
height: 30px;
margin-top: 8px;
padding-left: 20px;
}
.navbar-text {
padding-right: 30px;
font-size: 20px;
}
.text-center {
text-align: center;
font-family: "Quicksand", sans-serif;
}
.bold {
font-weight: 700;
}
.about-navbar {
position: relative;
top: -5px;
@ -75,62 +37,10 @@ footer{
margin: -57px 0 0 0
}
.sub-details {
font-family: Roboto, sans-serif;
line-height: 1.4;
font-size: 14px;
}
.sub-details h5 {
font-family: Roboto, sans-serif;
line-height: 1.4;
font-size: 14px;
margin: 20px 0 20px 0;
}
.sub-details p {
font-family: Roboto, sans-serif;
line-height: 1.4;
font-size: 14px;
text-align: justify;
}
.about-sub-details {
padding: 20px 0 20px 0;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
}
.about-sub-details .row h2 {
font-family: "Quicksand", sans-serif;
padding: 5px 10px;
font-weight: 500;
font-size: 24px;
}
.contact-sub-details {
margin-bottom: 40px;
}
.contact-sub-details .row h2 {
font-family: "Quicksand", sans-serif;
padding: 5px 10px;
font-weight: 500;
font-size: 24px;
}
.navbar-fixed-bottom, .navbar-fixed-top{
position: relative !important;
}
.contents {
text-align: right;
}
a {
text-decoration: none;
padding-right: 30px;
color: rgb(119,119,119);
padding-right: 0px;
}
.navbar-collapse.navbar-right {
@ -146,6 +56,10 @@ a:hover {
padding-left: 100px;
}
.contact-container {
margin-bottom: 64px;
}
@media screen and (max-width:990px) {
.navbar-collapse.navbar-right {
text-align: right;
@ -159,8 +73,8 @@ a:hover {
}
}
@media only screen and (min-height: 750px) {
.banner{
height:auto;
@media screen and (max-width: 768px ){
.contact-container {
margin-bottom: 88px;
}
}

View file

@ -1,97 +1,218 @@
<div id="about">
<nav class="navbar navbar-default nav-about">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#dropmenu">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand about-navbar" routerLink="/" title="Susper Search Engine">
<img alt="brand" class="navbar-logo" src="../../assets/images/susper.svg">
<img alt="brand" class="navbar-logo" src="../../assets/images/susper.svg" />
</a>
</div>
<div class="collapse navbar-collapse" id="dropmenu">
<ul class="nav navbar-nav navbar-collapse navbar-right">
<li>
<a routerLink="/privacy">Privacy</a>
</li>
<li>
<a routerLink="/terms">Terms</a>
</li>
<li>
<a routerLink="/about">About</a>
</li>
<li>
<a routerLink="/contact">Contact</a>
</li>
<li><a routerLink="/privacy">Privacy</a></li>
<li><a routerLink="/terms">Terms</a></li>
<li><a routerLink="/about">About</a></li>
<li><a routerLink="/contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<div class="image-banner col-xs-12 col-sm-12 col-md-12 col-lg-12">
<img src="../../assets/images/mountain.jpg" class="img-responsive banner">
<br>
</div>
<div class="container">
<br>
<h2 class="text-center">Susper is a decentral Search Engine that uses the peer to peer system 'YaCy' and 'Apache Solr' to crawl and index search
results.
</h2>
<br>
<div class="about-sub-details">
<div class="row">
<h2 class="bold">About Us</h2>
</div>
<div class="row">
<div class="col-lg-4 col-sm-12 sub-details">
<h5 class="bold">About YaCy</h5>
<p>YaCy is a free search engine that anyone can use to build a search portal for their intranet or to help search
the public internet. Read more about YaCy here -
<a class="page-link" href="https://{{yacySite}}/en/index.html" target="_blank">YaCy Decentralized Web Search</a>
</p>
</div>
<div class="col-lg-4 col-sm-12 sub-details">
<h5 class="bold">Communication</h5>
<p>Facing issues while setting up project on local environment? Our chat channel is on gitter here:
<a class="page-link" href="https://gitter.im/fossasia/{{susperUrl}}" target="_blank">fossasia/susper.com</a>. We'll be happy to help you out!'</p>
</div>
<div class="col-lg-4 col-sm-12 sub-details">
<h5 class="bold">Contribute to our project</h5>
<p>Get involved as an Open Source developer, designer or tester and start your adventure today! Solve an issue or
feature request on our repositories with
<a class="page-link" href="https://{{fossasia_repo}}/{{susperUrl}}" target="_blank">FOSSASIA</a>. Build up your developer profile and become part of a fantastic community.</p>
</div>
</div>
<div class="container" style="padding-top: 56px">
<div class="aboutFOSS">
<h1 style="text-align: center">About Us</h1>
<h2 style="text-align: center">
We bring amazing people together to create, develop, design <br />and make things with Open
Technologies - hardware and software - <br />and share our work for the benefit of all.
</h2>
</div>
<div class="contact-sub-details">
<div class="row">
<h2 class="bold">Contact Us</h2>
<div class="aboutSUS row" style="padding-top: 80px">
<div class="col-md-3">
<h2>About Susper</h2>
Susper is a decentral Search Engine that uses the peer to peer system 'YaCy' and 'Apache
Solr' to crawl and index search results.
</div>
<div class="col-md-3">
<h2>About YaCy</h2>
YaCy is a free search engine that anyone can use to build a search portal for their intranet
or to help search the public internet. Read more about YaCy here -
<a [href]="yacySite">YaCy Decentralized Web Search</a>
</div>
<div class="col-md-3">
<h2>Communication</h2>
Facing issues while setting up project on local environment? Our chat channel is on gitter
here: <a href="https://gitter.im/fossasia/susper.com">fossasia/susper.com</a>. We'll be
happy to help you out!
</div>
<div class="col-md-3">
<h2>Contribute to our project</h2>
Get involved as an Open Source developer, designer or tester and start your adventure today!
Solve an issue or feature request on our repositories with
<a href="https://github.com/fossasia/susper.com">FOSSASIA</a>. Build up your developer
profile and become part of a fantastic community.
</div>
</div>
<div class="ourTeam row">
<h2 style="text-align:center">Our Team</h2>
<div style="padding-top:40px">
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars2.githubusercontent.com/u/1583873?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Mario Behling</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars3.githubusercontent.com/u/20185076?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Soumya Vadlamannati</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars1.githubusercontent.com/u/15216503?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Nikhil Rayaprolu</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars2.githubusercontent.com/u/22245418?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Harshit Prasad</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars1.githubusercontent.com/u/25537606?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Praveen Ojha</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars1.githubusercontent.com/u/238730?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Michael Christen</h4>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-sm-12 contact-sub-details">
<p>If you would like to get in touch with us, you find our details on the
<a class="page-link" routerLink="/contact">contact page.</a>
</p>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars0.githubusercontent.com/u/7692626?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Isuru Abeyvardana</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars0.githubusercontent.com/u/19776278?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Prabhu Pant</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars2.githubusercontent.com/u/28914919?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Sathira Umesh</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars3.githubusercontent.com/u/33062425?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Raj Vaibhav Dubey</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars1.githubusercontent.com/u/33882273?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Valentin Bercaru</h4>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 text-center">
<div class="card">
<img
class="card-img-top"
style="width: 200px; height : 200px"
src="https://avatars0.githubusercontent.com/u/22936570?s=460&v=4"
/>
<div class="card-body">
<h4 style="text-align:center; font-size:18px" class="card-text">Bhavesh Anand</h4>
</div>
</div>
</div>
</div>
</div>
<br>
<hr />
<div class="contact-container">
<h1>Contact Us</h1>
<p>
If you would like to get in touch with us, you find our details on the
<a href="https://susper.com/contact">contact page</a>.
</p>
</div>
</div>
<footer>
<app-footer-navbar></app-footer-navbar>
</footer>
<footer><app-footer-navbar></app-footer-navbar></footer>
</div>

View file

@ -34,9 +34,9 @@ describe('Component: About', () => {
});
it('should have alt text property as brand', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
let image: HTMLImageElement = compiled.querySelector('div.navbar-header img');
const image: HTMLImageElement = compiled.querySelector('div.navbar-header img');
expect(image).toBeTruthy();
expect(image.alt).toBe('brand');
});
@ -46,8 +46,14 @@ describe('Component: About', () => {
expect(footerNavbar).toBeTruthy();
});
it('should have a footer element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('footer')).toBeTruthy();
});
it('should have an app-footer-navbar element', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-footer-navbar')).toBeTruthy();
});

View file

@ -1,17 +1,18 @@
import { Component, OnInit } from '@angular/core';
import { url } from '../../assets/url_configuration';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.css']
styleUrls: ['./about.component.css'],
})
export class AboutComponent implements OnInit {
susperUrl = url.susper.site;
yacyUrl = url.yacy.api_server;
yacySite = url.yacy.site;
fossasia_repo = url.github_repo.fossasia;
constructor() { }
ngOnInit() {
}
yacySite: string;
constructor() {}
ngOnInit() {
this.yacySite = url.yacy.site;
}
}

View file

@ -1,18 +1,22 @@
import { Action } from '@ngrx/store';
import { type } from '../utils';
export const ActionTypes = {
CONTENT_CHANGE: type('[Knowledge] Content Change'),
IMAGE_CHANGE: type('[Knowledge] Image Change'),
DESCRIPTION_CHANGE: type('[Knowledge] Description Change')
};
export class SearchContentAction implements Action {
type = ActionTypes.CONTENT_CHANGE;
constructor(public payload: object) {}
}
export class SearchImageAction implements Action {
type = ActionTypes.IMAGE_CHANGE;
constructor(public payload: object) {}
}
export class DescriptionAction implements Action {
type = ActionTypes.DESCRIPTION_CHANGE;
constructor(public payload: object) {}

View file

@ -8,13 +8,11 @@ export const ActionTypes = {
export class QueryAction implements Action {
type = ActionTypes.QUERYCHANGE;
constructor(public payload: any) {}
}
export class QueryServerAction implements Action {
type = ActionTypes.QUERYSERVER;
constructor(public payload: any) {}
}

View file

@ -10,25 +10,21 @@ export const ActionTypes = {
export class SearchAction implements Action {
type = ActionTypes.CHANGE;
constructor(public payload: any) {}
}
export class ItemsAction implements Action {
type = ActionTypes.ITEMS;
constructor(public payload: any) {}
}
export class TotalResultsAction implements Action {
type = ActionTypes.TOTALRESULTS;
constructor(public payload: any) {}
}
export class NavigationAction implements Action {
type = ActionTypes.NAVIGATION;
constructor(public payload: any) {}
}

View file

@ -7,7 +7,6 @@ export const ActionTypes = {
export class SearchAction implements Action {
type = ActionTypes.CHANGE;
constructor(public payload: any) {}
}

View file

@ -40,7 +40,16 @@ describe('AdvancedsearchComponent', () => {
fixture.detectChanges();
});
it('should create an instance', () => {
it('should create an advanced search instance', () => {
expect(component).toBeTruthy();
});
it('should have advance search modal', () => {
const compiled = fixture.debugElement.nativeElement;
const button = compiled.querySelector('button');
button.click();
const modalBody: HTMLInputElement = compiled.querySelector('div.modal-body');
expect(modalBody).toBeTruthy();
});
});

View file

@ -1,53 +1,61 @@
/* Packages */
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { StoreModule } from '@ngrx/store';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';
import { InfiniteScrollModule } from "ngx-infinite-scroll";
import { ChartsModule } from 'ng2-charts/ng2-charts';
import { EffectsModule } from '@ngrx/effects';
import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal';
/* Custom Components */
import { AppComponent } from './app.component';
import { NavbarComponent } from './navbar/navbar.component';
import { IndexComponent } from './index/index.component';
import { ResultsComponent } from './results/results.component';
import { Routes, RouterModule } from '@angular/router';
import { SearchService } from './services/search.service';
import { NotFoundComponent } from './not-found/not-found.component';
import { CommonModule } from '@angular/common';
import { AdvancedsearchComponent } from './advancedsearch/advancedsearch.component';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { StoreModule } from '@ngrx/store';
import { reducer } from './reducers/index';
import { SearchBarComponent } from './search-bar/search-bar.component';
import { AboutComponent } from './about/about.component';
import { FooterNavbarComponent } from './footer-navbar/footer-navbar.component';
import { ContactComponent } from './contact/contact.component';
import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal';
import { TermsComponent } from './terms/terms.component';
import { PrivacyComponent } from './privacy/privacy.component';
import { EffectsModule } from '@ngrx/effects';
import { ApiSearchEffects } from './effects/search-effects';
import { NewadvancedsearchComponent } from './newadvancedsearch/newadvancedsearch.component';
import { AutocompleteService } from "./services/autocomplete.service";
import { AutoCompleteComponent } from './auto-complete/auto-complete.component';
import { ThemeComponent } from './theme/theme.component';
import { ThemeService } from './services/theme.service';
import { CrawlstartComponent } from './crawlstart/crawlstart.component';
import { CrawlstartService } from "./services/crawlstart.service";
import { SearchsettingsComponent } from './searchsettings/searchsettings.component';
import { SpeechService } from './services/speech.service';
import { DropdownComponent } from './dropdown/dropdown.component';
import { IntelligenceComponent } from './intelligence/intelligence.component';
import { IntelligenceService } from "./services/intelligence.service";
import { SpeechtotextComponent } from './speechtotext/speechtotext.component';
import { AutoCorrectComponent } from './auto-correct/auto-correct.component';
import { StatsboxComponent } from './statsbox/statsbox.component';
import { InfoboxComponent } from './infobox/infobox.component';
import { KnowledgeEffects } from "./effects/knowledge";
/* Custom Services */
import { AutocompleteService } from "./services/autocomplete.service";
import { ThemeService } from './services/theme.service';
import { CrawlstartService } from "./services/crawlstart.service";
import { SpeechService } from './services/speech.service';
import { IntelligenceService } from "./services/intelligence.service";
import { AutocorrectService } from "./services/autocorrect.service";
import { SpeechSynthesisService } from './services/speech-synthesis.service';
import { InfiniteScrollModule } from "ngx-infinite-scroll";
import { ChartsModule } from 'ng2-charts/ng2-charts';
import { InfoboxComponent } from './infobox/infobox.component';
import { KnowledgeapiService } from './services/knowledgeapi.service';
import { KnowledgeEffects } from "./effects/knowledge";
import { SearchService } from './services/search.service';
import { NewsService } from './services/news.service';
import { GetJsonService } from './services/get-json.service';
import { HelpComponent } from './help/help.component';
/* Reducers */
import { reducer } from './reducers/index';
const appRoutes: Routes = [
{path: 'search', component: ResultsComponent},
{path: '', component: IndexComponent},

View file

@ -37,7 +37,15 @@ describe('AutoCompleteComponent', () => {
fixture.detectChanges();
});
it('should create', () => {
it('should create autocomplete component', () => {
expect(component).toBeTruthy();
});
it('should have query$ variable', () => {
expect(component.query$).toBeTruthy();
});
it('should have resultsearch variable equal to "/search"', () => {
expect(component.resultsearch).toEqual('/search');
});
});

View file

@ -34,17 +34,6 @@
padding-left: 20px;
}
.navbar-text {
padding-right: 30px;
font-size: 20px;
margin-top: 6px;
}
.text-center {
text-align: center;
font-family: "Quicksand", sans-serif;
}
.bold {
font-weight: 700;
}
@ -68,12 +57,6 @@ footer{
}
}
.about-navbar {
position: relative;
top: -5px;
}
.navbar {
margin-bottom: 0px !important;
}
@ -131,10 +114,6 @@ footer{
font-size: 24px;
}
.navbar-fixed-bottom, .navbar-fixed-top{
position: relative !important;
}
.contact-title{
border-bottom: 1px solid #eee;
}

View file

@ -1,351 +1,187 @@
<!-- Start ignoring BootLintBear-->
<!-- Stop ignoring BootLintBear-->
<div id="contact">
<nav class="navbar navbar-default nav-about">
<div class="container-fluid">
<div class="navbar-header">
<button type = "button" class = "navbar-toggle"
data-toggle = "collapse" data-target = "#dropmenu">
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
</button>
<a class="navbar-brand contact-navbar" routerLink="/" title="Susper Search Engine">
<img alt="brand" class="navbar-logo" src="../../assets/images/susper.svg">
</a>
</div>
<div class="collapse navbar-collapse" id="dropmenu">
<ul class="nav navbar-nav navbar-collapse navbar-right">
<li><a routerLink="/privacy">Privacy</a></li>
<li><a routerLink="/terms">Terms</a></li>
<li><a routerLink="/about">About</a></li>
<li><a routerLink="/contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<div class="image-banner col-xs-12 col-sm-12 col-md-12 col-lg-12">
<img src="../../assets/images/boat.png" class="img-responsive banner">
<br>
</div>
<div class="container">
<br>
<div class="about-sub-details">
<div class="row contact-title">
<h2 class="bold">Contact Us</h2>
<br>
</div>
<br>
<div class="row">
<div class="col-lg-12 col-sm-12 sub-details">
<h5 class="bold">Susper</h5>
<p><a href="https://www.openstreetmap.org/search?query=93%20Mau%20Than%20Street%2C%20Can%20Tho#map=19/10.03117/105.77529" target="_blank">93 Mau Than Street<br> Can Tho<br> Viet Nam<br></a> Phone +84 (0) 907 65 29 27<br><a href="mailto: support@susper.net"> Email: support@susper.net</a><br>Board
of Directors: Hong Phuc Dang<br> Susper Ltd. is registered in Can Tho, Viet Nam.</p>
<nav class="navbar navbar-default nav-about">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#dropmenu">
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand contact-navbar" routerLink="/" title="Susper Search Engine">
<img alt="brand" class="navbar-logo" src="../../assets/images/susper.svg" />
</a>
</div>
<div class="collapse navbar-collapse" id="dropmenu">
<ul class="nav navbar-nav navbar-collapse navbar-right">
<li><a routerLink="/privacy">Privacy</a></li>
<li><a routerLink="/terms">Terms</a></li>
<li><a routerLink="/about">About</a></li>
<li><a routerLink="/contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<div class="image-banner col-xs-12 col-sm-12 col-md-12 col-lg-12">
<img src="../../assets/images/boat.png" class="img-responsive banner" /> <br />
</div>
<br>
<div class="contact-sub-details">
<div class="row">
<div class="col-lg-12 col-sm-12 contact-sub-details">
<p>Report a safety or abuse issue affecting our products.<br> If you know of a safety or abuse problem with any of Susper's
services, we'd like to hear about it right away. Please use our <a [routerLink]="['/contact']" (click)="open()">contact form</a> to report the
issue.
</p>
<div class="container">
<br />
<div class="about-sub-details">
<div class="row contact-title">
<h2 class="bold">Contact Us</h2>
<br />
</div>
<br />
<div class="row">
<div class="col-lg-12 col-sm-12 sub-details">
<h5 class="bold">Susper</h5>
<p>
<a
href="https://www.openstreetmap.org/search?query=93%20Mau%20Than%20Street%2C%20Can%20Tho#map=19/10.03117/105.77529"
target="_blank"
>93 Mau Than Street<br />
Can Tho<br />
Viet Nam<br
/></a>
Phone +84 (0) 907 65 29 27<br /><a href="mailto: support@susper.net">
Email: support@susper.net</a
><br />Board of Directors: Hong Phuc Dang<br />
Susper Ltd. is registered in Can Tho, Viet Nam.
</p>
</div>
</div>
</div>
<br />
<div class="contact-sub-details">
<div class="row">
<div class="col-lg-12 col-sm-12 contact-sub-details">
<p>
Report a safety or abuse issue affecting our products.<br />
If you know of a safety or abuse problem with any of Susper's services, we'd like to
hear about it right away. Please use our <a (click)="openModal()">contact form</a> to
report the issue.
</p>
</div>
</div>
</div>
</div>
<footer><app-footer-navbar></app-footer-navbar></footer>
</div>
<footer>
<app-footer-navbar></app-footer-navbar>
</footer>
</div>
<modal #myModal>
<modal #ContactUsModal>
<div>
<a (click)="close()" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="closeModal()" class="close-btn"
><i
class="fa fa-times"
aria-hidden="true"
style="font-size: 2em; float: right; padding: 10px; cursor: pointer;"
></i
></a>
</div>
<form class="form-horizontal" method="POST" action="https://formspree.io/office@fossasia.org">
<fieldset>
<legend>Contact Form</legend>
<fieldset>
<legend>Contact Form</legend>
<div class="form-group">
<label class="col-md-3 control-label" for="textinput">Your Name<sup>*</sup></label>
<div class="form-group">
<label class="col-md-3 control-label" for="textinput">Your Name<sup>*</sup></label>
<div class="col-md-9">
<input id="textinput" name="yourName" type="text" placeholder="Your Name" class="form-control input-md" required="">
</div>
</div>
<div class="col-md-9">
<input
id="textinput"
name="yourName"
type="text"
placeholder="Your Name"
class="form-control input-md"
(ngModelChange)="checkValidity()"
[(ngModel)]="nameInput"
required=""
/>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label"a for="emailinput">Email<sup>*</sup></label>
<div class="form-group">
<label class="col-md-3 control-label" a for="emailinput">Email<sup>*</sup></label>
<div class="col-md-9">
<input id="emailinput" name="email-address" type="email" placeholder="Email Address" class="form-control input-md" required="">
</div>
</div>
<div class="col-md-9">
<input
id="emailinput"
name="email-address"
type="email"
placeholder="Email Address"
class="form-control input-md"
(ngModelChange)="checkValidity()"
[(ngModel)]="emailInput"
required=""
/>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label" for="countrycode">Mobile Number<sup>*</sup></label>
<div class="form-group row">
<label class="col-md-3 control-label" for="countrycode">Mobile Number<sup>*</sup></label>
<div class="col-md-9 mobile_input">
<select id="countrycode" name="countrycode" class="form-control">
<option data-countryCode="DZ" value="213">Algeria (+213)</option>
<option data-countryCode="AD" value="376">Andorra (+376)</option>
<option data-countryCode="AO" value="244">Angola (+244)</option>
<option data-countryCode="AI" value="1264">Anguilla (+1264)</option>
<option data-countryCode="AG" value="1268">Antigua &amp; Barbuda (+1268)</option>
<option data-countryCode="AR" value="54">Argentina (+54)</option>
<option data-countryCode="AM" value="374">Armenia (+374)</option>
<option data-countryCode="AW" value="297">Aruba (+297)</option>
<option data-countryCode="AU" value="61">Australia (+61)</option>
<option data-countryCode="AT" value="43">Austria (+43)</option>
<option data-countryCode="AZ" value="994">Azerbaijan (+994)</option>
<option data-countryCode="BS" value="1242">Bahamas (+1242)</option>
<option data-countryCode="BH" value="973">Bahrain (+973)</option>
<option data-countryCode="BD" value="880">Bangladesh (+880)</option>
<option data-countryCode="BB" value="1246">Barbados (+1246)</option>
<option data-countryCode="BY" value="375">Belarus (+375)</option>
<option data-countryCode="BE" value="32">Belgium (+32)</option>
<option data-countryCode="BZ" value="501">Belize (+501)</option>
<option data-countryCode="BJ" value="229">Benin (+229)</option>
<option data-countryCode="BM" value="1441">Bermuda (+1441)</option>
<option data-countryCode="BT" value="975">Bhutan (+975)</option>
<option data-countryCode="BO" value="591">Bolivia (+591)</option>
<option data-countryCode="BA" value="387">Bosnia Herzegovina (+387)</option>
<option data-countryCode="BW" value="267">Botswana (+267)</option>
<option data-countryCode="BR" value="55">Brazil (+55)</option>
<option data-countryCode="BN" value="673">Brunei (+673)</option>
<option data-countryCode="BG" value="359">Bulgaria (+359)</option>
<option data-countryCode="BF" value="226">Burkina Faso (+226)</option>
<option data-countryCode="BI" value="257">Burundi (+257)</option>
<option data-countryCode="KH" value="855">Cambodia (+855)</option>
<option data-countryCode="CM" value="237">Cameroon (+237)</option>
<option data-countryCode="CA" value="1">Canada (+1)</option>
<option data-countryCode="CV" value="238">Cape Verde Islands (+238)</option>
<option data-countryCode="KY" value="1345">Cayman Islands (+1345)</option>
<option data-countryCode="CF" value="236">Central African Republic (+236)</option>
<option data-countryCode="CL" value="56">Chile (+56)</option>
<option data-countryCode="CN" value="86">China (+86)</option>
<option data-countryCode="CO" value="57">Colombia (+57)</option>
<option data-countryCode="KM" value="269">Comoros (+269)</option>
<option data-countryCode="CG" value="242">Congo (+242)</option>
<option data-countryCode="CK" value="682">Cook Islands (+682)</option>
<option data-countryCode="CR" value="506">Costa Rica (+506)</option>
<option data-countryCode="HR" value="385">Croatia (+385)</option>
<option data-countryCode="CU" value="53">Cuba (+53)</option>
<option data-countryCode="CY" value="90392">Cyprus North (+90392)</option>
<option data-countryCode="CY" value="357">Cyprus South (+357)</option>
<option data-countryCode="CZ" value="42">Czech Republic (+42)</option>
<option data-countryCode="DK" value="45">Denmark (+45)</option>
<option data-countryCode="DJ" value="253">Djibouti (+253)</option>
<option data-countryCode="DM" value="1809">Dominica (+1809)</option>
<option data-countryCode="DO" value="1809">Dominican Republic (+1809)</option>
<option data-countryCode="EC" value="593">Ecuador (+593)</option>
<option data-countryCode="EG" value="20">Egypt (+20)</option>
<option data-countryCode="SV" value="503">El Salvador (+503)</option>
<option data-countryCode="GQ" value="240">Equatorial Guinea (+240)</option>
<option data-countryCode="ER" value="291">Eritrea (+291)</option>
<option data-countryCode="EE" value="372">Estonia (+372)</option>
<option data-countryCode="ET" value="251">Ethiopia (+251)</option>
<option data-countryCode="FK" value="500">Falkland Islands (+500)</option>
<option data-countryCode="FO" value="298">Faroe Islands (+298)</option>
<option data-countryCode="FJ" value="679">Fiji (+679)</option>
<option data-countryCode="FI" value="358">Finland (+358)</option>
<option data-countryCode="FR" value="33">France (+33)</option>
<option data-countryCode="GF" value="594">French Guiana (+594)</option>
<option data-countryCode="PF" value="689">French Polynesia (+689)</option>
<option data-countryCode="GA" value="241">Gabon (+241)</option>
<option data-countryCode="GM" value="220">Gambia (+220)</option>
<option data-countryCode="GE" value="7880">Georgia (+7880)</option>
<option data-countryCode="DE" value="49">Germany (+49)</option>
<option data-countryCode="GH" value="233">Ghana (+233)</option>
<option data-countryCode="GI" value="350">Gibraltar (+350)</option>
<option data-countryCode="GR" value="30">Greece (+30)</option>
<option data-countryCode="GL" value="299">Greenland (+299)</option>
<option data-countryCode="GD" value="1473">Grenada (+1473)</option>
<option data-countryCode="GP" value="590">Guadeloupe (+590)</option>
<option data-countryCode="GU" value="671">Guam (+671)</option>
<option data-countryCode="GT" value="502">Guatemala (+502)</option>
<option data-countryCode="GN" value="224">Guinea (+224)</option>
<option data-countryCode="GW" value="245">Guinea - Bissau (+245)</option>
<option data-countryCode="GY" value="592">Guyana (+592)</option>
<option data-countryCode="HT" value="509">Haiti (+509)</option>
<option data-countryCode="HN" value="504">Honduras (+504)</option>
<option data-countryCode="HK" value="852">Hong Kong (+852)</option>
<option data-countryCode="HU" value="36">Hungary (+36)</option>
<option data-countryCode="IS" value="354">Iceland (+354)</option>
<option data-countryCode="IN" value="91">India (+91)</option>
<option data-countryCode="ID" value="62">Indonesia (+62)</option>
<option data-countryCode="IR" value="98">Iran (+98)</option>
<option data-countryCode="IQ" value="964">Iraq (+964)</option>
<option data-countryCode="IE" value="353">Ireland (+353)</option>
<option data-countryCode="IL" value="972">Israel (+972)</option>
<option data-countryCode="IT" value="39">Italy (+39)</option>
<option data-countryCode="JM" value="1876">Jamaica (+1876)</option>
<option data-countryCode="JP" value="81">Japan (+81)</option>
<option data-countryCode="JO" value="962">Jordan (+962)</option>
<option data-countryCode="KZ" value="7">Kazakhstan (+7)</option>
<option data-countryCode="KE" value="254">Kenya (+254)</option>
<option data-countryCode="KI" value="686">Kiribati (+686)</option>
<option data-countryCode="KP" value="850">Korea North (+850)</option>
<option data-countryCode="KR" value="82">Korea South (+82)</option>
<option data-countryCode="KW" value="965">Kuwait (+965)</option>
<option data-countryCode="KG" value="996">Kyrgyzstan (+996)</option>
<option data-countryCode="LA" value="856">Laos (+856)</option>
<option data-countryCode="LV" value="371">Latvia (+371)</option>
<option data-countryCode="LB" value="961">Lebanon (+961)</option>
<option data-countryCode="LS" value="266">Lesotho (+266)</option>
<option data-countryCode="LR" value="231">Liberia (+231)</option>
<option data-countryCode="LY" value="218">Libya (+218)</option>
<option data-countryCode="LI" value="417">Liechtenstein (+417)</option>
<option data-countryCode="LT" value="370">Lithuania (+370)</option>
<option data-countryCode="LU" value="352">Luxembourg (+352)</option>
<option data-countryCode="MO" value="853">Macao (+853)</option>
<option data-countryCode="MK" value="389">Macedonia (+389)</option>
<option data-countryCode="MG" value="261">Madagascar (+261)</option>
<option data-countryCode="MW" value="265">Malawi (+265)</option>
<option data-countryCode="MY" value="60">Malaysia (+60)</option>
<option data-countryCode="MV" value="960">Maldives (+960)</option>
<option data-countryCode="ML" value="223">Mali (+223)</option>
<option data-countryCode="MT" value="356">Malta (+356)</option>
<option data-countryCode="MH" value="692">Marshall Islands (+692)</option>
<option data-countryCode="MQ" value="596">Martinique (+596)</option>
<option data-countryCode="MR" value="222">Mauritania (+222)</option>
<option data-countryCode="YT" value="269">Mayotte (+269)</option>
<option data-countryCode="MX" value="52">Mexico (+52)</option>
<option data-countryCode="FM" value="691">Micronesia (+691)</option>
<option data-countryCode="MD" value="373">Moldova (+373)</option>
<option data-countryCode="MC" value="377">Monaco (+377)</option>
<option data-countryCode="MN" value="976">Mongolia (+976)</option>
<option data-countryCode="MS" value="1664">Montserrat (+1664)</option>
<option data-countryCode="MA" value="212">Morocco (+212)</option>
<option data-countryCode="MZ" value="258">Mozambique (+258)</option>
<option data-countryCode="MN" value="95">Myanmar (+95)</option>
<option data-countryCode="NA" value="264">Namibia (+264)</option>
<option data-countryCode="NR" value="674">Nauru (+674)</option>
<option data-countryCode="NP" value="977">Nepal (+977)</option>
<option data-countryCode="NL" value="31">Netherlands (+31)</option>
<option data-countryCode="NC" value="687">New Caledonia (+687)</option>
<option data-countryCode="NZ" value="64">New Zealand (+64)</option>
<option data-countryCode="NI" value="505">Nicaragua (+505)</option>
<option data-countryCode="NE" value="227">Niger (+227)</option>
<option data-countryCode="NG" value="234">Nigeria (+234)</option>
<option data-countryCode="NU" value="683">Niue (+683)</option>
<option data-countryCode="NF" value="672">Norfolk Islands (+672)</option>
<option data-countryCode="NP" value="670">Northern Marianas (+670)</option>
<option data-countryCode="NO" value="47">Norway (+47)</option>
<option data-countryCode="OM" value="968">Oman (+968)</option>
<option data-countryCode="PW" value="680">Palau (+680)</option>
<option data-countryCode="PA" value="507">Panama (+507)</option>
<option data-countryCode="PG" value="675">Papua New Guinea (+675)</option>
<option data-countryCode="PY" value="595">Paraguay (+595)</option>
<option data-countryCode="PE" value="51">Peru (+51)</option>
<option data-countryCode="PH" value="63">Philippines (+63)</option>
<option data-countryCode="PL" value="48">Poland (+48)</option>
<option data-countryCode="PT" value="351">Portugal (+351)</option>
<option data-countryCode="PR" value="1787">Puerto Rico (+1787)</option>
<option data-countryCode="QA" value="974">Qatar (+974)</option>
<option data-countryCode="RE" value="262">Reunion (+262)</option>
<option data-countryCode="RO" value="40">Romania (+40)</option>
<option data-countryCode="RU" value="7">Russia (+7)</option>
<option data-countryCode="RW" value="250">Rwanda (+250)</option>
<option data-countryCode="SM" value="378">San Marino (+378)</option>
<option data-countryCode="ST" value="239">Sao Tome &amp; Principe (+239)</option>
<option data-countryCode="SA" value="966">Saudi Arabia (+966)</option>
<option data-countryCode="SN" value="221">Senegal (+221)</option>
<option data-countryCode="CS" value="381">Serbia (+381)</option>
<option data-countryCode="SC" value="248">Seychelles (+248)</option>
<option data-countryCode="SL" value="232">Sierra Leone (+232)</option>
<option data-countryCode="SG" value="65">Singapore (+65)</option>
<option data-countryCode="SK" value="421">Slovak Republic (+421)</option>
<option data-countryCode="SI" value="386">Slovenia (+386)</option>
<option data-countryCode="SB" value="677">Solomon Islands (+677)</option>
<option data-countryCode="SO" value="252">Somalia (+252)</option>
<option data-countryCode="ZA" value="27">South Africa (+27)</option>
<option data-countryCode="ES" value="34">Spain (+34)</option>
<option data-countryCode="LK" value="94">Sri Lanka (+94)</option>
<option data-countryCode="SH" value="290">St. Helena (+290)</option>
<option data-countryCode="KN" value="1869">St. Kitts (+1869)</option>
<option data-countryCode="SC" value="1758">St. Lucia (+1758)</option>
<option data-countryCode="SD" value="249">Sudan (+249)</option>
<option data-countryCode="SR" value="597">Suriname (+597)</option>
<option data-countryCode="SZ" value="268">Swaziland (+268)</option>
<option data-countryCode="SE" value="46">Sweden (+46)</option>
<option data-countryCode="CH" value="41">Switzerland (+41)</option>
<option data-countryCode="SI" value="963">Syria (+963)</option>
<option data-countryCode="TW" value="886">Taiwan (+886)</option>
<option data-countryCode="TJ" value="7">Tajikstan (+7)</option>
<option data-countryCode="TH" value="66">Thailand (+66)</option>
<option data-countryCode="TG" value="228">Togo (+228)</option>
<option data-countryCode="TO" value="676">Tonga (+676)</option>
<option data-countryCode="TT" value="1868">Trinidad &amp; Tobago (+1868)</option>
<option data-countryCode="TN" value="216">Tunisia (+216)</option>
<option data-countryCode="TR" value="90">Turkey (+90)</option>
<option data-countryCode="TM" value="7">Turkmenistan (+7)</option>
<option data-countryCode="TM" value="993">Turkmenistan (+993)</option>
<option data-countryCode="TC" value="1649">Turks &amp; Caicos Islands (+1649)</option>
<option data-countryCode="TV" value="688">Tuvalu (+688)</option>
<option data-countryCode="UG" value="256">Uganda (+256)</option>
<option data-countryCode="GB" value="44">UK (+44)</option>
<option data-countryCode="UA" value="380">Ukraine (+380)</option>
<option data-countryCode="AE" value="971">United Arab Emirates (+971)</option>
<option data-countryCode="UY" value="598">Uruguay (+598)</option>
<option data-countryCode="US" value="1">USA (+1)</option>
<option data-countryCode="UZ" value="7">Uzbekistan (+7)</option>
<option data-countryCode="VU" value="678">Vanuatu (+678)</option>
<option data-countryCode="VA" value="379">Vatican City (+379)</option>
<option data-countryCode="VE" value="58">Venezuela (+58)</option>
<option data-countryCode="VN" value="84">Vietnam (+84)</option>
<option data-countryCode="VG" value="84">Virgin Islands - British (+1284)</option>
<option data-countryCode="VI" value="84">Virgin Islands - US (+1340)</option>
<option data-countryCode="WF" value="681">Wallis &amp; Futuna (+681)</option>
<option data-countryCode="YE" value="969">Yemen (North)(+969)</option>
<option data-countryCode="YE" value="967">Yemen (South)(+967)</option>
<option data-countryCode="ZM" value="260">Zambia (+260)</option>
<option data-countryCode="ZW" value="263">Zimbabwe (+263)</option>
</select>
<div class="col-md-9 mobile_input">
<select id="countrycode" name="countrycode" class="form-control">
<option
*ngFor="let countryCode of countryCodeList"
[value]="countryCode.value"
>{{ countryCode.description }}</option
>
</select>
<input id="telephone" name="telephone" type="number" placeholder="Mobile Number"(ngModelChange)="checkValidity()" [(ngModel)]="tpnoInput" class="form-control input-md" required="">
<input
id="telephone"
name="telephone"
type="number"
placeholder="Mobile Number"
(ngModelChange)="checkValidity()"
[(ngModel)]="phoneNumberInput"
class="form-control input-md"
required=""
/>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label" for="message">Message<sup>*</sup></label>
<div class="form-group">
<label class="col-md-3 control-label" for="message">Message<sup>*</sup></label>
<div class="col-md-9">
<textarea
class="form-control"
id="message"
name="message"
placeholder="Minimum 100 characters required."
required=""
(ngModelChange)="checkValidity()"
[(ngModel)]="contactMessage"
></textarea>
</div>
</div>
<div class="col-md-9">
<textarea class="form-control" id="message" name="message" placeholder="Minimum 100 words" required="" (ngModelChange)="checkValidity()" [(ngModel)]="contactMessage"></textarea>
</div>
<div class="form-group">
<label class="col-md-12 control-label" for="submit"></label>
</div>
<div class="form-group">
<label class="col-md-12 control-label" for="submit"></label>
<div class="col-md-12">
<button id="submit" name="submit" class="btn btn-info sub-btn" type="submit" #submitButton disabled>Submit</button>
</div>
</div>
</fieldset>
<div class="col-md-12">
<button
id="submit"
name="submit"
class="btn btn-info sub-btn"
type="submit"
#submitButton
disabled
>
Submit
</button>
</div>
</div>
</fieldset>
</form>
</modal>

View file

@ -8,9 +8,10 @@ import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { ContactComponent } from '../contact/contact.component';
import { ContactComponent } from './contact.component';
import { FooterNavbarComponent } from '../footer-navbar/footer-navbar.component';
import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
import { validateMessage, validatePhone, validateEmail, validateName } from '../utils';
describe('Component: Contact', () => {
let component: ContactComponent;
@ -18,18 +19,9 @@ describe('Component: Contact', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
HttpModule,
RouterTestingModule,
FormsModule
],
declarations: [
FooterNavbarComponent,
ContactComponent,
ModalComponent,
]
})
.compileComponents();
imports: [HttpModule, RouterTestingModule, FormsModule],
declarations: [FooterNavbarComponent, ContactComponent, ModalComponent],
}).compileComponents();
}));
beforeEach(() => {
@ -44,9 +36,9 @@ describe('Component: Contact', () => {
});
it('should have alt text property as brand', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
let image: HTMLImageElement = compiled.querySelector('div.navbar-header img');
const image: HTMLImageElement = compiled.querySelector('div.navbar-header img');
expect(image).toBeTruthy();
expect(image.alt).toBe('brand');
});
@ -56,10 +48,39 @@ describe('Component: Contact', () => {
expect(footerNavbar).toBeTruthy();
});
it('should have a footer element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('footer')).toBeTruthy();
});
it('should have an element app-footer-navbar', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-footer-navbar')).toBeTruthy();
});
it('validates messages correctly', () => {
expect(validateMessage('abc')).toBe(false);
expect(
validateMessage(
'fdasfdasfsdaffffffffffffffffffffffffffffffasdfsafasdfadfdasfdasfsdaffffffffffffffffffffffffffffffasdfsafasdfad'
)
).toBe(true);
});
it('validates phone number correctly', () => {
expect(validatePhone('1234567890')).toBe(true);
expect(validatePhone('123450')).toBe(false);
});
it('validates name correctly', () => {
expect(validateName('susper')).toBe(true);
expect(validateName('')).toBe(false);
});
it('validates email correctly', () => {
expect(validateEmail('susper@gmail.com')).toBe(true);
expect(validateEmail('fdasfdasf')).toBe(false);
});
});

View file

@ -1,47 +1,49 @@
import { Component, ViewChild, OnInit } from '@angular/core';
import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
import { validatePhone, validateEmail, validateMessage, validateName, countryCodeList } from '../utils';
@Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.css']
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.css'],
})
export class ContactComponent implements OnInit {
@ViewChild('submitButton') submitButton;
@ViewChild('submitButton') submitButton;
@ViewChild('emailInput') emailInput;
emailInput: string;
nameInput: string;
phoneNumberInput: number;
contactMessage: string;
countryCodeList: any;
nameInput: string;
tpnoInput: number;
contactMessage: string = '';
@ViewChild('ContactUsModal')
modal: ModalComponent;
@ViewChild('myModal')
modal: ModalComponent;
constructor() {}
constructor() { }
ngOnInit() {
this.contactMessage = '';
this.countryCodeList = countryCodeList;
}
ngOnInit() {
}
close() {
this.modal.close();
}
open() {
this.modal.open();
}
// check whether messsage contains more than 100 words
checkValidity() {
if (this.tpnoInput && this.tpnoInput.toString().length >= 10 && this.tpnoInput > 0) {
this.submitButton.nativeElement.disabled = false;
} else {
this.submitButton.nativeElement.disabled = true;
}
if (this.contactMessage && this.contactMessage.length >= 100) {
this.submitButton.nativeElement.disabled = false;
} else {
this.submitButton.nativeElement.disabled = true;
}
closeModal() {
this.modal.close();
}
openModal() {
this.modal.open();
}
checkValidity() {
if (
validateEmail(this.emailInput) &&
validatePhone(this.phoneNumberInput) &&
validateMessage(this.contactMessage) &&
validateName(this.nameInput)
) {
this.submitButton.nativeElement.disabled = false;
} else {
this.submitButton.nativeElement.disabled = true;
}
}
}

View file

@ -1,9 +1,7 @@
@media screen and (max-width:990px) {
.navbar-collapse.navbar-right {
text-align: right;
}
}
.navbar-nav > li > a {
@ -32,11 +30,11 @@
margin: -57px 0 0 0;
}
#label-inline{
#label-inline {
display: inline;
}
#language{
#language {
display: inline;
}
@ -65,70 +63,70 @@
margin-left: 80px;
}
.label-bold{
.label-bold {
font-weight: bold;
}
label{
font-weight: bold;
display: inline;
}
label {
font-weight: bold;
display: inline;
}
#fieldset-1 input[type=text], textarea{
#fieldset-1 input[type=text], textarea {
margin-left: 80px;
}
#fieldset-1 dt{
#fieldset-1 dt {
width: 35%;
}
#fieldset-1 dd{
#fieldset-1 dd {
width: 60%;
}
span{
span {
margin-left: 10px;
}
#country-code-span{
#country-code-span {
margin-left: 7px;
}
.span-right{
.span-right {
margin-left: 0px;
margin-right: 10px;
}
.span-both{
margin: 0px 10px;
.span-both {
margin: 0px 10px;
}
.top-margin-div{
.top-margin-div {
margin-top: 15px;
}
#fieldset-2 .label-bold{
#fieldset-2 .label-bold {
font-weight: bold;
}
#checkbox-desc-1{
#checkbox-desc-1 {
margin-left: 5px;
}
#checkbox-desc-2{
#checkbox-desc-2 {
margin-left: 25px;
}
#directDocByURLID{
#directDocByURLID {
margin-left: 25px;
}
dl{
width: 75%;
margin-left: 20px;
dl {
width: 75%;
margin-left: 20px;
}
dt{
dt {
text-align: left;
float: left; margin-top: 20px;
clear: left;
@ -136,7 +134,7 @@ dt{
position: relative;
}
dd{
dd {
float: left; margin-top: 20px;
display: block;
}
@ -150,7 +148,7 @@ dd{
background-color: #3079ed;
background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed);
box-shadow: none;
cursor: default;
cursor: pointer;
border: 1px solid #3079ed;
border-radius: 2px;
}
@ -194,7 +192,7 @@ dd{
text-align: center;
}
legend{
legend {
border-radius: 5px;
text-align: left;
color: red;
@ -228,17 +226,17 @@ h2 {
line-height: 1.8;
}
fieldset{
fieldset {
color: #18294A;
border: 0px solid #eeeeee;
border-radius: 5px;
}
#language{
#language {
width: 20%;
}
.dd-class{
.dd-class {
width: 100%;
}
@ -262,3 +260,7 @@ div {
margin-left: -77px;
}
}
a {
padding-right: 0px;
}

View file

@ -27,32 +27,32 @@
<div class="container">
<h3 style="color: #dd4b39;font-family: Arial,SansSerif">Expert Crawl Start</h3>
<p>
You can define URLs as start points for Web page crawling and start crawling here.
"Crawling" implies that YaCy will download the given website, extract all links in it and then download the content behind these links.
This is repeated as long as specified under "Crawling Depth".
A crawl can also be started using wget and the <a href="http://www.{{yacyWebSearchUrl}}/wiki/index.php/Dev:APICrawler" target="_blank">post arguments</a> for this web page.
</p>
<hr>
<fieldset>
<fieldset>
<legend>Crawl Job</legend>
<p>A Crawl Job consist of one or more start points, crawl limitations and document freshness rules.</p><br/>
<fieldset id="fieldset-1">
<fieldset id="fieldset-1">
<legend>Start Point</legend>
<dl>
<form>
<div class="row">
<div class="form-group">
<dt>
<input [(ngModel)]="crawlvalues.crawlingMode" name="crawlingMode"
<input [(ngModel)]="crawlvalues.crawlingMode" name="crawlingMode"
value="url" type="radio">
<label for="words" class="label-inline">One Start URL or a list of URLs:<br>
(must start with http:// https:// ftp:// smb:// file://):</label>
</dt>
<dd>
<textarea [(ngModel)]="crawlvalues.crawlingURL" type="text"
<textarea [(ngModel)]="crawlvalues.crawlingURL" type="text"
name="crawlingURL" class="form-control" id="words" cols="64" rows="3" size="41" >
</textarea>
</dd>
@ -70,7 +70,7 @@
<label for="any" class="label-inline">From Sitemap</label>
</dt>
<dd>
<input type="text" class="form-control" id="any"
<input type="text" class="form-control" id="any"
[(ngModel)]="crawlvalues.sitemapURL" maxlength="256" name="sitemapURL">
</dd>
</div>
@ -80,7 +80,7 @@
<label for="none" class="label-inline">From File (enter a path <br/> within your local file system)</label>
</dt>
<dd>
<input type="text" class="form-control" id="none"
<input type="text" class="form-control" id="none"
[(ngModel)]="crawlvalues.crawlingFile" size="71" maxlength="256" name="crawlingFile">
</dd>
</div>
@ -112,7 +112,7 @@
<div class="col-md-4"><label for="last update">Maximum Pages per Domain</label></div>
<div class="col-md-6">
<input type="checkbox" name="DomMaxCheck" [(ngModel)]="crawlvalues.crawlingDomMaxCheck"><span>Use Page Count:</span>
<input type="text" class="form-control" id="last update" name="DomMaxPages" [(ngModel)]="crawlvalues.crawlingDomMaxPages" size="6" maxlength="6">
<input type="number" class="form-control" id="last update" name="DomMaxPages" [(ngModel)]="crawlvalues.crawlingDomMaxPages" size="6" maxlength="6">
</div>
</div>
@ -145,7 +145,7 @@
</div>
<div class="form-group">
<div class="col-md-4"><label for="terms appearing">Load Filter on IPs</label></div>
<div class="col-md-4"><label for="terms appearing">Load Filter on IPs</label></div>
<div class="col-md-6">
<img src="https://{{yacySearchlabUrl}}/env/grafics/plus.gif">
<span>must-match</span>
@ -279,25 +279,25 @@
</div>
<div class="col-md-6">
<input name="storeHT" [(ngModel)]="crawlvalues.storeHTCache" type="checkbox">
<input name="storeHT" [(ngModel)]="crawlvalues.storeHTCache" type="checkbox"><span class="span-both">Yes</span><br>
</div>
</div>
<div class="form-group">
<div class="col-md-4"><label>Policy for usage of Web Cache</label></div>
<div class="col-md-6">
<input name="cache" [(ngModel)]="crawlvalues.cachePolicy" type="radio" value="nocache"><span class="span-both">no cache</span><br/>
<input name="cachepolicy" type="radio" [(ngModel)]="crawlvalues.cachePolicy" value="iffresh"><span class="span-both">if fresh</span><br/>
<input name="cachepolicy" type="radio" [(ngModel)]="crawlvalues.cachePolicy" value="ifexist"><span class="span-both">if exist</span><br/>
<input name="cachepolicy" type="radio" [(ngModel)]="crawlvalues.cachePolicy" value="cacheonly"><span class="span-both">cache only</span><br/>
<input name="cache" [(ngModel)]="crawlvalues.cachePolicy" type="radio" value="nocache"><span class="span-both">No cache</span><br/>
<input name="cachepolicy" type="radio" [(ngModel)]="crawlvalues.cachePolicy" value="iffresh"><span class="span-both">If fresh</span><br/>
<input name="cachepolicy" type="radio" [(ngModel)]="crawlvalues.cachePolicy" value="ifexist"><span class="span-both">If exist</span><br/>
<input name="cachepolicy" type="radio" [(ngModel)]="crawlvalues.cachePolicy" value="cacheonly"><span class="span-both">Cache only</span><br/>
</div>
</div>
</div>
</form>
</form>
</fieldset>
<hr>
<fieldset>
<legend>Snapshot Creation</legend>
@ -306,7 +306,7 @@
<div class="form-group">
<div class="col-md-4"><label>Max Depth for Snapshots</label></div>
<div class="col-md-6">
<input type="text" name="snapshotsmaxdepth" class="form-control" [(ngModel)]="crawlvalues.snapshotsMaxDepth" size="2" maxlength="2" value="-1">
<input type="number" name="snapshotsmaxdepth" class="form-control" [(ngModel)]="crawlvalues.snapshotsMaxDepth" size="2" maxlength="2" value="-1">
</div>
</div>
@ -339,8 +339,8 @@
<div class="form-group">
<div class="col-md-4 top-margin-div"><label>Indexing</label></div>
<div class="col-md-6">
<input name="indextext" type="checkbox" [(ngModel)]="crawlvalues.indexText"><span>index text</span><br/>
<input name="indexmedia" type="checkbox" [(ngModel)]="crawlvalues.indexMedia"><span>index media</span>
<input name="indextext" type="checkbox" [(ngModel)]="crawlvalues.indexText"><span>Index text</span><br/>
<input name="indexmedia" type="checkbox" [(ngModel)]="crawlvalues.indexMedia"><span>Index media</span>
</div>
</div>
@ -360,7 +360,7 @@
</div>
</form>
</fieldset>
<div class="adv-submit" id="crawlStartBtn">
<button class="adv-btn btn" (click)="startCrawlJob()"><span class="btn-text">Start New Crawl Job</span></button>

View file

@ -1,64 +1,66 @@
li.dropdown-menu-box {
top: 10px;
top: 10px;
}
.menu-row{
.menu-row {
width: 267px;
grid-template-columns: 1fr 1fr 1fr;
background-color: white;
}
.menu-row a {
color: #737373;
text-decoration: none;
color: #737373;
text-decoration: none;
}
::-webkit-scrollbar {
display: none;
::-webkit-scrollbar {
display: none;
}
.dropdown-menu-inner {
height:400px;
overflow: auto;
height: 500px;
overflow: auto;
}
.menu-item {
border: 1px solid #fff;
float: left;
margin-bottom: 10px;
display: block;
width: 87px;
padding: 10px 0;
text-align: center;
border: 1px solid #fff;
float: left;
margin-bottom: 10px;
display: block;
width: 87px;
padding: 5px 0 5px 0;
text-align: center;
}
.menu-item:hover {
border-color: #ddd;
border-color: #ddd;
}
.menu-item .img {
height: 50px;
display: flex;
align-items: center;
justify-content: center;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
}
.menu-item img {
display: block;
margin: 0 auto 5px auto;
height: auto;
width: auto;
max-height: 50px;
max-width: 60px;
display: block;
margin: 0 auto 5px auto;
height: auto;
width: auto;
max-height: 50px;
max-width: 60px;
}
.menu-item p {
height: 28px;
line-height: 14px;
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
height: 28px;
line-height: 14px;
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
}
.dropdown-menu {
@ -90,70 +92,76 @@ li.dropdown-menu-box {
content: '';
}
.dropdown-menu-inner {
overflow-x:hidden;
}
div.block:hover {
border: 1px solid rgba(150,150,150,0.3);
border: 1px solid rgba(150, 150, 150, 0.3);
}
div.block {
border: 1px solid #fff;
text-align: center;
border: 1px solid #fff;
text-align: center;
}
p {
padding: 10px;
padding: 10px;
}
.side-menu{
width:0;
.side-menu {
width: 0;
float: right;
}
hr {
clear: both;
margin-bottom: 10px;
clear: both;
margin-bottom: 10px;
}
div#labs {
text-align: center;
margin: 0 0 -20px 0;
text-align: center;
margin: 0 0 -20px 0;
}
@media screen and (max-width: 2670px) {
.dropdown-menu-box {
margin-left: -80%;
}
.dropdown-menu-box {
margin-left: -80%;
}
}
@media screen and (min-width: 2560px) {
.dropdown-menu-box {
margin-left: -80%;
}
.dropdown-menu-box {
margin-left: -80%;
}
}
@media screen and (min-width: 812px) and (max-width: 860px) {
.dropdown-menu-box {
margin-left: -20%;
}
.navbar-right {
float: right!important;
margin-right: -30px;
}
.dropdown-menu-box {
margin-left: -20%;
}
.navbar-right {
float: right !important;
margin-right: -30px;
}
}
@media screen and (min-width: 801px) and (max-width: 811px) {
li.dropdown-menu-box {
margin-left: -14%;
}
li.dropdown-menu-box {
margin-left: -14%;
}
}
@media screen and (min-width: 768px) and (max-width: 800px) {
li.dropdown-menu-box {
margin-left: -14%;
top:40px;
}
li.dropdown-menu-box {
margin-left: -14%;
top: 40px;
}
}
@media screen and (max-width: 767px) {
#small-drop {
#small-drop {
position: absolute;
background-color: white;
border: 1px solid #cccccc;
@ -161,13 +169,13 @@ div#labs {
left: auto;
}
.nav > li > a {
.nav>li>a {
padding-left: 11px;
padding-right: 28px;
}
.dropdown-menu-box {
margin-left: -210%;
margin-left: -210%;
}
}

View file

@ -8,12 +8,12 @@
<!--First row starts from here-->
<div class="dropdown-menu-inner">
<div class="menu-row">
<a class="menu-item" href="//{{fossasiaBlogUrl}}" target="_blank">
<a class="menu-item" href="//{{fossasiaBlogUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/blog.png"></div>
<p>Blogs</p>
</a>
<a class="menu-item" href="{{fossasia_repo}}/{{susperUrl}}" target="_blank">
<a class="menu-item" href="{{fossasia_repo}}/{{susperUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/code.png"></div>
<p>Code</p>
</a>
@ -22,7 +22,7 @@
<!--Second row starts from here-->
<div class="menu-row">
<a class="menu-item" href="//github.com/fossasia/{{susperUrl}}/issues" target="_blank">
<a class="menu-item" href="//github.com/fossasia/{{susperUrl}}/issues" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/bug.png"></div>
<p>Bug<br>Report</p>
</a>
@ -43,17 +43,17 @@
<!--Third row starts from here-->
<div class="menu-row">
<a class="menu-item" href="//{{fossasiaUrl}}" target="_blank">
<a class="menu-item" href="//{{fossasiaUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/fossasia.png"></div>
<p>FOSSASIA</p>
</a>
<a class="menu-item" href="//{{loklakUrl}}" target="_blank">
<a class="menu-item" href="//{{loklakUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/loklak.png"></div>
<p>loklak</p>
</a>
<a class="menu-item" href="//{{susiUrl}}" target="_blank">
<a class="menu-item" href="//{{susiUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/susi_60x12.png"></div>
<p>SUSI</p>
</a>
@ -62,50 +62,54 @@
<!--Third row ends up here-->
<!--Fourth row starts from here-->
<div class="menu-row">
<a class="menu-item" href="//{{eventyayUrl}}" target="_blank">
<a class="menu-item" href="//{{eventyayUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/eventyay.png"></div>
<p>Eventyay</p>
</a>
<a class="menu-item" href="//{{pslabUrl}}" target="_blank">
<a class="menu-item" href="//{{pslabUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/Pslab.png"></div>
<p>PSlab</p>
</a>
<a class="menu-item" href="{{badgeyayUrl}}" target="_blank">
<a class="menu-item" href="{{badgeyayUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/badgeyay.ico"></div>
<p>Badgeyay</p>
</a>
</div>
<!--Fourth row ends up here-->
<!--Fifth row starts from here-->
<div class="menu-row">
<a class="menu-item" href="//{{meilixUrl}}" target="_blank">
<a class="menu-item" href="//{{meilixUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/meilix.png"></div>
<p>Meilix</p>
</a>
<a class="menu-item" href="{{phimpmeUrl}}" target="_blank">
<a class="menu-item" href="{{phimpmeUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/phimp.png"></div>
<p>Phimp.me</p>
</a>
<a class="menu-item" href="{{yaydocUrl}}" target="_blank">
<a class="menu-item" href="{{yaydocUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/yaydoc.jpg"></div>
<p>Yaydoc</p>
</a>
</div>
<!--Fifth row ends up here-->
<!--Sixth row starts from here-->
<div class="menu-row">
<a class="menu-item" href="{{susimagicmirrorUrl}}" target="_blank">
<a class="menu-item" href="{{susimagicmirrorUrl}}" target="_blank" rel="noopener">
<div class="img"><img src="../../assets/images/susimagicmirror.png"></div>
<p>SUSI.AI for Magic Mirror</p>
</a>
<a class="menu-item" href="{{badgemagicURL}}" target="_blank">
<div class="img"><img src="../../assets/images/badgemagic.jpg"></div>
<p>Badgemagic</p>
</a>
</div>
<!--Sixth row ends up here-->
<hr size="20">
<div class="menu-row" id="labs">
<a href="//{{fossasiaLabsUrl}}" target="_blank">More on labs.fossasia.org</a>
<a href="//{{fossasiaLabsUrl}}" target="_blank" rel="noopener">More on labs.fossasia.org</a>
</div>
</div>
@ -113,4 +117,4 @@
</div>
</li>
</ul>
</div>
</div>

View file

@ -8,9 +8,9 @@ describe('DropdownComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DropdownComponent ]
declarations: [DropdownComponent]
})
.compileComponents();
.compileComponents();
}));
beforeEach(() => {
@ -22,4 +22,19 @@ describe('DropdownComponent', () => {
it('should be created', () => {
expect(component).toBeTruthy();
});
it('should have dropdown-menu', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div .side-menu')).toBeTruthy();
});
it('should have dropdown-menu', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div .dropdown-menu')).toBeTruthy();
});
it('should have menu-row items', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div .menu-row')).toBeTruthy();
});
});

View file

@ -17,10 +17,11 @@ export class DropdownComponent implements OnInit {
fossasiaLabsUrl = url.fossasia.labs;
fossasia_repo = url.github_repo.fossasia;
badgeyayUrl = url.badgeyay.site;
meilixUrl = url.meilix.site;
meilixUrl = url.meilix.site;
phimpmeUrl = url.phimpme.site;
susimagicmirrorUrl = url.susimagicmirror.site;
yaydocUrl = url.yaydoc.site;
susimagicmirrorUrl = url.susimagicmirror.site;
yaydocUrl = url.yaydoc.site;
badgemagicURL = url.badgemagic.repo;
constructor() { }
ngOnInit() {

View file

@ -12,8 +12,8 @@ import 'rxjs/add/operator/takeUntil';
import * as query from '../actions/query';
export const CHANGE = 'CHANGE';
import * as fromRoot from '../reducers';
import * as search from '../actions/search';
import {SearchService} from '../services/search.service';
import * as searchactions from '../actions/search';
import { SearchService } from '../services/search.service';
export interface State {
query: string;
@ -35,10 +35,8 @@ export interface State {
@Injectable()
export class ApiSearchEffects {
@Effect()
search$: Observable<any>
= this.actions$
search$: Observable<any> = this.actions$
.ofType(query.ActionTypes.QUERYSERVER)
.debounceTime(300)
.map((action: query.QueryServerAction) => action.payload)
@ -50,14 +48,26 @@ export class ApiSearchEffects {
const nextSearch$ = this.actions$.ofType(query.ActionTypes.QUERYSERVER).skip(1);
if (querypay.search !== false) {
this.searchService.getsearchresults(querypay)
// mark as loading
this.store.dispatch(
new searchactions.SearchAction({
loading: true,
})
);
this.searchService
.getsearchresults(querypay)
.takeUntil(nextSearch$)
.subscribe((response) => {
.subscribe(response => {
if (querypay.append) {
this.store.dispatch(new search.SearchAction({response: response, append: true}));
this.store.dispatch(
new searchactions.SearchAction({ response: response, append: true, loading: false })
);
return empty();
} else {
this.store.dispatch(new search.SearchAction({response: response}));
this.store.dispatch(
new searchactions.SearchAction({ response: response, loading: false })
);
return empty();
}
});
@ -71,6 +81,5 @@ export class ApiSearchEffects {
private actions$: Actions,
private searchService: SearchService,
private store: Store<fromRoot.State>
) { }
) {}
}

View file

@ -4,7 +4,7 @@
<div class="left-side">
<a routerLink="/about" routerLinkActive="active">About</a>
<a href="//blog.fossasia.org/tag/susper/" id="blog">Blogs</a>
<a href="//{{fossasia_repo}}/{{susperUrl}}" id="code">Code</a>
<a href="{{fossasia_repo}}/{{susperUrl}}" id="code">Code</a>
</div>
<div class="right-side">

View file

@ -35,5 +35,9 @@ describe('Component: FooterNavbar', () => {
const footer = new FooterNavbarComponent();
expect(footer).toBeTruthy();
});
it('should have an footer element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('footer')).toBeTruthy();
});
});

View file

@ -4,6 +4,10 @@
}
}
a:hover {
cursor: pointer;
}
.bold {
font-weight: 700;
}
@ -19,6 +23,8 @@
color: blue;
}
.close-btn { cursor: pointer; }
.navbar-right {
border-top:none;
}
@ -172,6 +178,18 @@ a:hover {
color: #000000;
}
.accordion-section-title:before {
font-family: 'Glyphicons Halflings';
content: "\e114";
float: right;
transition: all 0.5s;
}
.accordion-section-title.active:before {
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
.accordion-section-title:hover {
background:#f2f2f2;
text-decoration:none;
@ -258,3 +276,7 @@ a:hover {
width: 90%;
height: 100%;
}
.help {
margin-bottom: 50px;
}

View file

@ -2,15 +2,21 @@
<div class="container-fluid">
<div class="navbar-header">
<button type = "button" class = "navbar-toggle"
data-toggle = "collapse" data-target = "#dropmenu">
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
<button
type = "button"
class = "navbar-toggle"
data-toggle = "collapse"
data-target = "#dropmenu"
>
<span class = "icon-bar"></span> <span class = "icon-bar"></span>
<span class = "icon-bar"></span>
</button>
<a class="navbar-brand about-navbar" routerLink="/" title="Susper Search Engine">
<img alt="brand" class="navbar-logo" src="../../assets/images/susper.svg">
</a>
<a
class="navbar-brand about-navbar"
routerLink="/" title="Susper Search Engine"
>
<img alt="brand" class="navbar-logo" src="../../assets/images/susper.svg">
</a>
</div>
<div class="collapse navbar-collapse" id="dropmenu">
@ -25,27 +31,30 @@
</nav>
<div class="appbar">Susper Search Help</div>
<div class="container">
<div class="container help" >
<div>
<div id="center">
<h1 id="center" class="help-heading">How can we help you?</h1>
<h1 id="center" class="help-heading">
How can we help you?
</h1>
<div id="sub-heading">
<p>Thank you for using Susper Search! We are more than happy to help you in your queries.</p>
<p>
Thank you for using Susper Search! We are more than happy to help you in your queries.
</p>
</div>
</div>
<!--Accordion starts-->
<div class="accordion">
<div class="accordion-section">
<a class="accordion-section-title" href="#accordion-1">Popular Articles</a>
<a class="accordion-section-title" href="#accordion-1">
Popular Articles
</a>
<div id="accordion-1" class="accordion-section-content">
<p><a [routerLink]="['/help']" (click)="open('1')">Make Susper your homepage</a></p>
<p><a [routerLink]="['/help']" (click)="open('2')">Use voice search</a></p>
<p><a [routerLink]="['/help']" (click)="open('3')">Search for images</a></p>
<p><a [routerLink]="['/help']" (click)="open('4')">Block explicit content using Safe Search</a></p>
<p><a (click)="open('1')">Make Susper your homepage</a></p>
<p><a (click)="open('2')">Use voice search</a></p>
<p><a (click)="open('3')">Search for images</a></p>
<p><a (click)="open('4')">Block explicit content using Safe Search</a></p>
</div>
</div>
</div>
@ -53,11 +62,12 @@
<!--Accordion starts-->
<div class="accordion">
<div class="accordion-section">
<a class="accordion-section-title" href="#accordion-2">Troubleshoot & request removals</a>
<a class="accordion-section-title" href="#accordion-2">
Troubleshoot & request removals
</a>
<div id="accordion-2" class="accordion-section-content">
<p><a [routerLink]="['/help']" (click)="open('5')">Problems with Susper Search</a></p>
<p><a [routerLink]="['/help']" (click)="open('5')">Report a problem with Susper Search</a></p>
<p><a (click)="open('5')">Problems with Susper Search</a></p>
<p><a (click)="open('5')">Report a problem with Susper Search</a></p>
</div>
</div>
</div>
@ -65,12 +75,13 @@
<!--Accordion starts-->
<div class="accordion">
<div class="accordion-section">
<a class="accordion-section-title" href="#accordion-3">Settings</a>
<a class="accordion-section-title" href="#accordion-3">
Settings
</a>
<div id="accordion-3" class="accordion-section-content">
<p><a [routerLink]="['/help']" (click)="open('1')">Make Susper your homepage</a></p>
<p><a [routerLink]="['/help']" (click)="open('6')">Make Susper your default search engine</a></p>
<p><a [routerLink]="['/help']" (click)="open('4')">Block explicit content using Safe Search</a></p>
<p><a (click)="open('1')">Make Susper your homepage</a></p>
<p><a (click)="open('6')">Make Susper your default search engine</a></p>
<p><a (click)="open('4')">Block explicit content using Safe Search</a></p>
<p><a routerLink="/preferences">More Settings and preferences</a></p>
</div>
</div>
@ -79,11 +90,12 @@
<!--Accordion starts-->
<div class="accordion">
<div class="accordion-section">
<a class="accordion-section-title" href="#accordion-4">Image Search</a>
<a class="accordion-section-title" href="#accordion-4">
Image Search
</a>
<div id="accordion-4" class="accordion-section-content">
<p><a [routerLink]="['/help']" (click)="open('3')">Search for images</a></p>
<p><a [routerLink]="['/help']" (click)="open('7')">Images aren't loading</a></p>
<p><a (click)="open('3')">Search for images</a></p>
<p><a (click)="open('7')">Images aren't loading</a></p>
<p><a routerLink="/help" (click)="open('4')">Safe image search using Safe Search</a></p>
</div>
</div>
@ -92,11 +104,12 @@
<!--Accordion starts-->
<div class="accordion">
<div class="accordion-section">
<a class="accordion-section-title" href="#accordion-5">Types of search results</a>
<a class="accordion-section-title" href="#accordion-5">
Types of search results
</a>
<div id="accordion-5" class="accordion-section-content">
<p><a [routerLink]="['/help']" (click)="open('2')">Use voice search</a></p>
<p><a [routerLink]="['/help']" (click)="open('3')">Use image search</a></p>
<p><a (click)="open('2')">Use voice search</a></p>
<p><a (click)="open('3')">Use image search</a></p>
<p><a routerLink="/about">Make contributions to Susper Search</a></p>
</div>
</div>
@ -105,11 +118,12 @@
<!--Accordion starts-->
<div class="accordion">
<div class="accordion-section">
<a class="accordion-section-title" href="#accordion-6">Filter & refine your results</a>
<a class="accordion-section-title" href="#accordion-6">
Filter & refine your results
</a>
<div id="accordion-6" class="accordion-section-content">
<p><a [routerLink]="['/help']" (click)="open('8')">How to search on Susper</a></p>
<p><a [routerLink]="['/help']" (click)="open('9')">Refine web searches</a></p>
<p><a (click)="open('8')">How to search on Susper</a></p>
<p><a (click)="open('9')">Refine web searches</a></p>
<p><a routerLink="/advancedsearch">Filter your search results</a></p>
<p><a routerLink="/advancedsearch">Advanced search</a></p>
</div>
@ -123,7 +137,9 @@
<div class="videos-slider">
<div id="center">
<h1 id="center" class="help-heading">Videos to help with Susper Search</h1>
<h1 id="center" class="help-heading">
Videos to help with Susper Search
</h1>
</div>
<div class="swiper-container videos-container">
<div class="swiper-wrapper">
@ -132,15 +148,24 @@
<div class="row">
<div class="col-md-4 video-left">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/DoYvE2vWLNk" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/DoYvE2vWLNk"
allowfullscreen
></iframe>
</div>
<div class="col-md-4 video-middle">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/Uw9HBw9zl3s" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/Uw9HBw9zl3s"
allowfullscreen
></iframe>
</div>
<div class="col-md-4 video-right">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/XNMywaYI2p0" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/XNMywaYI2p0"
allowfullscreen
></iframe>
</div>
</div>
</div>
@ -150,15 +175,24 @@
<div class="row">
<div class="col-md-4 video-left">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/-H6cROLyblA" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/-H6cROLyblA"
allowfullscreen
></iframe>
</div>
<div class="col-md-4 video-middle">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/NkkJHwQlaWw" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/NkkJHwQlaWw"
allowfullscreen
></iframe>
</div>
<div class="col-md-4 video-right">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/q1Zy-APxvs4" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/q1Zy-APxvs4"
allowfullscreen
></iframe>
</div>
</div>
</div>
@ -168,15 +202,24 @@
<div class="row">
<div class="col-md-4 video-left">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/G3TdTBUo13w" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/G3TdTBUo13w"
allowfullscreen
></iframe>
</div>
<div class="col-md-4 video-middle">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/3aFDJ6EDhF4" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/3aFDJ6EDhF4"
allowfullscreen
></iframe>
</div>
<div class="col-md-4 video-right">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/-8l1NUYXFhU" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/-8l1NUYXFhU"
allowfullscreen
></iframe>
</div>
</div>
</div>
@ -186,15 +229,24 @@
<div class="row">
<div class="col-md-4 video-left">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/rPbolbcexuI" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/rPbolbcexuI"
allowfullscreen
></iframe>
</div>
<div class="col-md-4 video-middle">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/AZTb4nITO9I" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/AZTb4nITO9I"
allowfullscreen
></iframe>
</div>
<div class="col-md-4 video-right">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/8rco8lcgins" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/8rco8lcgins"
allowfullscreen
></iframe>
</div>
</div>
</div>
@ -204,7 +256,10 @@
<div class="row">
<div class="col-md-4 video-left">
<img class="ratio" src="../../assets/images/16x9.png" />
<iframe src="https://www.youtube.com/embed/YqvryPQXL_g" allowfullscreen></iframe>
<iframe
src="https://www.youtube.com/embed/YqvryPQXL_g"
allowfullscreen
></iframe>
</div>
</div>
</div>
@ -225,37 +280,62 @@
<modal #Homepage>
<div>
<a (click)="close('1')" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="close('1')" class="close-btn">1
<i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i>
</a>
</div>
<div class="queries">
<h3>How to make Susper my homepage?</h3>
<p>You can quickly get to Susper every time you open your browser by making Susper your homepage.</p>
<p>Choose a browser below, then follow the steps on your computer. If you don't see your browser below, go to the "Help" section of your browser and look for information on how to change your browsers homepage.</p>
<p><a href="https://support.mozilla.org/en-US/kb/how-to-set-the-home-page">Firefox</a></p>
<p><a href="https://support.google.com/chrome/answer/95314?hl=en">Chrome</a></p>
<p><a href="https://support.apple.com/en-in/guide/safari/change-your-homepage-ibrw1020/mac">Safari</a></p>
<p><a href="https://support.microsoft.com/en-in/help/4027577/microsoft-edge-change-your-home-page">Microsoft Edge</a></p>
<p>
You can quickly get to Susper every time you open your browser by making Susper your homepage.
</p>
<p>
Choose a browser below, then follow the steps on your computer. If you don't see your browser below,
go to the "Help" section of your browser and look for information on how to change your browsers homepage.
</p>
<p>
<a href="https://support.mozilla.org/en-US/kb/how-to-set-the-home-page">Firefox</a>
</p>
<p>
<a href="https://support.google.com/chrome/answer/95314?hl=en">Chrome</a>
</p>
<p>
<a href="https://support.apple.com/en-in/guide/safari/change-your-homepage-ibrw1020/mac">Safari</a>
</p>
<p>
<a href="https://support.microsoft.com/en-in/help/4027577/microsoft-edge-change-your-home-page">Microsoft Edge</a>
</p>
</div>
</modal>
<modal #VoiceSearch>
<div>
<a (click)="close('2')" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="close('2')" class="close-btn">
<i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i>
</a>
</div>
<div class="queries">
<h3>How to use voice search?</h3>
<p>You can use your voice to do searches by simply tapping on the microphone on the search bar and speaking your query.</p>
<p>
You can use your voice to do searches by simply tapping on the
microphone on the search bar and speaking your query.
</p>
</div>
</modal>
<modal #Image>
<div>
<a (click)="close('3')" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="close('3')" class="close-btn">
<i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i>
</a>
</div>
<div class="queries">
<h3>How to search images on Susper?</h3>
<p>You can search Susper for images, just like you can search for websites. For example, you can check out pictures of potential vacation destinations, or find an image to use in an upcoming presentation.</p>
<p>
You can search Susper for images, just like you can search for websites. For example, you can
check out pictures of potential vacation destinations, or find an image to use in an upcoming presentation.
</p>
<ol>
<li>Go to <a href="https://susper.com">susper.com</a></li>
<li>Search your query</li>
@ -266,11 +346,16 @@
<modal #SafeSearch>
<div>
<a (click)="close('4')" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="close('4')" class="close-btn">
<i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i>
</a>
</div>
<div class="queries">
<h3>How to block explicit content on Susper?</h3>
<p>You can filter explicit search results on Susper, like pornography, with the SafeSearch setting. SafeSearch isnt 100% accurate. But it can help you avoid explicit and inappropriate search results on your phone, tablet, or computer.</p>
<p>
You can filter explicit search results on Susper, like pornography, with the SafeSearch setting. SafeSearch isnt
100% accurate. But it can help you avoid explicit and inappropriate search results on your phone, tablet, or computer.
</p>
<ol>
<li>Go to <a routerLink="/preferences">Search Settings</a></li>
<li>Under "SafeSearch filters," check or uncheck the box next to "Turn on SafeSearch."</li>
@ -281,11 +366,16 @@
<modal #Problem>
<div>
<a (click)="close('5')" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="close('5')" class="close-btn">
<i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i>
</a>
</div>
<div class="queries">
<h3>How to report a problem with Susper?</h3>
<p>If you're having a problem with Susper Search, or want to tell us your thoughts about how it's working, you can send a feedback report to Susper.</p>
<p>
If you're having a problem with Susper Search, or want to tell us your
thoughts about how it's working, you can send a feedback report to Susper.
</p>
<ol>
<li>Open our <a routerLink="/contact">Contact page.</a></li>
<li>Scroll down to the bottom of the page</li>
@ -298,21 +388,36 @@
<modal #DefaultSearch>
<div>
<a (click)="close('6')" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="close('6')" class="close-btn">
<i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i>
</a>
</div>
<div class="queries">
<h3>How to make Susper my default search engine?</h3>
<p>To get results from Susper each time you search, you can make Susper your default search engine. If your browser isnt listed below, check its help resources for info about changing search settings..</p>
<p><a href="https://support.mozilla.org/en-US/kb/change-your-default-search-settings-firefox">Firefox</a></p>
<p><a href="https://support.google.com/chrome/answer/95426?co=GENIE.Platform%3DDesktop&hl=en">Chrome</a></p>
<p><a href="https://discussions.apple.com/thread/5408586">Safari</a></p>
<p><a href="https://support.microsoft.com/en-in/help/4028574/microsoft-edge-change-the-default-search-engine">Microsoft Edge</a></p>
<p>
To get results from Susper each time you search, you can make Susper your default search engine.
If your browser isnt listed below, check its help resources for info about changing search settings..
</p>
<p>
<a href="https://support.mozilla.org/en-US/kb/change-your-default-search-settings-firefox">Firefox</a>
</p>
<p>
<a href="https://support.google.com/chrome/answer/95426?co=GENIE.Platform%3DDesktop&hl=en">Chrome</a>
</p>
<p>
<a href="https://discussions.apple.com/thread/5408586">Safari</a>
</p>
<p>
<a href="https://support.microsoft.com/en-in/help/4028574/microsoft-edge-change-the-default-search-engine">Microsoft Edge</a>
</p>
</div>
</modal>
<modal #ImageNotLoading>
<div>
<a (click)="close('7')" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="close('7')" class="close-btn">
<i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i>
</a>
</div>
<div class="queries">
<h3>Images aren't loading</h3>
@ -329,7 +434,9 @@
<modal #HowToSearch>
<div>
<a (click)="close('8')" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="close('8')" class="close-btn">
<i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i>
</a>
</div>
<div class="queries">
<h3>How to search on Susper?</h3>
@ -344,7 +451,9 @@
<modal #RefineSearch>
<div>
<a (click)="close('9')" class="close-btn"><i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i></a>
<a (click)="close('9')" class="close-btn">
<i class="fa fa-times" aria-hidden="true" style="font-size: 2em"></i>
</a>
</div>
<div class="queries">
<h3>Refine Search</h3>

View file

@ -1,12 +1,11 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpModule } from '@angular/http';
import { Component, Input, Output } from '@angular/core';
import { RouterTestingModule } from '@angular/router/testing';
import { By } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { FooterNavbarComponent } from '../footer-navbar/footer-navbar.component';
import { HelpComponent } from './help.component';
import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
import 'bootstrap';
describe('HelpComponent', () => {
let component: HelpComponent;
@ -45,8 +44,166 @@ describe('HelpComponent', () => {
it('should have an element app-footer-navbar', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-footer-navbar')).toBeTruthy();
});
it('should have 6 div of class accordion', () => {
const element = fixture.debugElement.queryAll(By.css('div.accordion'));
expect(element.length).toBe(6);
});
it('should have alt text property as brand', () => {
const compiled = fixture.debugElement.nativeElement;
const image: HTMLImageElement = compiled.querySelector('div.navbar-header img');
expect(image).toBeTruthy();
expect(image.alt).toBe('brand');
});
it('should have a div with class videos-slider', () => {
const element = fixture.debugElement.queryAll(By.css('div.videos-slider'));
expect(element).toBeTruthy();
});
it('should have preferences router', () => {
const div = document.getElementById('accordion-3');
const newAnchor = div.getElementsByTagName('a')[3];
expect(newAnchor.getAttribute('href')).toEqual('/preferences');
});
it('should call open function on anchor click', async(() => {
spyOn(component, 'open').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('div.accordion-section-content'))[0];
const anchor = element.queryAll(By.css('a'))[0].nativeElement as HTMLElement;
anchor.click();
expect(component.open).toHaveBeenCalled();
}));
it('should call open function on anchor click', async(() => {
spyOn(component, 'open').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('div.accordion-section-content'))[0];
const anchor = element.queryAll(By.css('a'))[1].nativeElement as HTMLElement;
anchor.click();
expect(component.open).toHaveBeenCalled();
}));
it('should call open function on anchor click', async(() => {
spyOn(component, 'open').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('div.accordion-section-content'))[0];
const anchor = element.queryAll(By.css('a'))[2].nativeElement as HTMLElement;
anchor.click();
expect(component.open).toHaveBeenCalled();
}));
it('should call open function on anchor click', async(() => {
spyOn(component, 'open').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('div.accordion-section-content'))[0];
const anchor = element.queryAll(By.css('a'))[3].nativeElement as HTMLElement;
anchor.click();
expect(component.open).toHaveBeenCalled();
}));
it('should call open function on anchor click', async(() => {
spyOn(component, 'open').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('div.accordion-section-content'))[1];
const anchor = element.queryAll(By.css('a'))[0].nativeElement as HTMLElement;
anchor.click();
expect(component.open).toHaveBeenCalled();
}));
it('should call open function on anchor click', async(() => {
spyOn(component, 'open').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('div.accordion-section-content'))[2];
const anchor = element.queryAll(By.css('a'))[1].nativeElement as HTMLElement;
anchor.click();
expect(component.open).toHaveBeenCalled();
}));
it('should call open function on anchor click', async(() => {
spyOn(component, 'open').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('div.accordion-section-content'))[3];
const anchor = element.queryAll(By.css('a'))[1].nativeElement as HTMLElement;
anchor.click();
expect(component.open).toHaveBeenCalled();
}));
it('should call open function on anchor click', async(() => {
spyOn(component, 'open').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('div.accordion-section-content'))[5];
const anchor = element.queryAll(By.css('a'))[0].nativeElement as HTMLElement;
anchor.click();
expect(component.open).toHaveBeenCalled();
}));
it('should call open function on anchor click', async(() => {
spyOn(component, 'open').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('div.accordion-section-content'))[5];
const anchor = element.queryAll(By.css('a'))[1].nativeElement as HTMLElement;
anchor.click();
expect(component.open).toHaveBeenCalled();
}));
it('should call close function on close-btn click', async(() => {
spyOn(component, 'close').and.callThrough();
const closeBtn = fixture.debugElement.queryAll(By.css('a.close-btn'))[0].nativeElement;
closeBtn.click();
expect(component.close).toHaveBeenCalled();
}));
it('should call close function on close-btn click', async(() => {
spyOn(component, 'close').and.callThrough();
const closeBtn = fixture.debugElement.queryAll(By.css('a.close-btn'))[1].nativeElement;
closeBtn.click();
expect(component.close).toHaveBeenCalled();
}));
it('should call close function on close-btn click', async(() => {
spyOn(component, 'close').and.callThrough();
const closeBtn = fixture.debugElement.queryAll(By.css('a.close-btn'))[2].nativeElement;
closeBtn.click();
expect(component.close).toHaveBeenCalled();
}));
it('should call close function on close-btn click', async(() => {
spyOn(component, 'close').and.callThrough();
const closeBtn = fixture.debugElement.queryAll(By.css('a.close-btn'))[3].nativeElement;
closeBtn.click();
expect(component.close).toHaveBeenCalled();
}));
it('should call close function on close-btn click', async(() => {
spyOn(component, 'close').and.callThrough();
const closeBtn = fixture.debugElement.queryAll(By.css('a.close-btn'))[4].nativeElement;
closeBtn.click();
expect(component.close).toHaveBeenCalled();
}));
it('should call close function on close-btn click', async(() => {
spyOn(component, 'close').and.callThrough();
const closeBtn = fixture.debugElement.queryAll(By.css('a.close-btn'))[5].nativeElement;
closeBtn.click();
expect(component.close).toHaveBeenCalled();
}));
it('should call close function on close-btn click', async(() => {
spyOn(component, 'close').and.callThrough();
const closeBtn = fixture.debugElement.queryAll(By.css('a.close-btn'))[6].nativeElement;
closeBtn.click();
expect(component.close).toHaveBeenCalled();
}));
it('should call close function on close-btn click', async(() => {
spyOn(component, 'close').and.callThrough();
const closeBtn = fixture.debugElement.queryAll(By.css('a.close-btn'))[7].nativeElement;
closeBtn.click();
expect(component.close).toHaveBeenCalled();
}));
it('should call close function on close-btn click', async(() => {
spyOn(component, 'close').and.callThrough();
const closeBtn = fixture.debugElement.queryAll(By.css('a.close-btn'))[8].nativeElement;
closeBtn.click();
expect(component.close).toHaveBeenCalled();
}));
});

View file

@ -40,7 +40,7 @@
}
div#susper-logo-fix {
margin-left: -40%;
margin-left: 33.5%;
}
}
@ -119,9 +119,13 @@
z-index: -1;
}
#susper-logo-fix {
width: 150px;
margin-left: 35%;
}
#biglogo {
display: block;
margin-left: 35%;
}
.navbar-brand {
@ -144,8 +148,8 @@ footer {
}
@media screen and (max-width: 823px) {
img#biglogo{
margin-left: 61%;
#susper-logo-fix {
margin-left: 78%;
}
}
@ -154,7 +158,7 @@ footer {
margin-left: -48%;
}
img#biglogo{
#susper-logo-fix {
margin-left: 37%;
}
@ -170,7 +174,8 @@ footer {
}
@media screen and (max-width: 479px) {
img#biglogo{
#susper-logo-fix {
margin-left: 52%;
}
}

View file

@ -4,7 +4,7 @@
<div id="search-bar">
<div class="row">
<div id="susper-logo-fix">
<a href="https://{{fossasia_repo}}/susper.com"><img src="assets/images/susper.svg" alt="Susper" id="biglogo"></a>
<a href="{{fossasia_repo}}/susper.com"><img src="assets/images/susper.svg" alt="Susper" id="biglogo"></a>
</div>
</div>
<h2 class="yacy" id="greeting"></h2>

View file

@ -57,21 +57,37 @@ describe('IndexComponent', () => {
});
it('should have logo with correct alt text property', () => {
let compiled = fixture.debugElement.nativeElement;
let image: HTMLImageElement = compiled.querySelector('div img');
const compiled = fixture.debugElement.nativeElement;
const image: HTMLImageElement = compiled.querySelector('div img');
expect(image).toBeTruthy();
expect(image.alt).toBe('Susper');
});
it('should have an element app-search-bar', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-search-bar')).toBeTruthy();
});
it('should have set-susper-default option', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div #set-susper-default')).toBeTruthy();
});
it('should have an app-footer-navbar element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-footer-navbar')).toBeTruthy();
});
it('should have an app-dropdown element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-dropdown')).toBeTruthy();
});
it('should have an app-search-bar element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-search-bar')).toBeTruthy();
});
});

View file

@ -35,12 +35,10 @@
top: 50%;
z-index: 1002;
background-color: #fefefe;
padding: 2em;
font-size: 1.1em;
border-radius: 4px;
border: 1px solid #888;
width: 324px;
height: 300px;
border-radius: 8px;
width: 268px;
height: auto;
}
.modal-container h1 {
@ -53,7 +51,7 @@
flex-direction: column;
}
.icon-container > * + * {
margin-top: 24px;
margin-top: 20px;
}
.icon-wrapper {
height: 38px;
@ -66,6 +64,20 @@
vertical-align: middle;
margin: 0px 0px 0px 16px;
}
div.share-link {
margin: 24px;
padding-top: 10px;
padding-bottom: 20px;
}
input#share_link {
width: 100%;
outline: 0;
border-width: 0 0 1px;
border-color: #999999;
}
input#share_link:focus {
border-bottom: 1px solid rgb(38, 84, 124);
}
.btn {
background: none;
@ -76,7 +88,7 @@
float: right;
font-size: 28px;
font-weight: bold;
margin: 24px 8px 24px 0px;
margin: 20px 24px 24px 0px;
}
.close:hover,
.close:focus {

View file

@ -32,11 +32,16 @@
</div></a
>
</div>
<div class="share-link">
<label for="share_link" style="color: #999999; margin-left: -6px;">Share link</label>
<br/>
<input type="text" id="share_link" value="{{ getUrl() }}">
</div>
</div>
</div>
<h2>
<b [style.color]="themeService.cardColor">{{ this.title }}</b
><button class="btn dropdown-toggle" type="button" (click)="ShowModal()">
><button class="btn dropdown-toggle" id="showSearchModal" type="button" (click)="ShowModal()">
<i class="material-icons">share</i>
</button>
</h2>
@ -47,8 +52,10 @@
<div class="info-img"><img class="main_image" *ngIf="this.image" src="{{this.image}}" /></div>
<p [style.color]="themeService.descriptionColor">
{{ this.description }}
<br />
More at
<a [style.color]="themeService.linkColor" href="https://en.wikipedia.org/wiki/{{this.title}}">
<br />More at Wikipedia</a
<br />Wikipedia</a
>
<br />
<a href="https://twitter.com/search?src=typd&q={{this.title}}">

View file

@ -8,6 +8,8 @@ import { reducer } from "../reducers/index";
import { StoreModule } from "@ngrx/store";
import { MockKnowledgeApi } from "../shared/mocks/knowledge.mock";
import { SpeechSynthesisService } from '../services/speech-synthesis.service';
import { By } from '@angular/platform-browser';
describe('Component: InfoboxComponent', () => {
let component: InfoboxComponent;
let fixture: ComponentFixture<InfoboxComponent>;
@ -55,4 +57,14 @@ describe('Component: InfoboxComponent', () => {
expect(component.image_response$).toBeTruthy();
});
it('should have resultsearch variable equal to "/search"', () => {
expect(component.resultsearch).toEqual('/search');
});
it('should not have card', () => {
const compiled = fixture.debugElement.nativeElement;
expect(fixture.debugElement.query(By.css('div.card'))).toBeNull();
});
});

View file

@ -83,6 +83,9 @@ export class InfoboxComponent implements OnInit {
closeModal() {
this.isModalOpen = false;
}
getUrl() {
(<HTMLInputElement>document.getElementById('share_link')).value = document.URL;
}
ngOnInit() {}
}

View file

@ -45,4 +45,12 @@ describe('IntelligenceComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
it('should have wholequery$ observables', () => {
expect(component.wholequery$).toBeTruthy();
});
it('should have resultscomponentchange$ observables', () => {
expect(component.resultscomponentchange$).toBeTruthy();
});
});

View file

@ -1,8 +1,8 @@
.navbar-brand {
width: 140px;
height: auto;
padding: 15px 15px 0px 15px;
margin-right: 26px;
width: 140px;
height: auto;
padding: 15px 15px 0px 15px;
margin-right: 26px;
}
#navbar-header {
@ -23,12 +23,14 @@
}
.navbar-default {
background-color: #fafafa;
background-color: rgb(255, 255, 255);
border-bottom: none;
}
.top-nav {
margin-bottom: 0px;
position: sticky;
top: -10px;
}
#navcontainer {
@ -55,8 +57,8 @@
@media screen and (max-width:1079px) {
.navbar-brand{
margin-top: 2px;
width: 120px;
margin-top: 2px;
width: 120px;
}
#navbar-search{
@ -72,8 +74,8 @@
@media screen and (max-width:767px) {
.navbar-brand{
margin-left: 38%;
height: auto;
margin-left: 38%;
height: auto;
}
#navbar-search {
@ -115,7 +117,7 @@
@media screen and (max-width:479px) {
.navbar-brand{
margin-left: 33%;
margin-left: 33%;
}
#navbar-search {
@ -125,6 +127,11 @@
.align-navsearch-btn {
margin-right: 3% !important;
}
.top-nav {
position: inherit;
top: 0px;
}
}
@media screen and (max-width:379px) {

View file

@ -1,19 +1,16 @@
<nav class="top-nav navbar navbar-static-top navbar-default" [style.background-color]="themeService.navbarbgColor">
<div class="container-fluid">
<div class="navbar-header" id="navcontainer">
<a routerLink="/">
<img class="navbar-brand" src="assets/images/susper.svg" alt="brand">
</a>
<div id="navbar-search">
<div id="search-bar">
<app-search-bar></app-search-bar>
</div>
</div>
<div id="navbar-dropdown-box">
<app-dropdown></app-dropdown>
</div>
</div>
<nav
class="top-nav navbar navbar-static-top navbar-default"
[style.background-color]="themeService.navbarbgColor"
>
<div class="container-fluid">
<div class="navbar-header" id="navcontainer">
<a routerLink="/" (click)="clearSearch()">
<img class="navbar-brand" src="assets/images/susper.svg" alt="brand" />
</a>
<div id="navbar-search">
<div id="search-bar"><app-search-bar></app-search-bar></div>
</div>
<div id="navbar-dropdown-box"><app-dropdown></app-dropdown></div>
</div>
</div>
</nav>

View file

@ -1,5 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Component, Input, Output } from '@angular/core';
import { RouterTestingModule } from '@angular/router/testing';
import { NavbarComponent } from './navbar.component';
@ -67,23 +66,28 @@ describe('Component: Navbar', () => {
*/
it('should have an app-search-bar element', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-search-bar')).toBeTruthy();
});
it('should have alt text property as brand', () => {
let compiled = fixture.debugElement.nativeElement;
let image: HTMLImageElement = compiled.querySelector('div.navbar-header img');
const compiled = fixture.debugElement.nativeElement;
const image: HTMLImageElement = compiled.querySelector('div.navbar-header img');
expect(image).toBeTruthy();
expect(image.alt).toBe('brand');
});
it('should have an app-dropdown element', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-dropdown')).toBeTruthy();
});
it('should have an app-search-bar element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-search-bar')).toBeTruthy();
});
});

View file

@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ThemeService } from '../services/theme.service';
import { SearchBarComponent } from 'app/search-bar/search-bar.component';
@Component({
selector: 'app-navbar',
@ -8,7 +9,7 @@ import { ThemeService } from '../services/theme.service';
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
@ViewChild(SearchBarComponent) searchComponent: SearchBarComponent;
searchdata = {
query: '',
verify: false,
@ -26,14 +27,16 @@ export class NavbarComponent implements OnInit {
private route: ActivatedRoute,
private router: Router,
public themeService: ThemeService
) { }
) {}
ngOnInit() {
this.searchdata.timezoneOffset = new Date().getTimezoneOffset();
}
submit() {
this.router.navigate(['/search'], {queryParams: this.searchdata});
clearSearch() {
this.searchComponent.clearSearch();
}
submit() {
this.router.navigate(['/search'], { queryParams: this.searchdata });
}
}

View file

@ -11,7 +11,7 @@
}
.label-heading {
max-width: 23%;
padding: 5px;
}
.label-search {
@ -23,14 +23,19 @@
.container {
padding-left: 3.5%;
float: left;
width: 70%;
width: 100%;
}
.form-control {
width: 135%;
width: 100%;
border-radius: 0px;
}
#help-labels {
height: 34px;
line-height: 34px;
}
.navbar-nav > li > a {
text-align: left;
}
@ -73,7 +78,7 @@
.nav-terms {
padding: 0px;
clear: both;
margin: -57px 0 0 0
margin: -57px 0 0 0;
}
.advsearch-navbar{
@ -87,7 +92,7 @@
.nav-about {
clear: both;
margin: -57px 0 0 0
margin: -57px 0 0 0;
}
.navbar-logo {
@ -162,8 +167,12 @@ h2 {
}
div {
margin-top: 0.5%;
font-family: Arial,SansSerif;
font-family: Arial, Sans-Serif;
}
select {
background-color: rgb(245, 245, 245);
text-decoration-color:rgb(68, 68, 68);
}
@media only screen and (max-width: 500px) {
@ -193,10 +202,14 @@ div {
font-size: 20px;
}
.to-word-alignment {
margin-top: 10px;
.word-alignment {
font-size: 11px;
color: rgb(102, 102, 102);
display: inline-block;
vertical-align: middle;
line-height: normal;
}
.label:hover {
cursor: default;
cursor: pointer;
}

View file

@ -2,11 +2,10 @@
<div class="container-fluid">
<div class="navbar-header">
<button type = "button" class = "navbar-toggle"
data-toggle = "collapse" data-target = "#dropmenu">
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#dropmenu">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand advsearch-navbar" routerLink="/">
<img alt="brand" class="navbar-logo" src="../../assets/images/susper.svg">
@ -28,95 +27,186 @@
<div class="container">
<h3 class="advanced-search-heading">Advanced Search</h3>
<hr id="top-line">
<h3 class="label-heading">Find pages with...</h3>
<form>
<div class="row">
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="words">all these words:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="words"></div>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="exact">this exact word or phrase:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="exact"></div>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="any">any of these words:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="any"></div>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="none">none of these words:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="none"></div>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="number">numbers ranging from:</label></div>
<div class="col-md-2"><input type="text" class="form-control" id="number"></div>
<div class="col-md-2" style="text-align: center">
<label for="to" class="to-word-alignment">to</label>
</div>
<div class="col-md-2"><input type="text" class="form-control" id="to"></div>
</div>
<h3 class="label-heading">Find pages with...</h3>
<form>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="words">all these words:</label></div>
<div class="col-md-5"><input type="text" class="form-control" id="words"></div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Type the important words: tri-colour rat terrier
</span>
</div>
</form>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="exact">this exact word or phrase:</label></div>
<div class="col-md-5"><input type="text" class="form-control" id="exact"></div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Put exact words in quotes: "rat terrier"
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="any">any of these words:</label></div>
<div class="col-md-5"><input type="text" class="form-control" id="any"></div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Type OR between all the words you want: miniature OR standard
</span>
</div>
</div><br>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="none">none of these words:</label></div>
<div class="col-md-5"><input type="text" class="form-control" id="none"></div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Put a minus sign just before words that you don't want: -rodent, -"Jack Russell"
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="number">numbers ranging from:</label></div>
<div class="col-md-2"><input type="number" class="form-control" id="number"></div>
<div class="col-md-1" style="height:34px; line-height:34px; text-align: center;">
<label for="to" class="word-alignment" style="font-size: 12px !important; color: black !important;">to</label>
</div>
<div class="col-md-2"><input type="number" class="form-control" id="to"></div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Put two full stops between the numbers and add a unit of measurement: 10..35 kg, £300..£500, 2010..2011
</span>
</div>
</div>
</form>
<hr>
<h3 class="label-heading">Then narrow your results by...</h3>
<form>
<div class="row">
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="language">language:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="language" value="English" disabled></div>
<h3 class="label-heading">Then narrow your results by...</h3>
<form>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="language">language:</label></div>
<div class="col-md-5">
<select class="form-control" disabled>
<option value="English">English</option>
</select>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="region">region:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="region"></div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Find pages in the language that you select.
</span>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="last update">last update:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="last update"></div>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="site">site or domain:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="site"></div>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="terms appearing">terms appearing:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="terms appearing"></div>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="safe search">safe search:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="safe search"></div>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="file type">file type:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="file type"></div>
</div>
<div class="form-group">
<div class="col-md-4"><label class="label-search" for="usage rights">usage rights:</label></div>
<div class="col-md-6"><input type="text" class="form-control" id="usage rights"></div>
</div>
</div>
</form>
<div class="adv-submit">
<button class="adv-btn btn" style="margin-bottom:50px;"><span class="btn-text">Advanced Search</span></button>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="region">region:</label></div>
<div class="col-md-5">
<select class="form-control" disabled>
<option value="anyRegion">Any Region</option>
</select>
</div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Find pages published in a particular region
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="last update">last update:</label></div>
<div class="col-md-5">
<select class="form-control" disabled>
<option value="anyTime">Any Time</option>
</select>
</div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Find pages updated within the time that you specify
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="site">site or domain:</label></div>
<div class="col-md-5"><input type="text" class="form-control" id="site"></div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Search one site (like wikipedia.org ) or limit your results to a domain like .edu, .org or .gov
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="terms appearing">terms appearing:</label></div>
<div class="col-md-5">
<select class="form-control" disabled>
<option value="anywhere">Anywhere in the page</option>
</select>
</div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Search for terms in the whole page, page title or web address, or links to the page you're looking for.
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="safe search">safe search:</label></div>
<div class="col-md-5">
<select class="form-control" disabled>
<option value="relevant">Show most relevant results</option>
</select>
</div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Tell SafeSearch whether to filter sexually explicit content
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="file type">file type:</label></div>
<div class="col-md-5">
<select class="form-control" disabled>
<option value="anyFormat">Any format</option>
</select>
</div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Find pages in the format that you prefer.
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"><label class="label-search" for="usage rights">usage rights:</label></div>
<div class="col-md-5">
<select class="form-control" disabled>
<option value="">Not filtered by license</option>
</select>
</div>
<div class="col-md-5" id="help-labels">
<span class="word-alignment">
Find pages that you are free to use yourself.
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2"></div>
<div class="col-md-5">
<div class="adv-submit">
<button class="adv-btn btn" style="margin-bottom:50px;"><span class="btn-text">Advanced Search</span></button>
</div>
</div>
<div class="col-md-5"></div>
</div>
</form>
</div>
<app-footer-navbar></app-footer-navbar>

View file

@ -26,4 +26,25 @@ describe('NewadvancedsearchComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
it('should have alt text property as brand', () => {
const compiled = fixture.debugElement.nativeElement;
const image: HTMLInputElement = compiled.querySelector('div.navbar-header img');
expect(image).toBeTruthy();
expect(image.alt).toBe('brand');
});
it('should have advanced-search-heading as Advanced Search', () => {
const compiled = fixture.debugElement.nativeElement;
const heading: HTMLInputElement = compiled.querySelector('h3.advanced-search-heading');
expect(heading.innerHTML).toContain('Advanced Search');
});
it('should have an app-footer-navbar element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-footer-navbar')).toBeTruthy();
});
});

View file

@ -4,6 +4,12 @@
}
}
nav.navbar {
position: fixed;
width: 100%;
z-index: 10;
}
.bold {
font-weight: 700;
}
@ -44,15 +50,13 @@
}
.link {
margin-top:2px;
margin-top:10px;
font-weight: 700;
line-height: 1.1;
color:#1565C0;
text-decoration: none;
}
.link:hover {
text-decoration: underline;
font-size: 20px;
padding-bottom: 20px;
padding-left: 40px;
}
#left {
@ -61,8 +65,39 @@
#right {
width:67.7%;
padding: 20px;
margin-bottom: 60px;
margin-left: 50px;
}
.wrapper{
position: fixed;
overflow-y: scroll;
bottom: 0;
top: 75px;
bottom:40px;
width: inherit;
}
.sidebar-list{
display: block;
list-style: none;
}
.sidebar-list>li{
font-size: 18px;
height: 100%;
padding-bottom: 20px;
cursor: pointer;
max-width: 100%;
overflow-x: hidden;
}
.sidebar-list>li.active{
color: #609;
}
.sidebar-list>li>a{
color: inherit;
text-decoration: none;
}
p {
@ -81,11 +116,25 @@ h2 {
#right {
width: 100%;
margin-left: 0px;
margin-top: 50px;
}
.navbar-brand {
margin-left: -77px;
margin-top: -9px;
.sidebar-list{
display: none;
}
.wrapper{
position: relative;
}
.navbar-brand {
margin-left: -77px;
margin-top: -9px;
}
.link {
padding-left: 0px;
}
}

View file

@ -25,82 +25,143 @@
</div>
</nav>
<div class="container">
<div class="row">
<div id="left" class="col-lg-4 col-md-3 col-sm-12">
<br><br><br>
<h2>Privacy Policy</h2>
<div class="wrapper">
<h3 class="link">Privacy Policy</h3>
<ul class="sidebar-list">
<li class="element1 active">
<a (click)="scrollTo('element1')">
Welcome to susper!
</a>
</li><br>
<li class="element2">
<a (click)="scrollTo('element2')">
Information Collection and Use
</a>
</li><br>
<li class="element3">
<a (click)="scrollTo('element3')">
Log Data
</a>
</li><br>
<li class="element4">
<a (click)="scrollTo('element4')">
Cookies
</a>
</li><br>
<li class="element5">
<a (click)="scrollTo('element5')">
Service Providers
</a>
</li><br>
<li class="element6">
<a (click)="scrollTo('element6')">
Security
</a>
</li><br>
<li class="element7">
<a (click)="scrollTo('element7')">
Links to Other Sites
</a>
</li><br>
<li class="element8">
<a (click)="scrollTo('element8')">
Childrens Privacy
</a>
</li><br>
<li class="element9">
<a (click)="scrollTo('element9')">
Changes to this Privacy Policy
</a>
</li>
</ul>
</div>
</div>
<div id = "right" class ="col-lg-8 col-md-9 col-sm-12">
<br><br>
<h2>Welcome to susper!</h2>
<div id="element1">
<h2>Welcome to susper!</h2>
<p>Thanks for using our products and services (“Services”). The Services are provided by FOSSASIA community, located at 93 Mau Than, Can Tho City, Viet Nam.
<p>Thanks for using our products and services (“Services”). The Services are provided by FOSSASIA community, located at 93 Mau Than, Can Tho City, Viet Nam.
<br><br>
By using our Services, you are agreeing to the Privacy Policy. Please read them carefully.
</p>
<p> FOSSASIA built the susper.com app as an Open Source app. This SERVICE is provided by FOSSASIA at no cost and is intended for use as is.
</p>
<p>This page is used to inform website visitors regarding our policies with the collection, use, and
</p>
<p> FOSSASIA built the susper.com app as an Open Source app. This SERVICE is provided by FOSSASIA at no cost and is intended for use as is.
</p>
<p>This page is used to inform website visitors regarding our policies with the collection, use, and
disclosure of Personal Information if anyone decided to use our Service.
</p>
<p>If you choose to use our Service, then you agree to the collection and use of information in relation
</p>
<p>If you choose to use our Service, then you agree to the collection and use of information in relation
to this policy. The Personal Information that we collect is used for providing and improving the
Service. We will not use or share your information with anyone except as described
in this Privacy Policy.
</p>
<p>The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at susper unless otherwise defined in this Privacy Policy.
</p>
</p>
<p>The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at susper unless otherwise defined in this Privacy Policy.
</p>
</div>
<h2>Information Collection and Use</h2>
<div id="element2">
<h2>Information Collection and Use</h2>
<p>For a better experience, while using our Service, we may require you to provide us with certain personally identifiable information. The information that we request is will be retained by us and used as described in this privacy policy.
</p>
<p>For a better experience, while using our Service, we may require you to provide us with certain personally identifiable information. The information that we request is will be retained by us and used as described in this privacy policy.
</p>
</div>
<h2>Log Data</h2>
<div id="element3">
<h2>Log Data</h2>
<p> We want to inform you that whenever you use our Service, in a case of an error in the app we collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address,device name, operating system version, the configuration of the app when utilizing our Service,the time and date of your use of the Service and other statistics.
</p>
<p> We want to inform you that whenever you use our Service, in a case of an error in the app we collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address,device name, operating system version, the configuration of the app when utilizing our Service,the time and date of your use of the Service and other statistics.
</p>
</div>
<h2>Cookies</h2>
<p>Cookies are files with small amount of data that is commonly used an anonymous unique identifier. These
<div id="element4">
<h2>Cookies</h2>
<p>Cookies are files with small amount of data that is commonly used an anonymous unique identifier. These
are sent to your browser from the website that you visit and are stored on your device internal memory.
</p>
<p>This Service does not use these “cookies” explicitly. However, the app may use third party code and libraries that use “cookies” to collection information and to improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service.
</p>
</p>
<p>This Service does not use these “cookies” explicitly. However, the app may use third party code and libraries that use “cookies” to collection information and to improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service.
</p>
</div>
<h2>Service Providers</h2>
<div id="element5">
<h2>Service Providers</h2>
<p> We may employ third-party companies and individuals due to the following reasons:</p>
<ul><li>To facilitate our Service;</li>
<li>To provide the Service on our behalf;</li>
<li>To perform Service-related services; or</li>
<li>To assist us in analyzing how our Service is used.</li>
</ul>
<p> We want to inform users of this Service that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose.
</p>
</div>
<p> We may employ third-party companies and individuals due to the following reasons:</p>
<ul><li>To facilitate our Service;</li>
<li>To provide the Service on our behalf;</li>
<li>To perform Service-related services; or</li>
<li>To assist us in analyzing how our Service is used.</li>
</ul>
<p> We want to inform users of this Service that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose.
</p>
<div id="element6">
<h2>Security</h2>
<p> We value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and we cannot guarantee its absolute security.
</p>
</div>
<h2>Security</h2>
<div id="element7">
<h2>Links to Other Sites</h2>
<p>This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by us. Therefore, we strongly advise you to review the Privacy Policy of these websites. We have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.
</p>
</div>
<p> We value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and we cannot guarantee its absolute security.
</p>
<div id="element8">
<h2>Childrens Privacy</h2>
<h2>Links to Other Sites</h2>
<p>These Services do not address anyone under the age of 13. We do not knowingly collect personally identifiable information from children under 13. In the case we discover that a child under 13 has provided us with personal information, we immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact us so that we will be able to do necessary actions.
</p>
</div>
<p>This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by us. Therefore, we strongly advise you to review the Privacy Policy of these websites. We have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.
</p>
<h2>Childrens Privacy</h2>
<p>These Services do not address anyone under the age of 13. We do not knowingly collect personally identifiable information from children under 13. In the case we discover that a child under 13 has provided us with personal information, we immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact us so that we will be able to do necessary actions.
</p>
<h2>Changes to this Privacy Policy</h2>
<p> We may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. We will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately after they are posted on this page.
</p>
<div id="element9">
<h2>Changes to this Privacy Policy</h2>
<p> We may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. We will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately after they are posted on this page.
</p>
</div>
<h2>Contact Us</h2>

View file

@ -1,5 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Component, Input, Output } from '@angular/core';
import { async, ComponentFixture, TestBed, tick } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
/**
@ -40,9 +39,56 @@ describe('Component: Privacy', () => {
expect(privacy).toBeTruthy();
});
it('should have alt text property as brand', () => {
let compiled = fixture.debugElement.nativeElement;
let image: HTMLImageElement = compiled.querySelector('div.navbar-header img');
expect(image).toBeTruthy();
expect(image.alt).toBe('brand');
});
it('should have a div with id left', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div#left'));
});
it('should have a div with id right', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div#right'));
});
it('should have a sidebar menu', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('ul.sidebar-list'));
});
it('should have an active list on sidebar menu', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('ul.sidebar-list li.active'));
});
it('should create a FooterNavbar Component', () => {
const footerNavbar = new FooterNavbarComponent();
expect(footerNavbar).toBeTruthy();
});
it('should have an app-footer-navbar element', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-footer-navbar')).toBeTruthy();
});
it('should scroll', async(() => {
let compiled = fixture.debugElement.nativeElement;
const element = compiled.querySelector('li.element4 a');
element.click();
fixture.whenStable().then(() => {
expect(compiled.querySelector('li.element4.active')).toBeTruthy();
});
}));
});

View file

@ -11,4 +11,18 @@ export class PrivacyComponent implements OnInit {
ngOnInit() {
}
scrollTo(el) {
let element = document.getElementById(el);
document.getElementsByClassName('active')[0].classList.remove('active');
document.getElementsByClassName(el)[0].classList.add('active');
const headerOffset = 25;
const elementPosition = element.offsetTop;
const offsetPosition = elementPosition - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
}
}

View file

@ -1,7 +1,6 @@
import { createSelector } from 'reselect';
import { ActionReducer } from '@ngrx/store';
import { environment } from '../../environments/environment';
import * as fromKnowledge from './knowledge';
/**
* The compose function is one of our most handy tools. In basic terms, you give
@ -30,7 +29,6 @@ import { storeFreeze } from 'ngrx-store-freeze';
*/
import { combineReducers } from '@ngrx/store';
/**
* Every reducer module's default export is the reducer function itself. In
* addition, each module should export a type or interface that describes
@ -40,6 +38,7 @@ import { combineReducers } from '@ngrx/store';
import * as fromSearch from './search';
import * as fromQuery from './query';
import * as fromSpeech from './speech';
import * as fromKnowledge from './knowledge';
/**
* As mentioned, we treat each reducer like a table in a database. This means
* our top level state interface is just a map of keys to inner state types.
@ -51,7 +50,6 @@ export interface State {
knowledge: fromKnowledge.State;
}
/**
* Because metareducers take a reducer function and return a new reducer,
* we can use our compose helper to chain them together. Here we are
@ -63,10 +61,15 @@ const reducers = {
search: fromSearch.reducer,
query: fromQuery.reducer,
speech: fromSpeech.reducer,
knowledge: fromKnowledge.reducer
knowledge: fromKnowledge.reducer,
};
const developmentReducer: ActionReducer<State> = compose(storeFreeze, combineReducers)(reducers);
const developmentReducer: ActionReducer<State> = compose(
storeFreeze,
combineReducers
)(reducers);
const productionReducer: ActionReducer<State> = combineReducers(reducers);
export function reducer(state: any, action: any) {
@ -81,14 +84,25 @@ export const getSearchState = (state: State) => state.search;
export const getQueryState = (state: State) => state.query;
export const getKnowledgeState = (state: State) => state.knowledge;
export const getSpeechState = (state: State) => state.speech;
export const getSearchResults = createSelector(getSearchState, fromSearch.getsearchresults);
export const getItems = createSelector(getSearchState, fromSearch.getItems);
export const getResponseTime = createSelector(getSearchState, fromSearch.getresponsetime);
export const getTotalResults = createSelector(getSearchState, fromSearch.getTotalResults);
export const getNavigation = createSelector(getSearchState, fromSearch.getNavigation);
export const getSearchStatus = createSelector(getSearchState, fromSearch.getSearchstatus);
export const getquery = createSelector(getQueryState, fromQuery.getpresentquery);
export const getKnowledgeContent = createSelector(getKnowledgeState, fromKnowledge.getContentResponse);
export const getKnowledgeImage = createSelector(getKnowledgeState, fromKnowledge.getImageResponse);
export const getDescription = createSelector(getKnowledgeState, fromKnowledge.getDescriptionResponse);
export const getwholequery = createSelector(getQueryState, fromQuery.getpresentwholequery);
export const getResponseTime = createSelector(getSearchState, fromSearch.getresponsetime);
export const getKnowledgeContent = createSelector(
getKnowledgeState,
fromKnowledge.getContentResponse
);
export const getKnowledgeImage = createSelector(getKnowledgeState, fromKnowledge.getImageResponse);
export const getDescription = createSelector(
getKnowledgeState,
fromKnowledge.getDescriptionResponse
);
export const getSpeechMode = createSelector(getSpeechState, fromSpeech.getspeechmode);

View file

@ -1,54 +1,51 @@
import { compose } from '@ngrx/core';
import { combineReducers } from '@ngrx/store';
import { ActionReducer, Action } from '@ngrx/store';
import { createSelector } from 'reselect';
import * as knowledge from '../actions/knowledge';
export const CONTENT_CHANGE = 'CONTENT_CHANGE';
export const IMAGE_CHANGE = 'IMAGE_CHANGE';
export interface State {
content_response: any,
image_response: any,
description_response: any
}
const initialState: State = {
const defaultState: State = {
content_response: {},
image_response: {},
description_response: {}
};
export function reducer(state: State = initialState, action: knowledge.Actions): State {
export function reducer(state: State = defaultState, action: knowledge.Actions): State {
switch (action.type) {
case knowledge.ActionTypes.CONTENT_CHANGE: {
const content_response = action.payload;
return Object.assign({}, state, {
return {
...state,
content_response: content_response,
image_response: state.image_response,
description_response: state.description_response
});
}
}
case knowledge.ActionTypes.IMAGE_CHANGE: {
const image_response = action.payload;
return Object.assign({}, state, {
return {
...state,
content_response: state.content_response,
image_response: image_response,
description_response: state.description_response
});
}
}
case knowledge.ActionTypes.DESCRIPTION_CHANGE: {
const description_response = action.payload;
return Object.assign({}, state, {
return {
...state,
content_response: state.content_response,
image_response: state.image_response,
description_response: description_response
});
}
}
default: {
return state;
}
}
}
export const getContentResponse = (state: State) => state.content_response;
export const getImageResponse = (state: State) => state.image_response;
export const getDescriptionResponse = (state: State) => state.description_response;

View file

@ -1,22 +1,11 @@
import { compose } from '@ngrx/core';
import { combineReducers } from '@ngrx/store';
import { ActionReducer, Action } from '@ngrx/store';
import { createSelector } from 'reselect';
import * as query from '../actions/query';
export const CHANGE = 'CHANGE';
export interface State {
query: string;
wholequery: any;
}
/**
* There is always a need of initial state to be passed onto the store.
*
* @prop: query: ''
* @prop: loading: false
*/
const initialState: State = {
const defaultState: State = {
query: '',
wholequery: {
query: '',
@ -26,18 +15,19 @@ const initialState: State = {
},
};
export function reducer(state: State = initialState, action: query.Actions): State {
export function reducer(state: State = defaultState, action: query.Actions): State {
switch (action.type) {
case query.ActionTypes.QUERYCHANGE: {
const changeQuery = action.payload;
return Object.assign({}, state, {
return {
...state,
query: changeQuery,
wholequery: state.wholequery
});
}
}
case query.ActionTypes.QUERYSERVER: {
let serverQuery = Object.assign({}, action.payload);
let serverQuery = {...action.payload};
let resultCount = 10;
if (localStorage.getItem('resultscount')) {
@ -51,10 +41,11 @@ export function reducer(state: State = initialState, action: query.Actions): Sta
}
serverQuery.rows = resultCount;
return Object.assign({}, state, {
return {
...state,
wholequery: serverQuery,
query: state.query
});
}
}
default: {
return state;

View file

@ -1,54 +1,54 @@
import { compose } from '@ngrx/core';
import { combineReducers } from '@ngrx/store';
import { ActionReducer, Action } from '@ngrx/store';
import { createSelector } from 'reselect';
import * as search from '../actions/search';
export const CHANGE = 'CHANGE';
export interface State {
searchresults: any;
items: any;
totalResults: any;
navigation: any;
responsetime: any;
loading: boolean;
}
/**
* There is always a need of initial state to be passed onto the store.
*
* @prop: query: ''
* @prop: loading: false
*/
const initialState: State = {
const defaultState: State = {
searchresults: {},
items: [],
totalResults: 0,
navigation: [],
responsetime: 0
responsetime: 0,
loading: false,
};
export function reducer(state: State = initialState, action: search.Actions): State {
export function reducer(state: State = defaultState, action: search.Actions): State {
switch (action.type) {
case search.ActionTypes.CHANGE: {
const changeSearch = action.payload.response;
const append = action.payload.append;
if (append) {
const newitems = state.items.concat(changeSearch.channels[0].items);
return Object.assign({}, state, {
searchresults: search,
items: newitems,
totalResults: Number(changeSearch.channels[0].totalResults) || 0,
navigation: changeSearch.channels[0].navigation,
responsetime: new Date()
});
const {response, append, loading} = action.payload;
if (!loading) {
if (append) {
const newitems = state.items.concat(response.channels[0].items);
return {
...state,
searchresults: search,
items: newitems,
totalResults: Number(response.channels[0].totalResults) || 0,
navigation: response.channels[0].navigation,
responsetime: new Date(),
loading: loading,
}
} else {
return {
...state,
searchresults: response,
items: response.channels[0].items,
totalResults: Number(response.channels[0].totalResults) || 0,
navigation: response.channels[0].navigation,
responsetime: new Date(),
loading: loading,
}
}
} else {
return Object.assign({}, state, {
searchresults: changeSearch,
items: changeSearch.channels[0].items,
totalResults: Number(changeSearch.channels[0].totalResults) || 0,
navigation: changeSearch.channels[0].navigation,
responsetime: new Date()
});
return {
...state, loading: true
}
}
}
default: {
@ -62,3 +62,4 @@ export const getItems = (state: State) => state.items;
export const getTotalResults = (state: State) => state.totalResults;
export const getresponsetime = (state: State) => state.responsetime;
export const getNavigation = (state: State) => state.navigation;
export const getSearchstatus = (state: State) => state.loading;

View file

@ -1,31 +1,21 @@
import { compose } from '@ngrx/core';
import { combineReducers } from '@ngrx/store';
import { ActionReducer, Action } from '@ngrx/store';
import { createSelector } from 'reselect';
import * as speech from '../actions/speech';
export const CHANGE = 'CHANGE';
export interface State {
speechmode: boolean;
}
/**
* There is always a need of initial state to be passed onto the store.
*
* @prop: query: ''
* @prop: loading: false
*/
const initialState: State = {
const defaultState: State = {
speechmode: false
};
export function reducer(state: State = initialState, action: speech.Actions): State {
export function reducer(state: State = defaultState, action: speech.Actions): State {
switch (action.type) {
case speech.ActionTypes.CHANGE: {
const response = action.payload;
return Object.assign({}, state, {
return {
...state,
speechmode: response,
});
}
}
default: {
return state;

View file

@ -18,8 +18,8 @@
overflow: hidden !important;
text-overflow: ellipsis;
}
.infobox{
float:left;
.infobox {
float: left;
margin-right: 15px;
}
@ -129,11 +129,11 @@ a {
line-height: 18px;
}
.apidata_large{
float:left;
.apidata_large {
float: left;
}
.apidata_small{
.apidata_small {
margin-left: 4%;
margin-bottom: 4px;
}
@ -149,7 +149,8 @@ a {
font-family: 'Roboto', sans-serif;
}
.prev, .next {
.prev,
.next {
color: #7f7f7f;
}
.page-number {
@ -167,7 +168,7 @@ a {
padding: 10px;
padding-right: 20px;
padding-left: 20px;
background-color: rgba(0,0,0,0.1);
background-color: rgba(0, 0, 0, 0.1);
}
.dropdown-menu > li:active {
@ -215,7 +216,7 @@ a {
/** END **/
#search-options-field {
background-color: #fafafa;
background-color: rgb(255, 255, 255);
padding-bottom: 3px;
}
@ -225,6 +226,10 @@ a {
vertical-align: middle;
}
hr {
margin-top: 0px;
}
#search-options {
margin-top: 0.5%;
margin-left: 155px;
@ -333,7 +338,8 @@ a {
margin-bottom: 100px;
}
.pagination>li>span.active_page,.pagination>li>span>div.page-text.active_page{
.pagination > li > span.active_page,
.pagination > li > span > div.page-text.active_page {
color: #7f7f7f;
}
@ -343,12 +349,12 @@ a {
}
.page-item span {
border: 0 ;
font-size: 13px;
border: 0;
font-size: 13px;
}
.page-item span {
padding: 6px 0.4px ;
padding: 6px 0.4px;
}
.clean {
@ -363,26 +369,26 @@ a {
border: 1px solid #f2f2f2;
border-radius: 2px;
color: #757575;
font-family: arial,sans-serif;
font-family: arial, sans-serif;
font-size: 13px;
font-weight: bold;
margin-bottom: 4px;
min-width: 54px;
padding: 0 16px;
text-align: center;
outline-color:#4170c6;
}
outline-color: #4170c6;
}
#toggle-button:hover {
background-image: -webkit-gradient(linear,left top,left bottom,from(#f8f8f8),to(#f1f1f1));
background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f1f1f1));
background-image: -webkit-linear-gradient(top, #f8f8f8, #f1f1f1);
background-color: #f8f8f8;
background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1);
background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1);
background-image: -o-linear-gradient(top, #f8f8f8, #f1f1f1);
background-image: -moz-linear-gradient(top, #f8f8f8, #f1f1f1);
border: 1px solid #c6c6c6;
box-shadow: 0 1px 1px rgba(0,0,0,0.1);
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
color: #222;
}
}
.noResults {
margin-left: 172px;
@ -391,20 +397,19 @@ a {
font-weight: normal;
}
.noResults >p {
.noResults > p {
margin-top: 10px;
margin-bottom: 15px;
}
.noResults >ul {
.noResults > ul {
padding-left: 16px;
}
.rss{
.rss {
padding: 0 0 0 0;
margin-right: 5px;
}
.noResults em {
font-weight: bold;
font-style: normal;
@ -413,38 +418,50 @@ a {
div.autocorrect {
margin-bottom: 7px;
margin-left: 172px;
height:5px;
height: 5px;
}
.intelligence{
.intelligence {
margin-top: 3%;
}
.loading-container {
width: 100%;
height: 86vh;
display: flex;
align-items: center;
justify-content: center;
}
/*Responsiveness*/
.loading-image {
height: 160px;
width: 160px;
}
/*Responsiveness*/
@media screen and (max-width: 811px) and (min-width: 768px) {
#settings{
#settings {
left: -15%;
}
#tools{
#tools {
left: -15%;
}
}
@media screen and (max-width: 767px) and (min-width: 736px) {
#settings{
#settings {
left: 5%;
}
#tools{
#tools {
left: 5%;
}
}
@media screen and (min-width: 1400px){
.infobox{
@media screen and (min-width: 1400px) {
.infobox {
float: left;
}
}
@media screen and (max-width: 735px) and (min-width: 640px) {
#tools{
#tools {
left: -5%;
}
}
@ -457,33 +474,33 @@ div.autocorrect {
left: 27%;
}
}
@media screen and (max-width: 890px) and (min-width: 768px){
@media screen and (max-width: 890px) and (min-width: 768px) {
#tool-dropdown {
margin-left: -121%;
min-width: 120px;
}
#setting-dropdown {
min-width: 100px!important;
margin-left: -60%!important;
}
min-width: 100px !important;
margin-left: -60% !important;
}
}
@media screen and (max-width: 735px) {
#tool-dropdown {
margin-left: -150%!important;
min-width: 100px!important;
margin-left: -150% !important;
min-width: 100px !important;
}
}
}
@media screen and (max-width: 560px) {
#tool-dropdown {
margin-left: 200%!important;
min-width: 100px!important;
margin-left: 200% !important;
min-width: 100px !important;
}
#setting-dropdown {
min-width: 100px!important;
margin-left: 200%!important;
min-width: 100px !important;
margin-left: 200% !important;
}
}
}
@media screen and (max-width: 495px) {
#settings {
@ -494,33 +511,33 @@ div.autocorrect {
}
#tool-dropdown {
right: 0;
margin-left: -150%!important;
min-width: 100px!important;
margin-left: -150% !important;
min-width: 100px !important;
}
#setting-dropdown {
min-width: 100px!important;
margin-left: 0%!important;
min-width: 100px !important;
margin-left: 0% !important;
}
}
}
@media screen and (max-width: 387px) {
@media screen and (max-width: 387px) {
#search-options li {
padding: 0 2vw 12px!important;
}
padding: 0 2vw 12px !important;
}
}
@media screen and (max-width: 327px) {
#search-options li {
padding: 0 1vw 12px!important;
}
#tool-dropdown {
margin-left: -200%!important;
}
}
@media screen and (max-width: 283px) {
#search-options li {
padding: 0 0vw 12px!important;
}
@media screen and (max-width: 327px) {
#search-options li {
padding: 0 1vw 12px !important;
}
#tool-dropdown {
margin-left: -200% !important;
}
}
@media screen and (max-width: 283px) {
#search-options li {
padding: 0 0vw 12px !important;
}
}
@media screen and (min-width: 426px) and (max-width: 2560px) {
.next-page-mobile {
@ -528,7 +545,7 @@ div.autocorrect {
}
}
@media screen and (min-width:1920px) {
@media screen and (min-width: 1920px) {
div.autocorrect {
margin-left: 191px;
}
@ -537,7 +554,7 @@ div.autocorrect {
margin-left: 191px;
}
div.feed{
div.feed {
margin-left: 191px;
}
@ -545,21 +562,21 @@ div.autocorrect {
margin-left: 191px;
}
#search-options{
#search-options {
margin-left: 174px;
}
}
@media screen and (max-width:1159px){
@media screen and (max-width: 1159px) {
.infobox {
display: none;
}
.apidata_large{
.apidata_large {
display: none;
}
}
@media screen and (max-width:1079px) {
@media screen and (max-width: 1079px) {
div.autocorrect {
margin-left: 134px;
}
@ -585,121 +602,121 @@ div.autocorrect {
div.combo-box {
display: none;
}
.apidata_small{
.apidata_small {
display: none;
}
}
@media screen and (max-width: 1159px) and (min-width: 768px){
.intelligence{
@media screen and (max-width: 1159px) and (min-width: 768px) {
.intelligence {
margin-left: -4%;
}
}
@media screen and (max-width: 1159px) and (min-width: 1080px){
@media screen and (max-width: 1159px) and (min-width: 1080px) {
div.combo-box {
margin-left: 13%;
}
.result{
.result {
margin-left: -2%;
}
#toggle-button{
#toggle-button {
margin-left: 0%;
}
.apidata_small{
.apidata_small {
margin-left: 13%;
}
#result-message{
#result-message {
margin-left: 14%;
}
}
@media screen and (max-width: 1079px) and (min-width: 1001px){
@media screen and (max-width: 1079px) and (min-width: 1001px) {
div.combo-box {
margin-left: 10%;
}
.result{
.result {
margin-left: -2%;
}
#toggle-button{
#toggle-button {
margin-left: -0.5%;
}
.apidata_small{
.apidata_small {
margin-left: 10%;
}
#result-message{
#result-message {
margin-left: 12%;
}
}
@media screen and (max-width: 1000px) and (min-width: 960px){
@media screen and (max-width: 1000px) and (min-width: 960px) {
div.combo-box {
margin-left: 11%;
}
.result{
.result {
margin-left: -2%;
}
#toggle-button{
#toggle-button {
margin-left: 0%;
}
.apidata_small{
.apidata_small {
margin-left: 11%;
}
#result-message{
#result-message {
margin-left: 13%;
}
}
@media screen and (max-width: 960px) and (min-width: 931px){
@media screen and (max-width: 960px) and (min-width: 931px) {
div.combo-box {
margin-left: 11.2%;
}
.result{
.result {
margin-left: -2%;
}
#toggle-button{
#toggle-button {
margin-left: 0%;
}
.apidata_small{
.apidata_small {
margin-left: 11%;
}
#result-message{
#result-message {
margin-left: 13%;
}
}
@media screen and (max-width: 930px) and (min-width: 816px){
@media screen and (max-width: 930px) and (min-width: 816px) {
div.combo-box {
margin-left: 12.2%;
}
.result{
.result {
margin-left: -2%;
}
#toggle-button{
#toggle-button {
margin-left: 0%;
}
.apidata_small{
.apidata_small {
margin-left: 12%;
}
#result-message{
#result-message {
margin-left: 13.5%;
}
}
@media screen and (max-width: 815px) and (min-width: 768px){
@media screen and (max-width: 815px) and (min-width: 768px) {
div.combo-box {
margin-left: 14%;
}
.result{
.result {
margin-left: -2%;
}
#toggle-button{
#toggle-button {
margin-left: 1%;
}
.apidata_small{
.apidata_small {
margin-left: 15%;
}
#result-message{
#result-message {
margin-left: 14%;
}
}
@media screen and (max-width:767px) {
@media screen and (max-width: 767px) {
div.result {
padding-right: 30px;
}
@ -727,9 +744,9 @@ div.autocorrect {
padding: 0 2.3% 12px;
}
#search-options-field {
padding-top: 8%;
}
#search-options-field {
padding-top: 8%;
}
#setting-dropdown {
min-width: 100px;
@ -769,34 +786,34 @@ div.autocorrect {
}
}
@media screen and (max-width:639px) {
@media screen and (max-width: 639px) {
#search-options li {
padding: 0 1.5% 12px;
}
#tool-dropdown li {
padding-left: 0!important;
padding-right: 0!important;
padding-left: 0 !important;
padding-right: 0 !important;
}
}
@media screen and (max-width:560px) {
@media screen and (max-width: 560px) {
li.dropdown {
left:0;
left: 0;
}
#setting-dropdown li {
padding-left: 0!important;
padding-right: 0!important;
padding-left: 0 !important;
padding-right: 0 !important;
}
#tool-dropdown li {
padding-left: 0!important;
padding-right: 0!important;
padding-left: 0 !important;
padding-right: 0 !important;
}
}
@media screen and (max-width:495px) {
@media screen and (max-width: 495px) {
.result {
padding-right: 20px;
}
@ -824,7 +841,7 @@ div.autocorrect {
}
}
@media screen and (max-width:425px) {
@media screen and (max-width: 425px) {
#pag-bar {
padding-left: 0;
}
@ -890,7 +907,7 @@ div.autocorrect {
margin-top: 1.1%;
}
}
@media screen and (max-width:379px) {
@media screen and (max-width: 379px) {
#search-options li {
padding: 0 3vw 12px;
}
@ -904,7 +921,7 @@ div.autocorrect {
}
}
@media screen and (max-width:330px) {
@media screen and (max-width: 330px) {
#search-options li {
padding: 0 2vw 12px;
}

View file

@ -1,19 +1,109 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
/>
<div class="resultContainer">
<app-navbar></app-navbar>
<div class="row" [style.background-color]="themeService.backgroundColor">
<div class="container-fluid" id="search-options-field" [style.background-color]="themeService.navbarbgColor">
<div
class="container-fluid"
id="search-options-field"
[style.background-color]="themeService.navbarbgColor"
[hidden]="hidefooter"
>
<ul type="none" id="search-options">
<a [routerLink]="['/search']" [queryParams]="{query:this.searchdata.query,start:this.searchdata.start,rows:this.searchdata.rows,resultDisplay:'all',mode:'text',nopagechange:'false',append:'false'}" [hidden]="this.resultDisplay==='all'"><li [class.active_view]="Display('all')" (click)="docClick()">All</li></a>
<li [class.active_view]="Display('all')" (click)="docClick()" *ngIf="Display('all')">All</li>
<a [routerLink]="['/search']" [queryParams]="{query:this.searchdata.query,start:this.searchdata.start,rows:this.searchdata.rows,mode:'text',nopagechange:'false',append:'false',fq:'url_file_ext_s%3A(png%2BOR%2Bjpeg%2BOR%2Bjpg%2BOR%2Bgif)',resultDisplay:'images'}" [hidden]="this.resultDisplay==='images'"><li [class.active_view]="Display('images')" (click)="imageClick()">Images</li></a>
<li [class.active_view]="Display('images')" (click)="imageClick()" *ngIf="Display('images')">Images</li>
<a [routerLink]="['/search']" [queryParams]="{query:this.searchdata.query,start:this.searchdata.start,rows:this.searchdata.rows,resultDisplay:'videos',mode:'text',nopagechange:'false',append:'false',fq:'url_file_ext_s%3A(avi%2BOR%2Bmov%2BOR%2Bflv%2BOR%2Bmp4)'}" [hidden]="this.resultDisplay==='videos'"><li [class.active_view]="Display('videos')" (click)="videoClick()">Videos</li></a>
<li [class.active_view]="Display('videos')" (click)="videoClick()" *ngIf="Display('videos')">Videos</li>
<a [routerLink]="['/search']" [queryParams]="{query:this.searchdata.query,start:this.searchdata.start,rows:this.searchdata.rows,resultDisplay:'news',mode:'text',nopagechange:'false',append:'false'}" [hidden]="this.resultDisplay==='news'"><li [class.active_view]="Display('news')" (click)="newsClick()">News</li></a>
<li [class.active_view]="Display('news')" (click)="newsClick()" *ngIf="Display('news')">News</li>
<a
[routerLink]="['/search']"
[queryParams]="{
query: this.searchdata.query,
start: this.searchdata.start,
rows: this.searchdata.rows,
resultDisplay: 'all',
mode: 'text',
nopagechange: 'false',
append: 'false'
}"
[hidden]="this.resultDisplay === 'all'"
>
<li [class.active_view]="Display('all')" (click)="docClick()">All</li>
</a>
<li [class.active_view]="Display('all')" (click)="docClick()" *ngIf="Display('all')">
All
</li>
<a
[routerLink]="['/search']"
[queryParams]="{
query: this.searchdata.query,
start: this.searchdata.start,
rows: this.searchdata.rows,
mode: 'text',
nopagechange: 'false',
append: 'false',
fq: 'url_file_ext_s%3A(png%2BOR%2Bjpeg%2BOR%2Bjpg%2BOR%2Bgif)',
resultDisplay: 'images'
}"
[hidden]="this.resultDisplay === 'images'"
>
<li [class.active_view]="Display('images')" (click)="imageClick()">Images</li>
</a>
<li
[class.active_view]="Display('images')"
(click)="imageClick()"
*ngIf="Display('images')"
>
Images
</li>
<a
[routerLink]="['/search']"
[queryParams]="{
query: this.searchdata.query,
start: this.searchdata.start,
rows: this.searchdata.rows,
resultDisplay: 'videos',
mode: 'text',
nopagechange: 'false',
append: 'false',
fq: 'url_file_ext_s%3A(avi%2BOR%2Bmov%2BOR%2Bflv%2BOR%2Bmp4)'
}"
[hidden]="this.resultDisplay === 'videos'"
>
<li [class.active_view]="Display('videos')" (click)="videoClick()">Videos</li>
</a>
<li
[class.active_view]="Display('videos')"
(click)="videoClick()"
*ngIf="Display('videos')"
>
Videos
</li>
<a
[routerLink]="['/search']"
[queryParams]="{
query: this.searchdata.query,
start: this.searchdata.start,
rows: this.searchdata.rows,
resultDisplay: 'news',
mode: 'text',
nopagechange: 'false',
append: 'false'
}"
[hidden]="this.resultDisplay === 'news'"
>
<li [class.active_view]="Display('news')" (click)="newsClick()">News</li>
</a>
<li [class.active_view]="Display('news')" (click)="newsClick()" *ngIf="Display('news')">
News
</li>
<li class="dropdown">
<a href="#" id="settings" class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<a
href="#"
id="settings"
class="dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true"
>
Settings
</a>
<ul class="dropdown-menu" aria-labelledby="settings" id="setting-dropdown">
@ -22,7 +112,14 @@
</ul>
</li>
<li class="dropdown">
<a href="#" id="tools" class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<a
href="#"
id="tools"
class="dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true"
>
Tools
</a>
<ul class="dropdown-menu" aria-labelledby="tools" id="tool-dropdown">
@ -33,27 +130,37 @@
</li>
</ul>
</div>
<hr>
<!-- Loading animation -->
<div class="loading-container" *ngIf="loading">
<img class="loading-image" src="../../assets/images/loading.gif" />
</div>
<div [hidden]="hidefooter">
<!-- Basic results 'All' -->
<div class="container-fluid">
<div id="result-message" class="result message-bar" *ngIf="totalNumber > 0 && !Display('images') && !Display('news')">
{{message}}
<div
id="result-message"
class="result message-bar"
*ngIf="totalNumber > 0 && !Display('images') && !Display('news')"
>
{{ message }}
</div>
<div id="result-message" class="result message-bar" *ngIf="Display('news')">
<p *ngIf="totalNumber>0">About {{newsResults['totalNewsResults']}} results<br></p>
<div class="newsUrl">News tab shows results filtered according to news organizations. If you wish to propose or change this list, please check <a href="{{newsFileUrl}}">here</a></div>
</div>
<div class="autocorrect">
<app-auto-correct [hidden]="hideAutoCorrect"></app-auto-correct>
<p *ngIf="totalNumber > 0">About {{ newsResults['totalNewsResults'] }} results<br /></p>
<div class="newsUrl">
News tab shows results filtered according to news organizations. If you wish to propose
or change this list, please check <a href="{{ newsFileUrl }}">here</a>
</div>
</div>
</div>
<div class="text-result" *ngIf="Display('all')">
<div *ngIf="totalNumber < 1" class="container-fluid">
<div [style.color]="themeService.descriptionColor" class="noResults">
<p>Your search -
<em>{{searchdata.query}}</em> - did not match any documents.</p>
<p>
Your search - <em>{{ searchedquery }}</em> - did not match any documents.
</p>
<p>Suggestions:</p>
<ul>
<li>Make sure that all words are spelled correctly.</li>
@ -63,42 +170,70 @@
</div>
</div>
<div class="container-fluid">
<div class="autocorrect">
<app-auto-correct [hidden]="hideAutoCorrect"></app-auto-correct>
</div>
<div class="combo-box">
<div class="small-info">
<app-infobox></app-infobox>
</div>
<div class="small-info"><app-infobox></app-infobox></div>
</div>
<div class="feed">
<div class="intelligence">
<app-intelligence [hidden]="hideAutoCorrect || hideIntelligence"></app-intelligence>
</div>
<div class="intelligence">
<app-intelligence [hidden]="hideAutoCorrect || hideIntelligence"></app-intelligence>
</div>
<div class="result">
<div *ngFor="let item of items$|async" class="result">
<div *ngFor="let item of (items$ | async)" class="result">
<div class="title">
<a class="title-pointer" href="{{item.link}}" [style.color]="themeService.titleColor">{{item.title}}</a>
<a
class="title-pointer"
href="{{ item.link }}"
[style.color]="themeService.titleColor"
>{{ item.title }}</a
>
</div>
<div class="link">
<p [style.color]="themeService.linkColor">{{item.link}}</p>
<p [style.color]="themeService.linkColor">{{ item.link }}</p>
</div>
<div class="description">
<p [style.color]="themeService.descriptionColor">{{item.pubDate|date:'MMMM d, yyyy'}} - {{item.description}}</p>
<p [style.color]="themeService.descriptionColor">
{{ item.pubDate | date: 'MMMM d, yyyy' }} - {{ item.description }}
</p>
</div>
</div>
</div>
</div>
<div class="infobox">
<app-infobox [hidden]="hidefooter || hideAutoCorrect || totalNumber < 1" *ngIf="Display('all')"></app-infobox>
<app-statsbox [hidden]="hidefooter || hideAutoCorrect || totalNumber < 1" *ngIf="Display('all')"></app-statsbox>
<app-infobox
[hidden]="hidefooter || hideAutoCorrect || totalNumber < 1"
*ngIf="Display('all')"
></app-infobox>
<app-statsbox
[hidden]="hidefooter || hideAutoCorrect || totalNumber < 1"
*ngIf="Display('all')"
></app-statsbox>
<div class="apidata_large">
<a class="rss" href="https://yacy.searchlab.eu/solr/select?query={{searchdata.query}}&start={{searchdata.start}}&rows={{searchdata.rows}}&mode=text&callback=__ng_jsonp__.__req3.finished&facet=true&facet.mincount=1&facet.field=host_s&facet.field=url_protocol_s&facet.field=author_sxt&facet.field=collection_sxt" target="_blank">
<img src="assets/images/RssOrange.jpg"/>
<span><b>RSS</b></span>
<a
class="rss"
href="https://yacy.searchlab.eu/solr/select?query={{ searchdata.query }}&start={{
searchdata.start
}}&rows={{
searchdata.rows
}}&mode=text&callback=__ng_jsonp__.__req3.finished&facet=true&facet.mincount=1&facet.field=host_s&facet.field=url_protocol_s&facet.field=author_sxt&facet.field=collection_sxt"
target="_blank"
>
<img src="assets/images/RssOrange.jpg" /> <span><b>RSS</b></span>
</a>
<a class="json" href="https://yacy.searchlab.eu/solr/select?query={{searchdata.query}}&start={{searchdata.start}}&rows={{searchdata.rows}}&mode=text&wt=yjson&callback=__ng_jsonp__.__req3.finished&facet=true&facet.mincount=1&facet.field=host_s&facet.field=url_protocol_s&facet.field=author_sxt&facet.field=collection_sxt" target="_blank">
<img src="assets/images/JsonGreen.jpg"/>
<span><b>JSON</b></span>
<a
class="json"
href="https://yacy.searchlab.eu/solr/select?query={{ searchdata.query }}&start={{
searchdata.start
}}&rows={{
searchdata.rows
}}&mode=text&wt=yjson&callback=__ng_jsonp__.__req3.finished&facet=true&facet.mincount=1&facet.field=host_s&facet.field=url_protocol_s&facet.field=author_sxt&facet.field=collection_sxt"
target="_blank"
>
<img src="assets/images/JsonGreen.jpg" /> <span><b>JSON</b></span>
</a>
</div>
</div>
</div>
</div>
</div>
@ -108,8 +243,9 @@
<div *ngIf="Display('images')">
<div *ngIf="totalNumber < 1" class="container-fluid">
<div [style.color]="themeService.descriptionColor" class="noResults">
<p>Your search -
<em>{{searchdata.query}}</em> - did not match any images.</p>
<p>
Your search - <em>{{ searchedquery }}</em> - did not match any images.
</p>
<p>Suggestions:</p>
<ul>
<li>Make sure that all words are spelled correctly.</li>
@ -120,20 +256,32 @@
</div>
<div class="container">
<div class="search-results" infiniteScroll [infiniteScrollDistance]="2" [infiniteScrollThrottle]="300" (scrolled)="onScroll()">
</div>
<div
class="search-results"
infiniteScroll
[infiniteScrollDistance]="2"
[infiniteScrollThrottle]="300"
(scrolled)="onScroll()"
></div>
<div *ngIf="totalNumber > 0">
<div *ngFor="let item of items;let i = index">
<div *ngFor="let item of items; let i = index">
<div class="item">
<img src="{{item.image}}" height="200px" (click)="expandImage(i)" [ngClass]="'image'+i">
<img
src="{{ item.image }}"
height="200px"
(click)="expandImage(i)"
[ngClass]="'image' + i"
/>
</div>
<div class=" item image-viewer" *ngIf="expand && expandedrow === i">
<span class="helper"></span>
<img
[src]="items[expandedkey].image"
height="200px"
style="vertical-align: middle;"
/>
</div>
</div>
<div class=" item image-viewer" *ngIf="expand && expandedrow === i">
<span class="helper"></span>
<img [src]="items[expandedkey].image" height="200px" style="vertical-align: middle;">
</div>
</div>
</div>
</div>
</div>
@ -142,8 +290,9 @@
<div class="video-result" *ngIf="Display('videos')">
<div *ngIf="totalNumber < 1" class="container-fluid">
<div [style.color]="themeService.descriptionColor" class="noResults">
<p>Your search -
<em>{{searchdata.query}}</em> - did not match any videos.</p>
<p>
Your search - <em>{{ searchedquery }}</em> - did not match any videos.
</p>
<p>Suggestions:</p>
<ul>
<li>Make sure that all words are spelled correctly.</li>
@ -153,130 +302,211 @@
</div>
</div>
<div class="feed container">
<div *ngFor="let item of items$|async" class="result">
<div *ngFor="let item of (items$ | async)" class="result">
<div class="title">
<a class="title-pointer" href="{{item.link}}" [style.color]="themeService.titleColor">{{item.title}}</a>
<a
class="title-pointer"
href="{{ item.link }}"
[style.color]="themeService.titleColor"
>{{ item.title }}</a
>
</div>
<div class="link">
<p [style.color]="themeService.linkColor">{{item.link}}</p>
<p [style.color]="themeService.linkColor">{{ item.link }}</p>
</div>
<div class="description">
<p [style.color]="themeService.descriptionColor">{{item.pubDate|date:'MMMM d, yyyy'}} - {{item.description}}</p>
<p [style.color]="themeService.descriptionColor">
{{ item.pubDate | date: 'MMMM d, yyyy' }} - {{ item.description }}
</p>
</div>
</div>
</div>
</div>
<!--End-->
<!-- News section -->
<div class="news-result" *ngIf="Display('news')">
<div *ngIf="totalNumber < 1" class="container-fluid">
<div class="noResults">
<p>Your search -
<em>{{searchdata.query}}</em> - did not match any news.</p>
<p>Suggestions:</p>
<ul>
<li>Make sure that all words are spelled correctly.</li>
<li>Try different keywords.</li>
<li>Try more general keywords.</li>
</ul>
</div>
</div>
<div class="feed container">
<div *ngFor="let item of newsResponse" class="result">
<div class="title">
<a class="title-pointer" href="{{item.link}}" [style.color]="themeService.titleColor">{{item.title}}</a>
<!-- News section -->
<div class="news-result" *ngIf="Display('news')">
<div *ngIf="totalNumber < 1" class="container-fluid">
<div class="noResults">
<p>
Your search - <em>{{ searchedquery }}</em> - did not match any news.
</p>
<p>Suggestions:</p>
<ul>
<li>Make sure that all words are spelled correctly.</li>
<li>Try different keywords.</li>
<li>Try more general keywords.</li>
</ul>
</div>
</div>
<div class="link">
<p [style.color]="themeService.linkColor">{{item.link}}</p>
<div class="feed container">
<div *ngFor="let item of newsResponse" class="result">
<div class="title">
<a
class="title-pointer"
href="{{ item.link }}"
[style.color]="themeService.titleColor"
>{{ item.title }}</a
>
</div>
<div class="link">
<p [style.color]="themeService.linkColor">{{ item.link }}</p>
</div>
<div class="description">
<p [style.color]="themeService.descriptionColor">
{{ item.pubDate | date: 'MMMM d, yyyy' }} - {{ item.description }}
</p>
</div>
</div>
</div>
<div class="description">
<p [style.color]="themeService.descriptionColor">{{item.pubDate|date:'MMMM d, yyyy'}} - {{item.description}}</p>
</div>
</div>
</div>
</div>
<!-- END -->
<br>
<!-- END -->
<br />
<div class="clean"></div>
<div class="card" *ngIf="totalNumber > 0">
<div class="pagination-bar" *ngIf="!Display('images')">
<div class="pagination-property" *ngIf="noOfPages>1">
<nav aria-label="Page navigation" *ngIf="(items$ | async)?.length!=0">
<div class="col-md-10 col-md-offset-1 col-sm-10 col-sm-offset-1 col-lg-10 col-lg-offset-1">
<div class="pagination-property" *ngIf="noOfPages > 1">
<nav aria-label="Page navigation" *ngIf="(items$ | async)?.length != 0">
<div
class="col-md-10 col-md-offset-1 col-sm-10 col-sm-offset-1 col-lg-10 col-lg-offset-1"
>
<ul class="pagination" id="pag-bar">
<li class="page-item2">
<span [style.background-color]='themeService.backgroundColor' class="spl" id="left-arrow" (click)="decPresentPage()">
<div class="arrow" (click)="decreasePage()" [hidden]="getStyle(1)">
&lt;
</div>
<div class="side-text" [hidden]="getStyle(1)">Previous</div>
<div style="width:47px" [hidden]="!getStyle(1)"></div>
<span
[style.background-color]="themeService.backgroundColor"
class="spl"
id="left-arrow"
(click)="decPresentPage()"
>
<div class="arrow" (click)="decreasePage()" [hidden]="getStyle(1)">&lt;</div>
<div class="side-text" [hidden]="getStyle(1)">Previous</div>
<div style="width:47px" [hidden]="!getStyle(1)"></div>
</span>
</li>
<li class="page-item">
<span [style.background-color]='themeService.backgroundColor' class="page-link" href="#" (click)="decPresentPage()">
<span
[style.background-color]="themeService.backgroundColor"
class="page-link"
href="#"
(click)="decPresentPage()"
>
<div class="page-text prev">S</div>
<br/>
<br />
</span>
</li>
<li class="page-item" *ngFor="let num of getNumber(maxPage)">
<span [style.background-color]='themeService.backgroundColor' class="page-link" *ngIf="presentPage>=4 && presentPage-3+num<=noOfPages" [class.active_page]="getStyle(presentPage-3+num)"
(click)="getPresentPage(presentPage-3+num)" href="#">
<div [class.active_page]="getStyle(presentPage-3+num)" class="page-text">U</div>
<span class="page-number">{{presentPage-3+num}}</span>
<span
[style.background-color]="themeService.backgroundColor"
class="page-link"
*ngIf="presentPage >= 4 && presentPage - 3 + num <= noOfPages"
[class.active_page]="getStyle(presentPage - 3 + num)"
(click)="getPresentPage(presentPage - 3 + num)"
href="#"
>
<div [class.active_page]="getStyle(presentPage - 3 + num)" class="page-text">
U
</div>
<span class="page-number">{{ presentPage - 3 + num }}</span>
</span>
<span [style.background-color]='themeService.backgroundColor' class="page-link" *ngIf="presentPage<4 && num<=noOfPages" [class.active_page]="num+1 == presentPage" (click)="getPresentPage(num+1)"
href="#">
<div [class.active_page]="num+1 == presentPage" class="page-text">U</div>
<span class="page-number">{{num+1}}</span>
<span
[style.background-color]="themeService.backgroundColor"
class="page-link"
*ngIf="presentPage < 4 && num <= noOfPages"
[class.active_page]="num + 1 == presentPage"
(click)="getPresentPage(num + 1)"
href="#"
>
<div [class.active_page]="num + 1 == presentPage" class="page-text">U</div>
<span class="page-number">{{ num + 1 }}</span>
</span>
</li>
<li class="page-item">
<span [style.background-color]='themeService.backgroundColor' class="page-link" (click)="incPresentPage()">
<span
[style.background-color]="themeService.backgroundColor"
class="page-link"
(click)="incPresentPage()"
>
<div class="page-text next">SPER</div>
</span>
</li>
<div class="next-page-mobile">Page {{count}}</div>
<div class="next-page-mobile">Page {{ count }}</div>
<li class="page-item3" *ngIf="!getStyle(noOfPages)">
<span [style.background-color]='themeService.backgroundColor' class="spl" (click)="incPresentPage()">
<span
[style.background-color]="themeService.backgroundColor"
class="spl"
(click)="incPresentPage()"
>
<div class="arrow" (click)="increasePage()">&gt;</div>
<div class="side-text">Next</div>
</span>
</li>
</ul>
</div>
</div>
</nav>
</div>
</div>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<app-advancedsearch></app-advancedsearch>
</div>
<div class="modal fade" id="customization" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<app-theme></app-theme>
</div>
</div>
<div
class="modal fade"
id="myModal"
tabindex="-1"
role="dialog"
aria-labelledby="myModalLabel"
>
<app-advancedsearch></app-advancedsearch>
</div>
<div
class="modal fade"
id="customization"
tabindex="-1"
role="dialog"
aria-labelledby="myModalLabel"
>
<app-theme></app-theme>
</div>
<!--footer navigation bar goes here-->
</div>
<!--footer navigation bar goes here-->
</div>
<div class="combo-box">
<button class="btn" id="toggle-button" (click)="BoxToggle()" type="button" data-toggle="collapse" data-target="#statbox"
aria-expanded="false" aria-controls="collapseExample" *ngIf="totalNumber > 0">
{{boxMessage}} Analytics
</button>
<app-statsbox class="collapse" id="statbox"></app-statsbox>
</div>
<div class="apidata_small">
<a class="rss" href="https://{{yacyApiUrl}}/solr/select?query={{searchdata.query}}&start={{searchdata.start}}&rows={{searchdata.rows}}&mode=text&callback=__ng_jsonp__.__req3.finished&facet=true&facet.mincount=1&facet.field=host_s&facet.field=url_protocol_s&facet.field=author_sxt&facet.field=collection_sxt" target="_blank">
<img src="assets/images/RssOrange.jpg"/>
<b>RSS</b>
</a>
<a class="json" href="https://{{yacyApiUrl}}/solr/select?query={{searchdata.query}}&start={{searchdata.start}}&rows={{searchdata.rows}}&mode=text&wt=yjson&callback=__ng_jsonp__.__req3.finished&facet=true&facet.mincount=1&facet.field=host_s&facet.field=url_protocol_s&facet.field=author_sxt&facet.field=collection_sxt" target="_blank">
<img src="assets/images/JsonGreen.jpg"/>
<b>JSON</b>
</a>
</div>
<app-footer-navbar [hidden]="hidefooter"></app-footer-navbar>
</div>
<div class="combo-box">
<button
class="btn"
id="toggle-button"
(click)="BoxToggle()"
type="button"
data-toggle="collapse"
data-target="#statbox"
aria-expanded="false"
aria-controls="collapseExample"
*ngIf="totalNumber > 0"
>
{{ boxMessage }} Analytics
</button>
<app-statsbox class="collapse" id="statbox"></app-statsbox>
</div>
<div class="apidata_small">
<a
class="rss"
href="https://{{ yacyApiUrl }}/solr/select?query={{ searchdata.query }}&start={{
searchdata.start
}}&rows={{
searchdata.rows
}}&mode=text&callback=__ng_jsonp__.__req3.finished&facet=true&facet.mincount=1&facet.field=host_s&facet.field=url_protocol_s&facet.field=author_sxt&facet.field=collection_sxt"
target="_blank"
>
<img src="assets/images/RssOrange.jpg" /> <b>RSS</b>
</a>
<a
class="json"
href="https://{{ yacyApiUrl }}/solr/select?query={{ searchdata.query }}&start={{
searchdata.start
}}&rows={{
searchdata.rows
}}&mode=text&wt=yjson&callback=__ng_jsonp__.__req3.finished&facet=true&facet.mincount=1&facet.field=host_s&facet.field=url_protocol_s&facet.field=author_sxt&facet.field=collection_sxt"
target="_blank"
>
<img src="assets/images/JsonGreen.jpg" /> <b>JSON</b>
</a>
</div>
<app-footer-navbar [hidden]="hidefooter"></app-footer-navbar>
</div>

View file

@ -1,8 +1,6 @@
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By, BrowserModule } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ResultsComponent } from './results.component';
import { RouterTestingModule } from '@angular/router/testing';
import { CommonModule } from '@angular/common';
@ -21,23 +19,23 @@ import { FooterNavbarComponent } from '../footer-navbar/footer-navbar.component'
import { AboutComponent } from '../about/about.component';
import { ModalComponent, Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal';
import { ContactComponent } from '../contact/contact.component';
import { AutoCompleteComponent } from "../auto-complete/auto-complete.component";
import { AutocompleteService } from "../services/autocomplete.service";
import { AutoCompleteComponent } from '../auto-complete/auto-complete.component';
import { AutocompleteService } from '../services/autocomplete.service';
import { ThemeComponent } from '../theme/theme.component';
import { ThemeService } from '../services/theme.service';
import { SpeechService } from '../services/speech.service';
import { DropdownComponent } from '../dropdown/dropdown.component';
import { IntelligenceComponent } from "../intelligence/intelligence.component";
import { IntelligenceService } from "../services/intelligence.service";
import { SpeechtotextComponent } from "../speechtotext/speechtotext.component";
import { AutoCorrectComponent } from "../auto-correct/auto-correct.component";
import { StatsboxComponent } from "../statsbox/statsbox.component";
import { AutocorrectService } from "../services/autocorrect.service";
import { SpeechSynthesisService } from "../services/speech-synthesis.service";
import { InfiniteScrollModule } from "ngx-infinite-scroll";
import { ChartsModule } from "ng2-charts";
import { InfoboxComponent } from "../infobox/infobox.component";
import { KnowledgeapiService } from "../services/knowledgeapi.service";
import { IntelligenceComponent } from '../intelligence/intelligence.component';
import { IntelligenceService } from '../services/intelligence.service';
import { SpeechtotextComponent } from '../speechtotext/speechtotext.component';
import { AutoCorrectComponent } from '../auto-correct/auto-correct.component';
import { StatsboxComponent } from '../statsbox/statsbox.component';
import { AutocorrectService } from '../services/autocorrect.service';
import { SpeechSynthesisService } from '../services/speech-synthesis.service';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { ChartsModule } from 'ng2-charts';
import { InfoboxComponent } from '../infobox/infobox.component';
import { KnowledgeapiService } from '../services/knowledgeapi.service';
import { GetJsonService } from '../services/get-json.service';
import { NewsService } from '../services/news.service';
import { SearchService } from '../services/search.service';
@ -57,7 +55,7 @@ describe('ResultsComponent', () => {
JsonpModule,
ChartsModule,
StoreModule.provideStore(reducer),
StoreDevtoolsModule.instrumentOnlyWithExtension()
StoreDevtoolsModule.instrumentOnlyWithExtension(),
],
declarations: [
AppComponent,
@ -79,7 +77,7 @@ describe('ResultsComponent', () => {
SpeechtotextComponent,
AutoCorrectComponent,
StatsboxComponent,
InfoboxComponent
InfoboxComponent,
],
providers: [
SearchService,
@ -91,10 +89,9 @@ describe('ResultsComponent', () => {
SpeechSynthesisService,
KnowledgeapiService,
GetJsonService,
NewsService
]
})
.compileComponents();
NewsService,
],
}).compileComponents();
}));
beforeEach(() => {
@ -108,44 +105,42 @@ describe('ResultsComponent', () => {
});
it('should have an app-navbar element', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-navbar')).toBeTruthy();
});
it('should have an app-advancedsearch element', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-advancedsearch')).toBeTruthy();
});
it('should have an footer-navbar element', () => {
let compiled = fixture.debugElement.nativeElement;
it('should have an app-footer-navbar element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-footer-navbar')).toBeTruthy();
});
it('should have an app-theme element', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-theme')).toBeTruthy();
});
it('should have an app-infobox element', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-infobox')).toBeTruthy();
});
expect(compiled.querySelector('app-infobox')).toBeTruthy();
});
it('should have an app-infobox element', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-infobox')).toBeTruthy();
});
it('should have an app-auto-correct element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-auto-correct')).toBeTruthy();
});
it('should have an app-statsbox element', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-statsbox')).toBeTruthy();
});
it('should have a search options menu', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div#search-options-field ul#search-options'));
});
@ -154,22 +149,22 @@ describe('ResultsComponent', () => {
});
it('should have a tool drop-down menu', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('ul#tool-dropdown'));
});
it('should have a tool drop-down menu', () => {
let compiled = fixture.debugElement.nativeElement;
it('should have a tool setting-down menu', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('ul#setting-dropdown'));
});
it('should have a pagination bar', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div.pagination-bar'));
});
it('should have correctly related sub-components', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
if (component.resultDisplay.toLocaleLowerCase() === 'all') {
expect(compiled.querySelector('div.text-result div.title'));
expect(compiled.querySelector('div.text-result div.link'));
@ -189,12 +184,19 @@ describe('ResultsComponent', () => {
});
it('should have appropriate message', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
if (component.totalNumber < 1) {
expect(compiled.querySelector('div.noResults'));
} else if (component.totalNumber > 0) {
} else if (component.totalNumber > 0) {
expect(compiled.querySelector('div.message-bar'));
}
});
it('should change boxMessage value on clicking toggle', () => {
expect(component.boxMessage).toBe('Show');
component.BoxToggle();
expect(component.boxMessage).toBe('Hide');
component.BoxToggle();
expect(component.boxMessage).toBe('Show');
});
});

View file

@ -1,4 +1,5 @@
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { ThemeService } from '../services/theme.service';
import { Router, ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
@ -13,10 +14,11 @@ declare var $: any;
@Component({
selector: 'app-results',
templateUrl: './results.component.html',
styleUrls: ['./results.component.css']
styleUrls: ['./results.component.css'],
})
export class ResultsComponent implements OnInit {
items$: Observable<any>;
searchStatus$: Observable<any>;
totalResults$: Observable<number>;
responseTime$: Observable<any>;
resultDisplay: string;
@ -27,13 +29,14 @@ export class ResultsComponent implements OnInit {
end: number;
begin: number;
message: string;
searchedquery: string;
query: any;
count: number = 1;
boxMessage = 'Show';
newsResponse: Array<any>;
newsResults: object = {
totalNewsResults: 0,
count: 0
count: 0,
};
searchdata: any = {
query: '',
@ -44,6 +47,7 @@ export class ResultsComponent implements OnInit {
expandedkey: number;
querylook = {};
hidefooter = 1;
loading = 0;
hideAutoCorrect = 1;
totalNumber: number;
querychange$: Observable<any>;
@ -65,7 +69,7 @@ export class ResultsComponent implements OnInit {
result = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
}
return result;
};
}
getPresentPage(N) {
this.presentPage = N;
@ -76,18 +80,18 @@ export class ResultsComponent implements OnInit {
filterByDate() {
let urldata = Object.assign({}, this.searchdata);
urldata.query += urldata.query.substr(urldata.query.length - 6, 6) !== " /date" ? " /date" : "";
urldata.query += urldata.query.substr(urldata.query.length - 6, 6) !== ' /date' ? ' /date' : '';
this.store.dispatch(new queryactions.QueryServerAction(urldata));
}
filterByContext() {
let urldata = Object.assign({}, this.searchdata);
urldata.query = urldata.query.replace("/date", "");
urldata.query = urldata.query.replace('/date', '');
this.store.dispatch(new queryactions.QueryServerAction(urldata));
}
Display(S) {
return (this.resultDisplay === S);
return this.resultDisplay === S;
}
expandImage(key) {
@ -99,7 +103,7 @@ export class ResultsComponent implements OnInit {
let i = key;
let previouselementleft = 0;
while ( $('.image' + i) && $('.image' + i).offset().left > previouselementleft) {
while ($('.image' + i) && $('.image' + i).offset().left > previouselementleft) {
this.expandedrow = i;
previouselementleft = $('.image' + i).offset().left;
i = i + 1;
@ -136,7 +140,7 @@ export class ResultsComponent implements OnInit {
urldata.rows = 10;
urldata.resultDisplay = this.resultDisplay;
this.store.dispatch(new queryactions.QueryServerAction(urldata));
}
}
docClick() {
let urldata = Object.assign({}, this.searchdata);
@ -161,7 +165,7 @@ export class ResultsComponent implements OnInit {
}
getStyle(page) {
return ((this.presentPage) === page);
return this.presentPage === page;
}
constructor(
@ -169,13 +173,15 @@ export class ResultsComponent implements OnInit {
private activatedroute: ActivatedRoute,
private store: Store<fromRoot.State>,
private ref: ChangeDetectorRef,
private titleService: Title,
public themeService: ThemeService,
public getJsonService: GetJsonService,
public getNewsService: NewsService
) {
this.activatedroute.queryParams.subscribe(query => {
let urldata = Object.assign({}, this.searchdata);
this.setTitle(query['query'] + ' - Susper Search');
this.searchedquery = query['query'] ;
if (query['fq']) {
if (query['fq'].includes('png')) {
this.resultDisplay = 'images';
@ -217,25 +223,28 @@ export class ResultsComponent implements OnInit {
this.presentPage = Math.abs(query['start'] / urldata.rows) + 1;
let querydata = Object.assign({}, urldata);
this.store.dispatch(new queryactions.QueryServerAction(querydata));
this.getJsonService.getJSON().subscribe(res => { this.newsResponse = [];
for (let i = 0; i < res.newsOrgs.length; i++) {
this.getNewsService.getSearchResults(querydata, res.newsOrgs[i].provider).subscribe(
response => {
if (response.channels[0].items[0] !== undefined) {
this.getJsonService.getJSON().subscribe(res => {
this.newsResponse = [];
for (let i = 0; i < res.newsOrgs.length; i++) {
this.getNewsService
.getSearchResults(querydata, res.newsOrgs[i].provider)
.subscribe(response => {
if (response.channels[0].items[0] !== undefined) {
this.newsResponse.push(response.channels[0].items[0]);
}
if (response.channels[0].items[1] !== undefined) {
if (this.newsResults['count'] < 5) {
this.newsResults['totalNewsResults'] += parseInt(response.channels[0].totalResults, 10);
}
if (response.channels[0].items[1] !== undefined) {
if (this.newsResults['count'] < 5) {
this.newsResults['totalNewsResults'] += parseInt(
response.channels[0].totalResults,
10
);
this.newsResults['count']++;
}
this.newsResponse.push(response.channels[0].items[1]);
}
}
);
this.newsResponse.push(response.channels[0].items[1]);
}
});
}
});
});
if (this.presentPage === 1) {
this.hideAutoCorrect = 0;
@ -258,7 +267,7 @@ export class ResultsComponent implements OnInit {
this.searchresults$ = store.select(fromRoot.getSearchResults);
this.searchresults$.subscribe( searchresults => {
this.searchresults$.subscribe(searchresults => {
if (searchresults && searchresults.channels && searchresults.channels[0]) {
this.startindex = parseInt(searchresults.channels[0].startIndex, 10);
}
@ -293,20 +302,26 @@ export class ResultsComponent implements OnInit {
this.start = (this.presentPage - 1) * data.rows;
this.begin = this.start + 1;
});
this.searchStatus$ = store.select(fromRoot.getSearchStatus);
this.searchStatus$.subscribe(loading => {
this.loading = loading ? 1 : 0;
});
}
onScroll () {
onScroll() {
let urldata = Object.assign({}, this.searchdata);
this.getPresentPage(1);
this.resultDisplay = 'images';
urldata.start = (this.startindex) + urldata.rows;
urldata.start = this.startindex + urldata.rows;
urldata.fq = 'url_file_ext_s:(png+OR+jpeg+OR+jpg+OR+gif)';
urldata.resultDisplay = this.resultDisplay;
urldata.append = true;
urldata.nopagechange = true;
this.store.dispatch(new queryactions.QueryServerAction(urldata));
};
}
increasePage() {
this.count += 1;
@ -324,7 +339,9 @@ export class ResultsComponent implements OnInit {
}
}
ngOnInit() {
public setTitle( newTitle: string) {
this.titleService.setTitle( newTitle );
}
ngOnInit() {}
}

View file

@ -3,8 +3,8 @@
width: 632px;
color: black;
height: 44px;
border-radius: 0;
border: none;
border-radius: 25px;
border: 2px solid #609;
border-style: solid;
border-color:rgba(0, 0, 0, 0);
border-width: 0px;
@ -23,26 +23,26 @@
top: 4px;
color: black;
width: 536px;
height: 34px !important;
height: 44px !important;
line-height: 34px ;
border-radius: 0;
border: none;
border-radius: 25px;
border: 2px;
box-shadow: none;
padding-left: 16px;
font-family: Arial, sans-serif;
position: initial;
padding-top: 8px;
padding-top: 2px;
padding-bottom: 0px;
padding-right: 9px;
}
#nav-button {
border-radius: 0;
border-radius: 25px;
height: 38px;
background-color: white;
color: #0066ff;
box-shadow: none;
border: none;
border: 2px;
position: initial;
}
@ -51,12 +51,12 @@
}
#speech-button {
border-radius: 0;
border-radius: 25px;
height: 38px;
background-color: white;
color: #0066ff;
box-shadow: none;
border: none;
border: 2px;
position: initial;
}
@ -102,6 +102,7 @@
@media screen and (max-width: 767px) {
#nav-group {
width: 95vw!important;
top: -10px;
}
.align-search-btn{

View file

@ -1,6 +1,9 @@
import {
Component, OnInit, Input, Output, AfterContentInit, ContentChild,
AfterViewChecked, AfterViewInit, ViewChild, ViewChildren, ElementRef,
Component,
OnInit,
AfterViewInit,
ViewChildren,
ElementRef,
HostListener
} from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
@ -19,7 +22,8 @@ import { ThemeService } from '../services/theme.service';
styleUrls: ['./search-bar.component.css']
})
export class SearchBarComponent implements OnInit, AfterViewInit {
@ViewChildren('input') vc;
@ViewChildren('input')
vc;
query$: Observable<any>;
displayStatus: any;
@ -51,7 +55,7 @@ export class SearchBarComponent implements OnInit, AfterViewInit {
});
this.resultspage = this.router.url.toString().includes('/search');
};
}
speechRecognition() {
this.store.dispatch(new speechactions.SearchAction(true));
@ -68,14 +72,24 @@ export class SearchBarComponent implements OnInit, AfterViewInit {
onEnter(event: any) {
if (event.which === 13) {
if (this.searchdata.fq !== '') {
this.store.dispatch(new queryactions.QueryServerAction({'query': event.target.value, start: 0, rows: this.searchdata.rows, fq: this.searchdata.fq, mode: this.searchdata.mode}));
this.store.dispatch(
new queryactions.QueryServerAction({
query: event.target.value,
start: 0,
rows: this.searchdata.rows,
fq: this.searchdata.fq,
mode: this.searchdata.mode
})
);
} else {
this.store.dispatch(new queryactions.QueryServerAction({
'query': event.target.value,
start: 0,
rows: this.searchdata.rows,
mode: this.searchdata.mode
}));
this.store.dispatch(
new queryactions.QueryServerAction({
query: event.target.value,
start: 0,
rows: this.searchdata.rows,
mode: this.searchdata.mode
})
);
}
this.displayStatus = 'hidebox';
@ -94,14 +108,24 @@ export class SearchBarComponent implements OnInit, AfterViewInit {
onClick() {
if (this.searchdata.fq !== '') {
this.store.dispatch(new queryactions.QueryServerAction({'query': this.searchdata.query, start: 0, rows: this.searchdata.rows, fq: this.searchdata.fq, mode: this.searchdata.mode}));
this.store.dispatch(
new queryactions.QueryServerAction({
query: this.searchdata.query,
start: 0,
rows: this.searchdata.rows,
fq: this.searchdata.fq,
mode: this.searchdata.mode
})
);
} else {
this.store.dispatch(new queryactions.QueryServerAction({
'query': this.searchdata.query,
start: 0,
rows: this.searchdata.rows,
mode: this.searchdata.mode
}));
this.store.dispatch(
new queryactions.QueryServerAction({
query: this.searchdata.query,
start: 0,
rows: this.searchdata.rows,
mode: this.searchdata.mode
})
);
}
this.displayStatus = 'hidebox';
@ -109,7 +133,7 @@ export class SearchBarComponent implements OnInit, AfterViewInit {
}
ShowAuto() {
return (this.displayStatus === 'showbox');
return this.displayStatus === 'showbox';
}
ngOnInit() {
@ -119,12 +143,20 @@ export class SearchBarComponent implements OnInit, AfterViewInit {
ngAfterViewInit() {
this.vc.first.nativeElement.focus();
}
clearSearch() {
this.store.dispatch(
new queryactions.QueryServerAction({
query: ''
})
);
}
submit() {
if (this.searchdata.query.toString().length !== 0) {
if (!this.resultspage) {
this.router.navigate(['/search'], {queryParams: this.searchdata});
}
// if (!this.resultspage) {
// this.router.navigate(['/search'], {queryParams: this.searchdata});
// }
this.router.navigate(['/search'], { queryParams: this.searchdata });
}
}
}

View file

@ -18,8 +18,6 @@
position: relative;
}
.navbar-right {
border-top:none;
}
@ -31,7 +29,7 @@
.nav-terms {
padding: 0px;
clear: both;
margin: -57px 0 0 0
margin: -57px 0 0 0;
}
.advsearch-navbar {
@ -41,7 +39,7 @@
.nav-about {
clear: both;
margin: -57px 0 0 0
margin: -57px 0 0 0;
}
.navbar-logo {
@ -208,5 +206,9 @@ ul li{
}
.active {
color:#dd4b39
color:#dd4b39;
}
footer {
position: fixed;
}

View file

@ -48,32 +48,31 @@ describe('SearchsettingsComponent', () => {
});
it('should have an app-advancedsearch element', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-footer-navbar')).toBeTruthy();
});
it('should have a save button', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('button.savbtn'));
});
it('should have a cancel button', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('button.cancbtn'));
});
it('should have a navbar', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('nav.navbar'));
});
it('should have alt text property as brand', () => {
let compiled = fixture.debugElement.nativeElement;
const compiled = fixture.debugElement.nativeElement;
let image: HTMLImageElement = compiled.querySelector('a.navbar-brand img');
const image: HTMLImageElement = compiled.querySelector('a.navbar-brand img');
expect(image).toBeTruthy();
expect(image.alt).toBe('brand');
});

View file

@ -1,4 +1,3 @@
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { Injectable } from '@angular/core';
import {Http, URLSearchParams, Jsonp, Response, Headers, RequestOptions} from '@angular/http';
import 'rxjs/add/operator/map';
@ -6,8 +5,6 @@ import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/retry';
import {Store} from '@ngrx/store';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs/Rx';
import * as search from '../actions/search';
import * as fromRoot from '../reducers';
import { url } from '../../assets/url_configuration';

View file

@ -4,7 +4,6 @@ import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import { Store } from '@ngrx/store';
import * as fromRoot from '../reducers';
import * as search from '../actions/search';
import { Observable } from 'rxjs';
import { url } from '../../assets/url_configuration';
@Injectable()

View file

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { Http, URLSearchParams, Jsonp } from '@angular/http';
import { URLSearchParams, Jsonp } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import { Observable } from 'rxjs';

View file

@ -4,7 +4,6 @@ import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import { Store } from '@ngrx/store';
import * as fromRoot from '../reducers';
import * as search from '../actions/search';
import {Observable} from 'rxjs';
import { url } from '../../assets/url_configuration';
@Injectable()
@ -42,9 +41,7 @@ export class SearchService {
return this.jsonp
.get(this.searchUrl, {search: params}).map(res =>
res.json()[0]
).catch(this.handleError);
}

View file

@ -1,14 +1,27 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SpeechtotextComponent } from './speechtotext.component';
import { SpeechService } from "../services/speech.service";
import { StoreModule } from "@ngrx/store";
import { StoreModule, Store } from "@ngrx/store";
import { reducer } from "../reducers/index";
import * as fromRoot from '../reducers';
import { RouterTestingModule } from "@angular/router/testing";
describe('SpeechtotextComponent', () => {
let component: SpeechtotextComponent;
let fixture: ComponentFixture<SpeechtotextComponent>;
let message: any;
let ticks: any;
let timer: any;
let subscription: any;
let change: boolean;
let borderheight;
let borderwidth;
let buttoncolor;
let miccolor;
let resultspage: boolean;
let shadowleft: any;
let shadowtop: any;
let store: Store<fromRoot.State>;
beforeEach(async(() => {
TestBed.configureTestingModule({
@ -31,4 +44,93 @@ describe('SpeechtotextComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
it('should message speak now', () => {
message = component.message;
expect(message).toBe("Speak Now");
});
it('ticks should equal zero', () => {
ticks = component.ticks;
expect(ticks).toBe(0);
});
it('should have change to be false', () => {
change = component.change;
expect(change).toBe(false);
});
it('should have borderheight equal to zero', () => {
borderheight = component.borderheight;
expect(borderheight).toBe(0);
});
it('should have borderwidth equal to zero', () => {
borderwidth = component.borderwidth;
expect(borderwidth).toBe(0);
});
it('should have buttoncolor equal to #fff', () => {
buttoncolor = component.buttoncolor;
expect(buttoncolor).toBe('#fff');
});
it('should have miccolor equal to #f44', () => {
miccolor = component.miccolor;
expect(miccolor).toBe('#f44');
});
it('should have shadowleft equal to -69px or -103px', () => {
shadowleft = component.shadowleft;
resultspage = component.resultspage;
if (resultspage) {
expect(shadowleft).toBe('-103px');
} else {
expect(shadowleft).toBe('-69px');
}
});
it('should have shadowtop equal to -68px', () => {
shadowtop = component.shadowtop;
resultspage = component.resultspage;
if (resultspage) {
expect(shadowtop).toBe('-102px');
} else {
expect(shadowtop).toBe('-68px');
}
});
it('should call hidespeech function on div click', () => {
spyOn(component, 'hidespeech').and.callThrough();
const divelement = document.getElementById('spch');
divelement.click();
expect(component.hidespeech).toHaveBeenCalled();
});
it('close button should close speech', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div.close-button')).toBeTruthy();
})
// should call the ngOnInit........
it('should call functions after calling ngOnInit', () => {
component.ngOnInit();
if (ticks === 1) {
expect(component.message).toBe('Listening...');
} else if (ticks === 4) {
expect(component.message).toBe('Please check your microphone and audio levels.');
expect(component.miccolor).toBe('#C2C2C2');
} else if (ticks === 6) {
expect(component.subscription.unsubscribe()).toBeTruthy();
}
});
it('should call resettimer function', () => {
spyOn(component, 'resettimer');
component.onquery(event);
expect(component.resettimer).toHaveBeenCalled();
expect(component.message).toBe(event);
});
});

View file

@ -196,7 +196,7 @@ a {
@media screen and (max-width: 767px){
.card {
width: 95vw;
width: 90vw;
margin-left: 4vw;
}
}

View file

@ -4,6 +4,12 @@
}
}
nav.navbar {
position: fixed;
width: 100%;
z-index: 10;
}
.bold {
font-weight: 700;
}
@ -44,15 +50,13 @@
}
.link {
margin-top:2px;
margin-top:10px;
font-weight: 700;
line-height: 1.1;
color:#1565C0;
text-decoration: none !important;
}
.link:hover {
text-decoration: underline;
font-size: 20px;
padding-bottom: 20px;
padding-left: 40px;
}
#left {
@ -61,6 +65,39 @@
#right {
width:67.7%;
margin-left: 50px;
}
.wrapper{
position: fixed;
overflow-y: scroll;
bottom: 0;
top: 75px;
bottom:40px;
width: inherit;
}
.sidebar-list{
display: block;
list-style: none;
}
.sidebar-list>li{
font-size: 18px;
height: 100%;
padding-bottom: 20px;
cursor: pointer;
max-width: 100%;
overflow-x: hidden;
}
.sidebar-list>li.active{
color: #609;
}
.sidebar-list>li>a{
color: inherit;
text-decoration: none;
}
p {
@ -79,11 +116,25 @@ h2 {
#right {
width: 100%;
margin-left: 0px;
margin-top: 50px;
}
.navbar-brand {
margin-left: -77px;
margin-top: -9px;
.sidebar-list{
display: none;
}
.wrapper{
position: relative;
}
.navbar-brand {
margin-left: -77px;
margin-top: -9px;
}
.link {
padding-left: 0px;
}
}

View file

@ -2,12 +2,11 @@
<div class="container-fluid">
<div class="navbar-header">
<button type = "button" class = "navbar-toggle"
data-toggle = "collapse" data-target = "#dropmenu">
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
<span class = "icon-bar"></span>
</button>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#dropmenu">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand about-navbar" routerLink="/" title="Susper Search Engine">
<img alt="brand" class="navbar-logo" src="../../assets/images/susper.svg">
</a>
@ -15,7 +14,7 @@
<div class="collapse navbar-collapse" id="dropmenu">
<ul class="nav navbar-nav navbar-collapse navbar-right">
<li><a routerLink="/privacy">Privacy</a></li>
<li><a routerLink="/privacy">Privacy</a></li>
<li><a routerLink="/terms">Terms</a></li>
<li><a routerLink="/about">About</a></li>
<li><a routerLink="/contact">Contact</a></li>
@ -25,175 +24,354 @@
</div>
</nav>
<div class="container">
<div class="row">
<div id="left" class="col-lg-4 col-md-3 col-sm-12">
<br><br><br>
<h2>Terms of Service</h2>
<div class="wrapper">
<h3 class="link">Terms of Service</h3>
<ul class="sidebar-list">
<li class="element1 active">
<a (click)="scrollTo('element1')">
Welcome to susper!
</a>
</li><br>
<li class="element2">
<a (click)="scrollTo('element2')">
Using our Services
</a>
</li><br>
<li class="element3">
<a (click)="scrollTo('element3')">
Your susper Account
</a>
</li><br>
<li class="element4">
<a (click)="scrollTo('element4')">
Privacy and Copyright Protection
</a>
</li><br>
<li class="element5">
<a (click)="scrollTo('element5')">
Your Content in our Services
</a>
</li><br>
<li class="element6">
<a (click)="scrollTo('element6')">
About Software in our Services
</a>
</li><br>
<li class="element7">
<a (click)="scrollTo('element7')">
Modifying and Terminating our Services
</a>
</li><br>
<li class="element8">
<a (click)="scrollTo('element8')">
Our Warranties and Disclaimers
</a>
</li><br>
<li class="element9">
<a (click)="scrollTo('element9')">
Liability for our Services
</a>
</li><br>
<li class="element10">
<a (click)="scrollTo('element10')">
Business uses of our Services
</a>
</li><br>
<li class="element11">
<a (click)="scrollTo('element11')">
About these Terms
</a>
</li>
</ul>
</div>
</div>
<div id = "right"class ="col-lg-8 col-md-9 col-sm-12">
<div id="right" class="col-lg-8 col-md-9 col-sm-12">
<br><br>
<h2>Welcome to susper!</h2>
<p>Thanks for using our products and services (“Services”). The Services are provided by FOSSASIA community, located
at 93 Mau Than, Can Tho City, Viet Nam.
<br><br> By using our Services, you are agreeing to these terms. Please read them carefully.
</p>
<h2>Using our Services</h2>
<p>You must follow any policies made available to you within the Services.
<br><br> Dont misuse our Services. For example, dont interfere with our Services or try to access them using
a method other than the interface and the instructions that we provide. You may use our Services only as permitted
by law, including applicable export and re-export control laws and regulations. We may suspend or stop providing
our Services to you if you do not comply with our terms or policies or if we are investigating suspected misconduct.
<br><br> Using our Services does not give you ownership of any intellectual property rights in our Services or
the content you access. You may not use content from our Services unless you obtain permission from its owner
or are otherwise permitted by law. These terms do not grant you the right to use any branding or logos used in
our Services. Dont remove, obscure, or alter any legal notices displayed in or along with our Services.
<br><br> Our Services display some content that is not suspers. This content is the sole responsibility of the
entity that makes it available. We may review content to determine whether it is illegal or violates our policies,
and we may remove or refuse to display content that we reasonably believe violates our policies or the law. But
that does not necessarily mea.n that we review content, so please dont assume that we do.
<br><br> In connection with your use of the Services, we may send you service announcements, administrative messages,
and other information. You may opt out of some of those communications.
<br><br> Some of our Services are available on mobile devices. Do not use such Services in a way that distracts
you and prevents you from obeying traffic or safety laws.
<br><br>
</p>
<h2>Your susper Account</h2>
<p>
You may need a susper Account in order to use some of our Services. You may create your own susper Account, or your susper
Account may be assigned to you by an administrator, such as your employer or educational institution. If you
are using a susper Account assigned to you by an administrator, different or additional terms may apply and your
administrator may be able to access or disable your account.
<br><br> To protect your susper Account, keep your password confidential. You are responsible for the activity
that happens on or through your susper Account. Try not to reuse your susper Account password on third-party
applications. If you learn of any unauthorized use of your password or susper Account, change your password and
take measures to secure your account.
<br><br>
</p>
<h2>Privacy and Copyright Protection</h2>
<p>suspers privacy policies ensures that your personal data is safe and protected. By using our Services, you agree
that susper can use such data in accordance with our privacy policies.
<br><br> We respond to notices of alleged copyright infringement and terminate accounts of repeat infringers.
If you think somebody is violating your copyrights and want to notify us, you can find information about submitting
notices and suspers policy about responding to notices on our website.
<br><br>
</p>
<h2>Your Content in our Services</h2>
<p>Some of our Services allow you to upload, submit, store, send or receive content. You retain ownership of any intellectual
property rights that you hold in that content. In short, what belongs to you stays yours.
<br><br> When you upload, submit, store, send or receive content to or through our Services, you give susper
(and those we work with) a worldwide license to use, host, store, reproduce, modify, create derivative works
(such as those resulting from translations, adaptations or other changes we make so that your content works better
with our Services), communicate, publish, publicly perform, publicly display and distribute such content. The
rights you grant in this license are for the limited purpose of operating, promoting, and improving our Services,
and to develop new ones. This license continues even if you stop using our Services (for example, for a business
listing you have added to susper Maps). Some Services may offer you ways to access and remove content that has
been provided to that Service. Also, in some of our Services, there are terms or settings that narrow the scope
of our use of the content submitted in those Services. Make sure you have the necessary rights to grant this
license for any content that you submit to our Services.
<br><br> If you have a susper Account, we may display your Profile name, Profile photo, and actions you take
on susper or on third-party applications connected to your susper Account in our Services, including displaying
in ads and other commercial contexts. We will respect the choices you make to limit sharing or visibility settings
in your susper Account.
<br><br>
</p>
<h2>About Software in our Services</h2>
<p>When a Service requires or includes downloadable software, this software may update automatically on your device
once a new version or feature is available. Some Services may let you adjust your automatic update settings.
<br><br> susper gives you a personal, worldwide, royalty-free, non-assignable and non-exclusive license to use
the software provided to you by susper as part of the Services. This license is for the sole purpose of enabling
you to use and enjoy the benefit of the Services as provided by susper, in the manner permitted by these terms.
<br><br> Most of our services are offered through Free Software and/or Open Source Software. You may copy, modify,
distribute, sell, or lease these applications and share the source code of that software as stated in the License
agreement provided with the Software.
<br><br>
</p>
<h2>Modifying and Terminating our Services</h2>
<p>We are constantly changing and improving our Services. We may add or remove functionalities or features, and we may
suspend or stop a Service altogether.
<br><br> You can stop using our Services at any time. susper may also stop providing Services to you, or add
or create new limits to our Services at any time.
<br><br> We believe that you own your data and preserving your access to such data is important. If we discontinue
a Service, where reasonably possible, we will give you reasonable advance notice and a chance to get information
out of that Service.
<br><br>
</p>
<h2>Our Warranties and Disclaimers</h2>
<p>We provide our Services using a reasonable level of skill and care and we hope that you will enjoy using them. But
there are certain things that we dont promise about our Services.
<br><br> Other than as expressly set out in these terms or additional terms, neither susper nor its suppliers
or distributors make any specific promises about the Services. For example, we dont make any commitments about
the content within the Services, the specific functions of the Services, or their reliability, availability,
or ability to meet your needs. We provide the Services “as is”.
<br><br> Some jurisdictions provide for certain warranties, like the implied warranty of merchantability, fitness
for a particular purpose and non-infringement. To the extent permitted by law, we exclude all warranties.
<br><br>
</p>
<h2>Liability for our Services</h2>
<p>When permitted by law, susper, and suspers suppliers and distributors, will not be responsible for lost profits,
revenues, or data, financial losses or indirect, special, consequential, exemplary, or punitive damages.
<br><br> To the extent permitted by law, the total liability of susper, and its suppliers and distributors, for
any claims under these terms, including for any implied warranties, is limited to the amount you paid us to use
the Services (or, if we choose, to supplying you the Services again).
<br><br> In all cases, susper, and its suppliers and distributors, will not be liable for any loss or damage
that is not reasonably foreseeable.
<br><br> We recognize that in some countries, you might have legal rights as a consumer. If you are using the
Services for a personal purpose, then nothing in these terms or any additional terms limits any consumer legal
rights which may not be waived by contract.
<br><br>
</p>
<h2>Business uses of our Services</h2>
<p>If you are using our Services on behalf of a business, that business accepts these terms. It will hold harmless and
indemnify susper and its affiliates, officers, agents, and employees from any claim, suit or action arising from
or related to the use of the Services or violation of these terms, including any liability or expense arising
from claims, losses, damages, suits, judgments, litigation costs and attorneys fees.
<br><br>
<h2>About these Terms</h2>
<p>We may modify these terms or any additional terms that apply to a Service to, for example, reflect changes to
the law or changes to our Services. You should look at the terms regularly. Well post notice of modifications
to these terms on this page. Well post notice of modified additional terms in the applicable Service. Changes
will not apply retroactively and will become effective no sooner than fourteen days after they are posted.
However, changes addressing new functions for a Service or changes made for legal reasons will be effective
immediately. If you do not agree to the modified terms for a Service, you should discontinue your use of
that Service.
<br><br> If there is a conflict between these terms and the additional terms, the additional terms will control
for that conflict.
<br> These terms control the relationship between susper and you. They do not create any third party beneficiary
rights.
<br><br> If you do not comply with these terms, and we dont take action right away, this doesnt mean that
we are giving up any rights that we may have (such as taking action in the future).
<br><br> If it turns out that a particular term is not enforceable, this will not affect any other terms.<br><br> You agree that the laws of Can Tho, Viet Nam will apply to any disputes arising out of or relating to these
terms or the Services. All claims arising out of or relating to these terms or the services will be litigated
exclusively in the courts of Can Tho City, Viet Nam, and you and susper consent to personal jurisdiction
in those courts.
<br><br><div style="margin-bottom:50px;"> For information about how to contact susper, please visit our <a class="page-link" routerLink="/contact">contact page</a>.</div>
<div id="element1">
<h2>Welcome to susper!</h2>
<p>
Thanks for using our products and services (“Services”). The Services are provided by FOSSASIA
community,
located at 93 Mau Than, Can Tho City, Viet Nam.
<br><br> By using our Services, you are agreeing to these terms. Please read them carefully.
</p>
</div>
<div id="element2">
<h2>Using our Services</h2>
<p>You must follow any policies made available to you within the Services.
<br><br> Dont misuse our Services. For example, dont interfere with our Services or try to access
them using
a method other than the interface and the instructions that we provide. You may use our Services
only
as permitted
by law, including applicable export and re-export control laws and regulations. We may suspend or
stop
providing
our Services to you if you do not comply with our terms or policies or if we are investigating
suspected misconduct.
<br><br> Using our Services does not give you ownership of any intellectual property rights in our
Services or
the content you access. You may not use content from our Services unless you obtain permission from
its
owner
or are otherwise permitted by law. These terms do not grant you the right to use any branding or
logos
used in
our Services. Dont remove, obscure, or alter any legal notices displayed in or along with our
Services.
<br><br> Our Services display some content that is not suspers. This content is the sole
responsibility of the
entity that makes it available. We may review content to determine whether it is illegal or
violates
our policies,
and we may remove or refuse to display content that we reasonably believe violates our policies or
the
law. But
that does not necessarily mea.n that we review content, so please dont assume that we do.
<br><br> In connection with your use of the Services, we may send you service announcements,
administrative messages,
and other information. You may opt out of some of those communications.
<br><br> Some of our Services are available on mobile devices. Do not use such Services in a way
that
distracts
you and prevents you from obeying traffic or safety laws.
<br><br>
</p>
</div>
<div id="element3">
<h2>Your susper Account</h2>
<p>
You may need a susper Account in order to use some of our Services. You may create your own susper
Account, or your susper
Account may be assigned to you by an administrator, such as your employer or educational
institution.
If you
are using a susper Account assigned to you by an administrator, different or additional terms may
apply
and your
administrator may be able to access or disable your account.
<br><br> To protect your susper Account, keep your password confidential. You are responsible for
the
activity
that happens on or through your susper Account. Try not to reuse your susper Account password on
third-party
applications. If you learn of any unauthorized use of your password or susper Account, change your
password and
take measures to secure your account.
<br><br>
</p>
</div>
<div id="element4">
<h2>Privacy and Copyright Protection</h2>
<p>suspers privacy policies ensures that your personal data is safe and protected. By using our
Services,
you agree
that susper can use such data in accordance with our privacy policies.
<br><br> We respond to notices of alleged copyright infringement and terminate accounts of repeat
infringers.
If you think somebody is violating your copyrights and want to notify us, you can find information
about submitting
notices and suspers policy about responding to notices on our website.
<br><br>
</p>
</div>
<div id="element5">
<h2>Your Content in our Services</h2>
<p>Some of our Services allow you to upload, submit, store, send or receive content. You retain
ownership
of any intellectual
property rights that you hold in that content. In short, what belongs to you stays yours.
<br><br> When you upload, submit, store, send or receive content to or through our Services, you
give
susper
(and those we work with) a worldwide license to use, host, store, reproduce, modify, create
derivative
works
(such as those resulting from translations, adaptations or other changes we make so that your
content
works better
with our Services), communicate, publish, publicly perform, publicly display and distribute such
content. The
rights you grant in this license are for the limited purpose of operating, promoting, and improving
our
Services,
and to develop new ones. This license continues even if you stop using our Services (for example,
for a
business
listing you have added to susper Maps). Some Services may offer you ways to access and remove
content
that has
been provided to that Service. Also, in some of our Services, there are terms or settings that
narrow
the scope
of our use of the content submitted in those Services. Make sure you have the necessary rights to
grant
this
license for any content that you submit to our Services.
<br><br> If you have a susper Account, we may display your Profile name, Profile photo, and actions
you
take
on susper or on third-party applications connected to your susper Account in our Services,
including
displaying
in ads and other commercial contexts. We will respect the choices you make to limit sharing or
visibility settings
in your susper Account.
<br><br>
</p>
</div>
<div id="element6">
<h2>About Software in our Services</h2>
<p>When a Service requires or includes downloadable software, this software may update automatically on
your device
once a new version or feature is available. Some Services may let you adjust your automatic update
settings.
<br><br> susper gives you a personal, worldwide, royalty-free, non-assignable and non-exclusive
license
to use
the software provided to you by susper as part of the Services. This license is for the sole
purpose of
enabling
you to use and enjoy the benefit of the Services as provided by susper, in the manner permitted by
these terms.
<br><br> Most of our services are offered through Free Software and/or Open Source Software. You
may
copy, modify,
distribute, sell, or lease these applications and share the source code of that software as stated
in
the License
agreement provided with the Software.
<br><br>
</p>
</div>
<div id="element7">
<h2>Modifying and Terminating our Services</h2>
<p>We are constantly changing and improving our Services. We may add or remove functionalities or
features,
and we may
suspend or stop a Service altogether.
<br><br> You can stop using our Services at any time. susper may also stop providing Services to
you,
or add
or create new limits to our Services at any time.
<br><br> We believe that you own your data and preserving your access to such data is important. If
we
discontinue
a Service, where reasonably possible, we will give you reasonable advance notice and a chance to
get
information
out of that Service.
<br><br>
</p>
</div>
<div id="element8">
<h2>Our Warranties and Disclaimers</h2>
<p>We provide our Services using a reasonable level of skill and care and we hope that you will enjoy
using
them. But
there are certain things that we dont promise about our Services.
<br><br> Other than as expressly set out in these terms or additional terms, neither susper nor its
suppliers
or distributors make any specific promises about the Services. For example, we dont make any
commitments about
the content within the Services, the specific functions of the Services, or their reliability,
availability,
or ability to meet your needs. We provide the Services “as is”.
<br><br> Some jurisdictions provide for certain warranties, like the implied warranty of
merchantability, fitness
for a particular purpose and non-infringement. To the extent permitted by law, we exclude all
warranties.
<br><br>
</p>
</div>
<div id="element9">
<h2>Liability for our Services</h2>
<p>When permitted by law, susper, and suspers suppliers and distributors, will not be responsible for
lost
profits,
revenues, or data, financial losses or indirect, special, consequential, exemplary, or punitive
damages.
<br><br> To the extent permitted by law, the total liability of susper, and its suppliers and
distributors, for
any claims under these terms, including for any implied warranties, is limited to the amount you
paid
us to use
the Services (or, if we choose, to supplying you the Services again).
<br><br> In all cases, susper, and its suppliers and distributors, will not be liable for any loss
or
damage
that is not reasonably foreseeable.
<br><br> We recognize that in some countries, you might have legal rights as a consumer. If you are
using the
Services for a personal purpose, then nothing in these terms or any additional terms limits any
consumer legal
rights which may not be waived by contract.
<br><br>
</p>
</div>
<div id="element10">
<h2>Business uses of our Services</h2>
<p>If you are using our Services on behalf of a business, that business accepts these terms. It will
hold
harmless and
indemnify susper and its affiliates, officers, agents, and employees from any claim, suit or action
arising from
or related to the use of the Services or violation of these terms, including any liability or
expense
arising
from claims, losses, damages, suits, judgments, litigation costs and attorneys fees.
<br><br>
</p>
</div>
<div id="element11">
<h2>About these Terms</h2>
<p>We may modify these terms or any additional terms that apply to a Service to, for example, reflect
changes to
the law or changes to our Services. You should look at the terms regularly. Well post notice of
modifications
to these terms on this page. Well post notice of modified additional terms in the applicable
Service.
Changes
will not apply retroactively and will become effective no sooner than fourteen days after they are
posted.
However, changes addressing new functions for a Service or changes made for legal reasons will be
effective
immediately. If you do not agree to the modified terms for a Service, you should discontinue your
use
of
that Service.
<br><br> If there is a conflict between these terms and the additional terms, the additional terms
will
control
for that conflict.
<br> These terms control the relationship between susper and you. They do not create any third
party
beneficiary
rights.
<br><br> If you do not comply with these terms, and we dont take action right away, this doesnt
mean
that
we are giving up any rights that we may have (such as taking action in the future).
<br><br> If it turns out that a particular term is not enforceable, this will not affect any other
terms.<br><br> You agree that the laws of Can Tho, Viet Nam will apply to any disputes arising out
of
or relating to these
terms or the Services. All claims arising out of or relating to these terms or the services will be
litigated
exclusively in the courts of Can Tho City, Viet Nam, and you and susper consent to personal
jurisdiction
in those courts.
<br><br>
<div style="margin-bottom:50px;"> For information about how to contact susper, please visit our <a
class="page-link" routerLink="/contact">contact page</a>.</div>
<br><br>
</div>
</div>
</div>
<footer>
<app-footer-navbar></app-footer-navbar>
</footer>
<footer>
<app-footer-navbar></app-footer-navbar>
</footer>

View file

@ -39,9 +39,56 @@ describe('Component: Terms', () => {
expect(terms).toBeTruthy();
});
it('should have alt text property as brand', () => {
let compiled = fixture.debugElement.nativeElement;
let image: HTMLImageElement = compiled.querySelector('div.navbar-header img');
expect(image).toBeTruthy();
expect(image.alt).toBe('brand');
});
it('should have a div with id left', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div#left'));
});
it('should have a div with id right', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div#right'));
});
it('should have a sidebar menu', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('ul.sidebar-list'));
});
it('should have an active list on sidebar menu', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('ul.sidebar-list li.active'));
});
it('should create a FooterNavbar Component', () => {
const footerNavbar = new FooterNavbarComponent();
expect(footerNavbar).toBeTruthy();
});
it('should have an app-footer-navbar element', () => {
let compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('app-footer-navbar')).toBeTruthy();
});
it('should scroll', async(() => {
let compiled = fixture.debugElement.nativeElement;
const element = compiled.querySelector('li.element4 a');
element.click();
fixture.whenStable().then(() => {
expect(compiled.querySelector('li.element4.active')).toBeTruthy();
});
}));
});

View file

@ -12,4 +12,17 @@ export class TermsComponent implements OnInit {
ngOnInit() {
}
scrollTo(el) {
const element = document.getElementById(el);
document.getElementsByClassName('active')[0].classList.remove('active');
document.getElementsByClassName(el)[0].classList.add('active');
const headerOffset = 25;
const elementPosition = element.offsetTop;
const offsetPosition = elementPosition - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
}
}

View file

@ -2,3 +2,8 @@
font-weight: 600px;
padding: 5% 5% 3% 0%;
}
button.theme-link.active {
background-color: rgb(38, 84, 124);;
color: white;
}

View file

@ -1,18 +1,50 @@
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<!-- Start ignoring HTMLLintBear -->
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<!-- Stop ignoring HTMLLintBear -->
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
><span aria-hidden="true">&times;</span
></button>
<h4 class="modal-title" id="my-modal-label">Customization</h4>
<button type="button" (click)="setTheme('defaultTheme')" class="btn btn-round btn-default theme-link">Default</button>
<button type="button" (click)="setTheme('darkTheme')" class="btn btn-round btn-default theme-link">Dark</button>
<button type="button" (click)="setTheme('basicTheme')" class="btn btn-round btn-default theme-link">Basic</button>
<button type="button" (click)="setTheme('contrastTheme')" class="btn btn-round btn-default theme-link">Contrast</button>
<button type="button" (click)="setTheme('terminalTheme')" class="btn btn-round btn-default theme-link">Terminal</button>
<button type="button" (click)="setTheme('nightTheme')" class="btn btn-round btn-default theme-link">Night</button>
<button
type="button"
(click)="setTheme('defaultTheme')"
class="btn btn-round btn-default theme-link"
id="default"
>Default</button>
<button
type="button"
(click)="setTheme('darkTheme')"
class="btn btn-round btn-default theme-link"
id="dark"
>Dark</button>
<button
type="button"
(click)="setTheme('basicTheme')"
class="btn btn-round btn-default theme-link"
id="basic"
>Basic</button>
<button
type="button"
(click)="setTheme('contrastTheme')"
class="btn btn-round btn-default theme-link"
id="contrast"
>Contrast</button>
<button
type="button"
(click)="setTheme('terminalTheme')"
class="btn btn-round btn-default theme-link"
id="terminal"
>Terminal</button>
<button
type="button"
(click)="setTheme('nightTheme')"
class="btn btn-round btn-default theme-link"
id="night"
>Night</button>
</div>
</div>
</div>

View file

@ -2,6 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ThemeComponent } from './theme.component';
import { ThemeService } from '../services/theme.service';
import { By } from '@angular/platform-browser';
describe('ThemeComponent', () => {
let component: ThemeComponent;
@ -28,4 +29,109 @@ describe('ThemeComponent', () => {
it('should be created', () => {
expect(component).toBeTruthy();
});
it('should have modal-title', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h4.modal-title')).toBeTruthy();
});
it('should have button of class close', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('button.close')).toBeTruthy();
});
it('should have 6 buttons of class theme-link', () => {
const element = fixture.debugElement.queryAll(By.css('button.theme-link'));
expect(element.length).toBe(6);
});
it('should set default theme', async(() => {
spyOn(component, 'setTheme').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('button.theme-link'))[0];
const btn = element.nativeElement as HTMLElement;
btn.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const theme = JSON.parse(localStorage.getItem('theme')).value;
expect(theme).toBe('defaultTheme');
});
}));
it('should set dark theme', async(() => {
spyOn(component, 'setTheme').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('button.theme-link'))[1];
const btn = element.nativeElement as HTMLElement;
btn.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const theme = JSON.parse(localStorage.getItem('theme')).value;
expect(theme).toBe('darkTheme');
});
}));
it('should set basic theme', async(() => {
spyOn(component, 'setTheme').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('button.theme-link'))[2];
const btn = element.nativeElement as HTMLElement;
btn.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const theme = JSON.parse(localStorage.getItem('theme')).value;
expect(theme).toBe('basicTheme');
});
}));
it('should set contrast theme', async(() => {
spyOn(component, 'setTheme').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('button.theme-link'))[3];
const btn = element.nativeElement as HTMLElement;
btn.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const theme = JSON.parse(localStorage.getItem('theme')).value;
expect(theme).toBe('contrastTheme');
});
}));
it('should set terminal theme', async(() => {
spyOn(component, 'setTheme').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('button.theme-link'))[4];
const btn = element.nativeElement as HTMLElement;
btn.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const theme = JSON.parse(localStorage.getItem('theme')).value;
expect(theme).toBe('terminalTheme');
});
}));
it('should set night theme', async(() => {
spyOn(component, 'setTheme').and.callThrough();
const element = fixture.debugElement.queryAll(By.css('button.theme-link'))[5];
const btn = element.nativeElement as HTMLElement;
btn.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const theme = JSON.parse(localStorage.getItem('theme')).value;
expect(theme).toBe('nightTheme');
});
}));
});

View file

@ -59,6 +59,7 @@ export class ThemeComponent implements OnInit {
this.themeService.searchbarColor = '#000000';
this.themeService.searchbarbgColor = '#ffffff';
setFooter();
setBtnActive('dark');
}
defaultTheme() {
@ -71,6 +72,7 @@ export class ThemeComponent implements OnInit {
this.themeService.searchbarColor = '#000000';
this.themeService.searchbarbgColor = '#ffffff';
setFooter();
setBtnActive('default');
}
basicTheme() {
@ -83,6 +85,7 @@ export class ThemeComponent implements OnInit {
this.themeService.searchbarColor = '#000000';
this.themeService.searchbarbgColor = '#ffffff';
setFooter();
setBtnActive('basic');
}
contrastTheme() {
@ -95,6 +98,7 @@ export class ThemeComponent implements OnInit {
this.themeService.searchbarColor = '#000000';
this.themeService.searchbarbgColor = '#ffffff';
setFooter();
setBtnActive('contrast');
}
terminalTheme() {
@ -107,6 +111,7 @@ export class ThemeComponent implements OnInit {
this.themeService.searchbarColor = '#000000';
this.themeService.searchbarbgColor = '#ffffff';
setFooter();
setBtnActive('terminal');
}
nightTheme() {
@ -118,12 +123,24 @@ export class ThemeComponent implements OnInit {
this.themeService.navbarbgColor = '#373737';
this.themeService.searchbarColor = '#ffffff';
this.themeService.searchbarbgColor = '#323232';
(document.getElementsByClassName("footer-bar")[0] as HTMLElement).style.background = '#373737';
(document.getElementsByClassName("footer-bar")[0] as HTMLElement).style.borderTop = '#222222';
if (typeof(document.getElementsByClassName("footer-bar")[0] as HTMLElement) !== 'undefined') {
(document.getElementsByClassName("footer-bar")[0] as HTMLElement).style.background = '#373737';
(document.getElementsByClassName("footer-bar")[0] as HTMLElement).style.borderTop = '#222222';
}
setBtnActive('night');
}
}
function setFooter() {
(document.getElementsByClassName("footer-bar")[0] as HTMLElement).style.background = '#f2f2f2';
(document.getElementsByClassName("footer-bar")[0] as HTMLElement).style.borderTop = '#e4e4e4';
if (typeof(document.getElementsByClassName("footer-bar")[0] as HTMLElement) !== 'undefined') {
(document.getElementsByClassName("footer-bar")[0] as HTMLElement).style.background = '#f2f2f2';
(document.getElementsByClassName("footer-bar")[0] as HTMLElement).style.borderTop = '#e4e4e4';
}
}
function setBtnActive(btnID) {
if (document.getElementsByClassName('active').length > 0) {
document.getElementsByClassName('active')[0].classList.remove('active');
}
document.getElementById(btnID).classList.add('active');
}

View file

@ -17,3 +17,254 @@ export function type<T>(label: T | ''): T {
return <T>label;
}
export function validateMessage(message) {
if (message && message.length >= 100) {
return true;
} else {
return false;
}
}
export function validatePhone(phone) {
if (phone && phone.toString().length >= 10) {
return true;
} else {
return false;
}
}
export function validateEmail(email) {
if (email) {
let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
} else {
return false;
}
}
export function validateName(name) {
if (name && name.length > 0) {
return true;
} else {
return false;
}
}
export const countryCodeList = [
{ value: '213', description: 'Algeria (+213)' },
{ value: '213', description: 'Algeria (+213)' },
{ value: '376', description: 'Andorra (+376)' },
{ value: '244', description: 'Angola (+244)' },
{ value: '1264', description: 'Anguilla (+1264)' },
{ value: '1268', description: 'Antigua &amp; Barbuda (+1268)' },
{ value: '54', description: 'Argentina (+54)' },
{ value: '374', description: 'Armenia (+374)' },
{ value: '297', description: 'Aruba (+297)' },
{ value: '61', description: 'Australia (+61)' },
{ value: '43', description: 'Austria (+43)' },
{ value: '994', description: 'Azerbaijan (+994)' },
{ value: '1242', description: 'Bahamas (+1242)' },
{ value: '973', description: 'Bahrain (+973)' },
{ value: '880', description: 'Bangladesh (+880)' },
{ value: '1246', description: 'Barbados (+1246)' },
{ value: '375', description: 'Belarus (+375)' },
{ value: '32', description: 'Belgium (+32)' },
{ value: '501', description: 'Belize (+501)' },
{ value: '229', description: 'Benin (+229)' },
{ value: '1441', description: 'Bermuda (+1441)' },
{ value: '975', description: 'Bhutan (+975)' },
{ value: '591', description: 'Bolivia (+591)' },
{ value: '387', description: 'Bosnia Herzegovina (+387)' },
{ value: '267', description: 'Botswana (+267)' },
{ value: '55', description: 'Brazil (+55)' },
{ value: '673', description: 'Brunei (+673)' },
{ value: '359', description: 'Bulgaria (+359)' },
{ value: '226', description: 'Burkina Faso (+226)' },
{ value: '257', description: 'Burundi (+257)' },
{ value: '855', description: 'Cambodia (+855)' },
{ value: '237', description: 'Cameroon (+237)' },
{ value: '1', description: 'Canada (+1)' },
{ value: '238', description: 'Cape Verde Islands (+238)' },
{ value: '1345', description: 'Cayman Islands (+1345)' },
{ value: '236', description: 'Central African Republic (+236)' },
{ value: '56', description: 'Chile (+56)' },
{ value: '86', description: 'China (+86)' },
{ value: '57', description: 'Colombia (+57)' },
{ value: '269', description: 'Comoros (+269)' },
{ value: '242', description: 'Congo (+242)' },
{ value: '682', description: 'Cook Islands (+682)' },
{ value: '506', description: 'Costa Rica (+506)' },
{ value: '385', description: 'Croatia (+385)' },
{ value: '53', description: 'Cuba (+53)' },
{ value: '90392', description: 'Cyprus North (+90392)' },
{ value: '357', description: 'Cyprus South (+357)' },
{ value: '42', description: 'Czech Republic (+42)' },
{ value: '45', description: 'Denmark (+45)' },
{ value: '253', description: 'Djibouti (+253)' },
{ value: '1809', description: 'Dominica (+1809)' },
{ value: '1809', description: 'Dominican Republic (+1809)' },
{ value: '593', description: 'Ecuador (+593)' },
{ value: '20', description: 'Egypt (+20)' },
{ value: '503', description: 'El Salvador (+503)' },
{ value: '240', description: 'Equatorial Guinea (+240)' },
{ value: '291', description: 'Eritrea (+291)' },
{ value: '372', description: 'Estonia (+372)' },
{ value: '251', description: 'Ethiopia (+251)' },
{ value: '500', description: 'Falkland Islands (+500)' },
{ value: '298', description: 'Faroe Islands (+298)' },
{ value: '679', description: 'Fiji (+679)' },
{ value: '358', description: 'Finland (+358)' },
{ value: '33', description: 'France (+33)' },
{ value: '594', description: 'French Guiana (+594)' },
{ value: '689', description: 'French Polynesia (+689)' },
{ value: '241', description: 'Gabon (+241)' },
{ value: '220', description: 'Gambia (+220)' },
{ value: '7880', description: 'Georgia (+7880)' },
{ value: '49', description: 'Germany (+49)' },
{ value: '233', description: 'Ghana (+233)' },
{ value: '350', description: 'Gibraltar (+350)' },
{ value: '30', description: 'Greece (+30)' },
{ value: '299', description: 'Greenland (+299)' },
{ value: '1473', description: 'Grenada (+1473)' },
{ value: '590', description: 'Guadeloupe (+590)' },
{ value: '671', description: 'Guam (+671)' },
{ value: '502', description: 'Guatemala (+502)' },
{ value: '224', description: 'Guinea (+224)' },
{ value: '245', description: 'Guinea - Bissau (+245)' },
{ value: '592', description: 'Guyana (+592)' },
{ value: '509', description: 'Haiti (+509)' },
{ value: '504', description: 'Honduras (+504)' },
{ value: '852', description: 'Hong Kong (+852)' },
{ value: '36', description: 'Hungary (+36)' },
{ value: '354', description: 'Iceland (+354)' },
{ value: '91', description: 'India (+91)' },
{ value: '62', description: 'Indonesia (+62)' },
{ value: '98', description: 'Iran (+98)' },
{ value: '964', description: 'Iraq (+964)' },
{ value: '353', description: 'Ireland (+353)' },
{ value: '972', description: 'Israel (+972)' },
{ value: '39', description: 'Italy (+39)' },
{ value: '1876', description: 'Jamaica (+1876)' },
{ value: '81', description: 'Japan (+81)' },
{ value: '962', description: 'Jordan (+962)' },
{ value: '7', description: 'Kazakhstan (+7)' },
{ value: '254', description: 'Kenya (+254)' },
{ value: '686', description: 'Kiribati (+686)' },
{ value: '850', description: 'Korea North (+850)' },
{ value: '82', description: 'Korea South (+82)' },
{ value: '965', description: 'Kuwait (+965)' },
{ value: '996', description: 'Kyrgyzstan (+996)' },
{ value: '856', description: 'Laos (+856)' },
{ value: '371', description: 'Latvia (+371)' },
{ value: '961', description: 'Lebanon (+961)' },
{ value: '266', description: 'Lesotho (+266)' },
{ value: '231', description: 'Liberia (+231)' },
{ value: '218', description: 'Libya (+218)' },
{ value: '417', description: 'Liechtenstein (+417)' },
{ value: '370', description: 'Lithuania (+370)' },
{ value: '352', description: 'Luxembourg (+352)' },
{ value: '853', description: 'Macao (+853)' },
{ value: '389', description: 'Macedonia (+389)' },
{ value: '261', description: 'Madagascar (+261)' },
{ value: '265', description: 'Malawi (+265)' },
{ value: '60', description: 'Malaysia (+60)' },
{ value: '960', description: 'Maldives (+960)' },
{ value: '223', description: 'Mali (+223)' },
{ value: '356', description: 'Malta (+356)' },
{ value: '692', description: 'Marshall Islands (+692)' },
{ value: '596', description: 'Martinique (+596)' },
{ value: '222', description: 'Mauritania (+222)' },
{ value: '269', description: 'Mayotte (+269)' },
{ value: '52', description: 'Mexico (+52)' },
{ value: '691', description: 'Micronesia (+691)' },
{ value: '373', description: 'Moldova (+373)' },
{ value: '377', description: 'Monaco (+377)' },
{ value: '976', description: 'Mongolia (+976)' },
{ value: '1664', description: 'Montserrat (+1664)' },
{ value: '212', description: 'Morocco (+212)' },
{ value: '258', description: 'Mozambique (+258)' },
{ value: '95', description: 'Myanmar (+95)' },
{ value: '264', description: 'Namibia (+264)' },
{ value: '674', description: 'Nauru (+674)' },
{ value: '977', description: 'Nepal (+977)' },
{ value: '31', description: 'Netherlands (+31)' },
{ value: '687', description: 'New Caledonia (+687)' },
{ value: '64', description: 'New Zealand (+64)' },
{ value: '505', description: 'Nicaragua (+505)' },
{ value: '227', description: 'Niger (+227)' },
{ value: '234', description: 'Nigeria (+234)' },
{ value: '683', description: 'Niue (+683)' },
{ value: '672', description: 'Norfolk Islands (+672)' },
{ value: '670', description: 'Northern Marianas (+670)' },
{ value: '47', description: 'Norway (+47)' },
{ value: '968', description: 'Oman (+968)' },
{ value: '680', description: 'Palau (+680)' },
{ value: '507', description: 'Panama (+507)' },
{ value: '675', description: 'Papua New Guinea (+675)' },
{ value: '595', description: 'Paraguay (+595)' },
{ value: '51', description: 'Peru (+51)' },
{ value: '63', description: 'Philippines (+63)' },
{ value: '48', description: 'Poland (+48)' },
{ value: '351', description: 'Portugal (+351)' },
{ value: '1787', description: 'Puerto Rico (+1787)' },
{ value: '974', description: 'Qatar (+974)' },
{ value: '262', description: 'Reunion (+262)' },
{ value: '40', description: 'Romania (+40)' },
{ value: '7', description: 'Russia (+7)' },
{ value: '250', description: 'Rwanda (+250)' },
{ value: '378', description: 'San Marino (+378)' },
{ value: '239', description: 'Sao Tome &amp; Principe (+239)' },
{ value: '966', description: 'Saudi Arabia (+966)' },
{ value: '221', description: 'Senegal (+221)' },
{ value: '381', description: 'Serbia (+381)' },
{ value: '248', description: 'Seychelles (+248)' },
{ value: '232', description: 'Sierra Leone (+232)' },
{ value: '65', description: 'Singapore (+65)' },
{ value: '421', description: 'Slovak Republic (+421)' },
{ value: '386', description: 'Slovenia (+386)' },
{ value: '677', description: 'Solomon Islands (+677)' },
{ value: '252', description: 'Somalia (+252)' },
{ value: '27', description: 'South Africa (+27)' },
{ value: '34', description: 'Spain (+34)' },
{ value: '94', description: 'Sri Lanka (+94)' },
{ value: '290', description: 'St. Helena (+290)' },
{ value: '1869', description: 'St. Kitts (+1869)' },
{ value: '1758', description: 'St. Lucia (+1758)' },
{ value: '249', description: 'Sudan (+249)' },
{ value: '597', description: 'Suriname (+597)' },
{ value: '268', description: 'Swaziland (+268)' },
{ value: '46', description: 'Sweden (+46)' },
{ value: '41', description: 'Switzerland (+41)' },
{ value: '963', description: 'Syria (+963)' },
{ value: '886', description: 'Taiwan (+886)' },
{ value: '7', description: 'Tajikstan (+7)' },
{ value: '66', description: 'Thailand (+66)' },
{ value: '228', description: 'Togo (+228)' },
{ value: '676', description: 'Tonga (+676)' },
{ value: '1868', description: 'Trinidad &amp; Tobago (+1868)' },
{ value: '216', description: 'Tunisia (+216)' },
{ value: '90', description: 'Turkey (+90)' },
{ value: '7', description: 'Turkmenistan (+7)' },
{ value: '993', description: 'Turkmenistan (+993)' },
{ value: '1649', description: 'Turks &amp; Caicos Islands (+1649)' },
{ value: '688', description: 'Tuvalu (+688)' },
{ value: '256', description: 'Uganda (+256)' },
{ value: '44', description: 'UK (+44)' },
{ value: '380', description: 'Ukraine (+380)' },
{ value: '971', description: 'United Arab Emirates (+971)' },
{ value: '598', description: 'Uruguay (+598)' },
{ value: '1', description: 'USA (+1)' },
{ value: '7', description: 'Uzbekistan (+7)' },
{ value: '678', description: 'Vanuatu (+678)' },
{ value: '379', description: 'Vatican City (+379)' },
{ value: '58', description: 'Venezuela (+58)' },
{ value: '84', description: 'Vietnam (+84)' },
{ value: '84', description: 'Virgin Islands - British (+1284)' },
{ value: '84', description: 'Virgin Islands - US (+1340)' },
{ value: '681', description: 'Wallis &amp; Futuna (+681)' },
{ value: '969', description: 'Yemen (North) (+969)' },
{ value: '967', description: 'Yemen (South) (+967)' },
{ value: '260', description: 'Zambia (+260)' },
{ value: '263', description: 'Zimbabwe (+263)' },
];

View file

@ -44,6 +44,11 @@ dl {
width:96%;
}
.text-center {
padding-top:20px;
font-size:30px !important;
}
body, table, textarea {
font-size: 12px;
overflow-x: hidden;
@ -81,12 +86,12 @@ a:link {
}
a:visited {
color:#18294A;
color:#609 !important;
text-decoration:underline;
}
a:hover {
color:#18294A;
color:#609;
text-decoration:underline;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

View file

@ -4,7 +4,7 @@ export const url = {
'newsFile': 'https://github.com/fossasia/susper.com/blob/master/src/assets/newsFile.json'
},
'yacy': {
'site': 'yacy.net',
'site': 'https://yacy.net',
'api_server': 'yacy.searchlab.eu',
'crawl_start_api': 'yacygrid.com:8300',
'websearch_api': 'yacy-websearch.net'
@ -39,10 +39,13 @@ export const url = {
'site': 'https://github.com/fossasia/MMM-SUSI-AI'
},
'yaydoc': {
'site': 'http://dev.yaydoc.org'
'site': 'http://yaydoc.org'
},
'github_repo': {
'fossasia': 'https://github.com/fossasia'
'fossasia': 'github.com/fossasia'
},
'badgemagic': {
'repo' : 'https://github.com/fossasia/badge-magic-android'
}
}

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Susper</title>

View file

@ -1 +1,4 @@
/* You can add global styles to this file, and also import other style files */
/* You can add global styles to this file, and also import other style files */
a:hover {
text-decoration: underline !important;
}