浏览代码

FE prototyping

Thomas Hanika 3 年之前
父节点
当前提交
c18ebca9bb
共有 6 个文件被更改,包括 149 次插入99 次删除
  1. 15 0
      ycast/my_stations.py
  2. 1 1
      ycast/server.py
  3. 81 22
      ycast/static/script.js
  4. 46 37
      ycast/static/style.css
  5. 2 12
      ycast/templates/index.html
  6. 4 27
      ycast/test_YCast.py

+ 15 - 0
ycast/my_stations.py

@@ -65,3 +65,18 @@ def get_stations_by_category(category):
                 station_icon = param_list[1]
             stations.append(Station(station_name, station_url, category, station_icon))
     return stations
+
+def get_all_bookmarks_stations():
+    bm_stations_category = generic.read_yaml_file(generic.get_stations_file())
+    stations = []
+    if bm_stations_category :
+        for category in bm_stations_category:
+            for station_name in bm_stations_category[category]:
+                station_urls = bm_stations_category[category][station_name]
+                param_list = station_urls.split('|')
+                station_url = param_list[0]
+                station_icon = None
+                if len(param_list) > 1:
+                    station_icon = param_list[1]
+                stations.append(Station(station_name, station_url, category, station_icon))
+    return stations

+ 1 - 1
ycast/server.py

@@ -162,7 +162,7 @@ def landing_api(path):
 
     if path.endswith('bookmarks'):
         category = request.args.get('category')
-        stations = my_stations.get_stations_by_category(category)
+        stations = my_stations.get_all_bookmarks_stations()
         if stations is not None:
             stations_dict = []
             for station in stations:

+ 81 - 22
ycast/static/script.js

@@ -1,23 +1,27 @@
 window.onload = function () {
     category = document.getElementById('id_category').value;
     param = document.getElementById('id_param').value;
-    requestStationList(category, param) 
-    
+    requestStationList(category, param);
+    requestStationList('', '', true);
 }
 
-function initSearch() {
+function initSearchStation() {
     var stationsearch = document.getElementById('stationsearch');
     stationsearch.value = '';
     stationsearch.onkeyup = function () {
         var filter = stationsearch.value.toUpperCase();
-        var lis = document.getElementsByTagName('li');
-        for (var i = 0; i < lis.length; i++) {
-            var searchval = lis[i].dataset.search;
-            if (searchval.indexOf(filter) > -1)
-                lis[i].style.display = 'flex';
-            else
-                lis[i].style.display = 'none';
-        }
+        var stationList = Array.from(document.getElementById("stationList").childNodes);
+        stationList.forEach(function (listItem) {
+            try {
+                var searchval = listItem.dataset.search;
+                if (searchval.indexOf(filter) > -1)
+                    listItem.style.display = 'flex';
+                else
+                    listItem.style.display = 'none';
+            } catch (e) {
+                console.error(listItem, e)
+            }
+        })
     }
 }
 
@@ -50,17 +54,23 @@ function createItem(name, icon, description) {
     return itemElem;
 }
 
-function requestStationList(category, param) {
+function requestStationList(category, param, isbookmarklist = false) {
     var url = 'api/stations?category=' + category;
-
-    if (category.indexOf('language') > -1) {
-        url = url + '&language=' + param.toLowerCase();
+    var id_listnode = "stationList";
+    if (isbookmarklist) {
+        var url = 'api/bookmarks?category=' + category;
+        var id_listnode = "bookmarkList";
     }
-    if (category.indexOf('country') > -1) {
-        url = url + '&country=' + param;
+    if (param.length > 0) {
+        if (category.indexOf('language') > -1) {
+            url = url + '&language=' + param.toLowerCase();
+        }
+        if (category.indexOf('country') > -1) {
+            url = url + '&country=' + param;
+        }
     }
     var myRequest = new Request(url);
-    var myOldList = document.getElementById("stationList");
+    var myOldList = document.getElementById(id_listnode);
 
     var myList = myOldList.cloneNode(false);
     myOldList.parentNode.replaceChild(myList, myOldList);
@@ -75,11 +85,15 @@ function requestStationList(category, param) {
                 );
                 listItem.dataset.json = JSON.stringify(station);
                 listItem.dataset.search = (station.name + '#' + station.description).toUpperCase();
+                listItem.dataset.category = station.description;
                 myList.appendChild(listItem);
             }
+            if(isbookmarklist) {
+                setBookmarkCategoryList();
+            }
         })
         .catch(console.error);
-    initSearch();
+    initSearchStation();
 }
 
 function onInputSelect(e, objElem) {
@@ -91,11 +105,15 @@ function onInputSelect(e, objElem) {
         switch (category) {
             case 'language':
                 setParamlist();
-                try {paramElem.fokus();} catch(e) {};
+                try {
+                    paramElem.fokus();
+                } catch (e) {};
                 return;
             case 'country':
                 setParamlist();
-                try {paramElem.fokus();} catch(e) {};
+                try {
+                    paramElem.fokus();
+                } catch (e) {};
                 return;
             default:
                 paramElem.disabled = true;
@@ -105,13 +123,54 @@ function onInputSelect(e, objElem) {
     }
 }
 
+function setBookmarkCategoryList() {
+    var categoryList = [];
+    var bookmarkList = Array.from(document.getElementById("bookmarkList").childNodes);
+    bookmarkList.forEach(function (listItem) {
+        try {
+            var category = listItem.dataset.category;
+            if (!categoryList.find(function(arElem) { return (category == arElem);})) {
+                console.log(category);
+                categoryList.push(category);
+            }
+        } catch (e) {
+            console.error(listItem, e)
+        }
+    })
+    console.log(categoryList);
+    if (categoryList.length >0) {
+        var myOldList = document.getElementById('categorylist');
+        var myList = myOldList.cloneNode(false);
+        myOldList.parentNode.replaceChild(myList, myOldList);
+    
+        for (const categ of categoryList) {
+            var option = document.createElement('option');
+            option.value = categ;
+            myList.appendChild(option);
+        }
+    }
+}
+
+function filterBookmarkCategoryList(category) {
+    var bookmarkList = Array.from(document.getElementById("bookmarkList").childNodes);
+    bookmarkList.forEach(function (listItem) {
+        try {
+            if (listItem.dataset.category.indexOf(category) > -1)
+                listItem.style.display = 'flex';
+            else
+                listItem.style.display = 'none';
+        } catch (e) {
+            console.error(listItem, e)
+        }
+    })
+}
+
 function setParamlist() {
     var category = document.getElementById('id_category').value
     var url = 'api/paramlist?category=' + category;
     document.getElementById('id_param').value = '';
     var myRequest = new Request(url);
     var myOldList = document.getElementById('paramlist');
-
     var myList = myOldList.cloneNode(false);
     myOldList.parentNode.replaceChild(myList, myOldList);
 

+ 46 - 37
ycast/static/style.css

@@ -1,46 +1,45 @@
 body {
     font-family: sans-serif;
-    height: 100%;
-    align-items: center;
 }
 
 .page {
-    align-items: center;
-    height: 100%;
-    width: 100%;
+    display: block;
+    padding-left: calc(100% / 2 - 20rem);
 }
 
 .header {
+    position: relative;
     height=30rem;
-    width: 38.9rem;
+    max-width: 19.0rem;
+    min-width: 19.0rem;
     margin: 0rem;
     background-color: blue;
     color: white;
     text-align: center;
-    min-width: 20rem;
-    max-width: 40rem;
-    padding: 0.5rem
-}
-
-.container {
-    display: block;
-    width: 100%;
-    bottom: 0rem;
-    background-color: aquamarine;
+    padding: 0.5rem;
 }
 
 .content {
-    display: block;
-    width: 20rem;
-    min-width: 20rem;
-    float: left;
+    position: relative;
+    display: inline-block;
+    box-sizing: border-box;
     margin: 0rem;
-    height: calc(100% - 13rem);
-    max-height: 30rem;
+    max-height: 60rem;
+    max-width: 20rem;
+    min-width: 20rem;
+}
+
+@media (min-width: 42.5rem) {
+    .header {
+        max-width: 39.2rem;
+        min-width: 39.2rem;
+    }
 }
 
 .contentheader {
-    display: block;
+    box-sizing: border-box;
+    display: inline-table;
+    position: relative;
     background-color: blue;
     color: white;
     align-items: center;
@@ -48,25 +47,28 @@ body {
     padding: 0.2rem;
     border: 2px #eee solid;
     height: 5rem;
-    width: 100%
+    width: 100%;
+    min-width: 20rem;
 }
 
 .contentitems {
-    display: block;
+    box-sizing: border-box;
+    position: relative;
+    display: flex;
     overflow-y: auto;
     overflow-x: hidden;
-    top: 6rem;
-    width: 100%;
-    height: calc(100% - 20rem);
     max-height: 30rem;
-    border: 2px #eee solid ;
+    min-width: 20rem;
+    border: 2px #eee solid;
 }
 
 .item {
-    display: flex;
+    position: relative;
+    display: inline-flex;
     border: 2px #eee solid;
-    margin: 0rem;
-    height: 2.4rem;
+    margin: 0.1rem;
+    min-height: 2.6rem;
+    min-width: 19rem;
     align-items: center;
 }
 
@@ -75,12 +77,15 @@ body {
 }
 
 .itemicon {
+    display: flex;
+    box-sizing: border-box;
+    margin: 1px;
     height: 2.4rem;
     width: 2.4rem;
 }
 
 .itemtext {
-    white-space: nowrap;
+    display: flex white-space: nowrap;
     overflow: hidden;
     text-overflow: ellipsis;
 }
@@ -90,7 +95,6 @@ ul {
     margin: 0rem;
     height: 100%;
     width: 100%;
-    display: contents;
 }
 
 li {
@@ -114,18 +118,23 @@ h3 {
 h4 {
     text-align: left;
     padding-left: 1rem;
-    margin: auto
+    margin: auto;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+
 }
 
 p {
     padding-left: 1.1rem;
     margin: auto;
     font-size: 0.8rem;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
 
 }
 
 label {
     padding-left: 1.1rem;
 }
-
-input

+ 2 - 12
ycast/templates/index.html

@@ -43,8 +43,8 @@
             <div class="contentheader">
                 <h3>Bookmarks</h3>
                 <label for="idCategory">category:</label>
-                <input tabindex="10000" list="category" id="idCategory">
-                <datalist id="category">
+                <input tabindex="10000" list="categorylist" id="idCategory">
+                <datalist id="categorylist">
                     <option value="Actual">
                     <option value="Pop">
                     <option value="Classics">
@@ -53,16 +53,6 @@
             </div>
             <div class="contentitems">
                 <ul id="bookmarkList">
-                         <li class="item">
-        <div class="itemicon">
-             <img class="itemicon" src="http://www.klassikradio.de/_nuxt/icons/icon_64.a00w80w0000.png">
-        </div>
-        <div class="itemtext">
-            <h4>Radio</h4>
-            <p>ard,actuell</p>
-        </div>
-    </li>
-
                 </ul>
             </div>
         </div>

+ 4 - 27
ycast/test_YCast.py

@@ -12,6 +12,9 @@ from ycast import my_filter, generic, radiobrowser, my_recentlystation
 class MyTestCase(unittest.TestCase):
 
     logging.getLogger().setLevel(logging.DEBUG)
+    generic.init_base_dir("../../.test_ycast")
+    my_filter.init_filter_file()
+
 
     def test_verify_values(self):
         assert my_filter.verify_value(None, None)
@@ -41,22 +44,6 @@ class MyTestCase(unittest.TestCase):
             else:
                 logging.warning("    <empty list>")
 
-    def test_valid_station(self):
-        my_filter.begin_filter()
-        test_lines = generic.readlns_txt_file(generic.get_var_path()+"/test.json")
-
-        test_lines = radiobrowser.get_stations_by_votes()
-
-        io = StringIO(test_lines[0])
-        stations_json = json.load(io)
-        count = 0
-        for station_json in stations_json:
-            if my_filter.check_station(station_json):
-                station = radiobrowser.Station(station_json)
-                count = count + 1
-
-        my_filter.end_filter()
-
     def test_life_popular_station(self):
         # hard test for filter
         stations = radiobrowser.get_stations_by_votes(10000000)
@@ -67,11 +54,10 @@ class MyTestCase(unittest.TestCase):
         assert len(result) == 3
 
     def test_get_countries(self):
-        generic.init_base_dir('.ycast')
         my_filter.init_filter_file()
 
         result = radiobrowser.get_country_directories()
-        assert len(result) == 4
+        assert len(result) == 137
 
     def test_get_genre(self):
         result = radiobrowser.get_genre_directories()
@@ -81,15 +67,6 @@ class MyTestCase(unittest.TestCase):
         result = my_filter.get_limit('irgendwas',20)
         assert result == 20
 
-    def test_jsonable_classes(self):
-        stations = radiobrowser.get_stations_by_country('Germany')
-        station = stations[0]
-        text = station.to_vtuner()
-        response = station.toJson()
-        response = json.dumps(station, skipkeys= True)
-
-        assert response is not None
-
     def test_recently_hit(self):
 
         try: