I'm working on a CMS, and want to let users embed Soundcloud tunes and playlists.
I'd like to avoid fiddling with the API - since it doesn't appear to be necessary: )
Instead I just piece together an iframe-src-url with the appropriate parameters.
I was unable to find an official list anywhere, so I've collected my own, from various posts here and elsewhere:
&color=FF4444 // play-button and equalizer graphic (if not &visual=true)
&auto_play=false // shouls be obvious
&show_artwork=true // show the artist-graphic on the left
&show_comments=true // show fans commenst under equalizer
&show_playcount=true // number of times played # bottom right
&hide_related=true // don't force user over to Soundcloud after play
&show_user=false // don't show uploaders name # top left
&show_reposts=false // ?
&liking=false // dont show [Like] button
&visual=true // use artist-graphic for background (way cooler)
&buying=false // no Buy (iTunes) button
&sharing=false // no [Share] button
&download=false // no download button
&start_track=4 // start at specific track (for lists)
And guesed : )
&following=false (removes [Follow] when mouseover artwork)
What parameters am I missing?
What I really want is Next and Previous buttons for lists. Do they even exist?
You're missing:
download=true // Show/hide download buttons
sharing=true // Show/hide share buttons/dialogues
start_track=0 // Preselects a track in the playlist, given a number between 0 and the length of the playlist.
Found in the docs.
It looks like next() and prev() and skip(index) are all methods on the widget rather than parameters. You can get around this by keeping an index of the current track and pass in a value to the start_track parameter as a way to get to the next and previous tracks.
Related
I would like to display a table which have several thousand rows with complex formatting (color, font, border, etc. done on the ASP.Net Core server).
Initially, I generated an html copy of all the data (stored in a SQL Server database), but realised it wasn't optimal since the generated html data accounted for more than 50MB.
No, I only generate about 200 rows; 100 visible and 50 hidden above and below (cache). I would like to freely scroll the tablen, but when there are only 25 hidden rows above or below, fetch new rows from the controller which are then prepend or append to the table. Basically, I want to give enough room so I can can populate the table when I'm scrolling through the "hidden" (cache) rows.
Everything seems to work well, but I believe I need to use a web-worker to run the function in a background thread which add new rows to the table independently of the table being scrolled.
Below is a excerpt of the code :
I use a debunce function to only catch the lastest position of the mouse scroll.
The scroll function basically only checks whether there are enough hidden rows (cache) above or below the table. If it reaches the threshold, it either prepends (scroll upwards) or appends (scroll downwards) rows obtained from the controller.
The main issue is that I can't scroll the table when the new rows are being fetch as the page freezes. It only takes about 1 to 2 seconds to populate to new (scrollable) rows but it isn't smooth.
Could anyone help me improve the code? (general ideas) I also read that there are already existing libraries but can't really get my head around them..
$('#fields-table > tbody').on('wheel', _.debounce(async function (event) {
await scroll(); // Probably change it to a web-worker or promise?
}
async function scroll() {
var threshold = 200; // Corresponds to approximatively 50 rows (above and below).
var above = $('#fields-table').scrollTop();
var below = $('#fields-table > tbody').height() - $('#fields-table').height() - above;
// Gets the scroll delta based on the table heights.
var delta = 0
if (above < threshold) delta = above - threshold; // Scrolls upwards.
if (below < threshold) delta = threshold - below; // Scrolls downwards.
await addCacheRows(delta); // Prepends (delta < 0) or appends (delta > 0) or appends rows obtained via the fetch API.
}
Your problem is unlikely to resolve with a web worker. Without seeing more code I cannot tell for sure, but I suspect your code to generate new rows is not sufficiently efficient. Remember:
Use DocumentFragment to create the HTML, do not immediately append it to the main DOM tree row by row. Appending elements to a document triggers some recalculations.
Unless this is a LOT of data or requires lots of work serverside, you can immediately start preloading next/previous rows. Keep the promise object and only await it once you need them, that's the simplest way to go around it
Use passive scroll event listener - Firefox even shows a console warning whenever you do not do that
There is no way generating 200 rows of table data should take seconds. Since you use JQuery anyway (really, in 2022?), note that there are plugins for this. I don't remember what I used, but it worked perfect and scrolled smooth with much more data than what you have.
Thank you for your help. I realise it won't be as straightforward as I initally thought (I made some tests with WPF virtualization as well).
Regarding the time it takes to generate the extra rows, I believe it mostly comes from the server. Sure, I can probably load new rows independently of the threshold.
I've never heard about DocumentFragment, but that something I should definitely consider.
I need an algorithm to tell a sprite to end as soon as the text finishes appearing, basically I need to make a cutscene which describes the beginning of a story within the game, but since I'm using gamemaker, I don't know how to do it, can someone help me?
For cutscenes and automated image sequences you usually have some sort of variables, that handle the states and counters for displaying sprite's sub-images.
But firstly I like to use mainly two main time-related variables in my controller object usually named sys (counter and counterTime):
c = 0; // and for stepEvent: c += 1; // so it goes +1 per step
ct = 0; // and for stepEvent: ct+= 1 / room_speed; // so it goes +1 per second
During the cutscene you might want to stop everything else that moves:
is_cutscene = false; // objects might not be able to move when this is true
// you still have to implement that by yourself
// player can't move if is_cutscene, nothing happens!!
(except cutscene buttons etc...)
So now when the player gets to a 'cutscene'y object and triggers some cutscene_1 = true eg. you can have the image/text/sound/animation object come to life/create/active... That object might have in the create event:
duration = 6; // 6 seconds the scene lasts
start_time = sys.ct // and in Step: if sys.ct > (start_time + duration)
// then -> cutscene advance/destroy
Ofcourse - this is super simple and now you could only say implement:
walk close to a pop-up object
show an image for 6 seconds
it dissappears
And it might not be big trouble to implement it... BUT THIS may also be the foundation for more advanced multi-step sequence and cuts.
New appmaker user here.
I'm trying to port the work permits approval "app" I made with G Suite form+spreadsheet+GAS; users should enter the day, the start and end time of the permit.
I can see from the Forum Sample that the Date field type is a DateTime field type, so I can use it in my model.
The problem is I cannot find the time picker in the widgets, and the date box has no option to also enter the time.
Am I missing something?
Time Pickers for App Maker
I read your question and thought I'd try to role one of my own and this is what I came up with. I put all of the buttons on a pageFragment and call it with app.showDialog(app.pageFragments.timePicker2);
I only use clientside script.
function updateOutput(){
var h=app.pageFragments.TimePicker2.properties.hour||'00';
var m=app.pageFragments.TimePicker2.properties.minute||'00';
var s=app.pageFragments.TimePicker2.properties.second||'00';
var t=h + ':' + m + ':' + s;
app.pageFragments.TimePicker2.descendants.timeLBL.text=t;
return t;
}
function updateHour(v){
app.pageFragments.TimePicker2.properties.hour=v;
updateOutput();
}
function updateMinute(v){
app.pageFragments.TimePicker2.properties.minute=v;
updateOutput();
}
function updateSecond(v){
app.pageFragments.TimePicker2.properties.second=v;
updateOutput();
}
Here's what my time picker looks like:
Yes. Adding all of the buttons is a nuisance but there are a few features about AppMaker that make it more tolerable.
First you can assign the TimePicker form properties which I use as global properties. I had three hour,minute and second.
Then after you add all of the hour buttons you can grab all of them at one time by clicking each one while holding down control on a windows machine and click on the onClick event and pick custom action and type this in updateHour(widget.text); the code completion won't give you text as an option but type it any way.
I just figured out how to grab the buttons all a one time by pushing shift and selecting with the mouse
Do the same thing with the minute and second buttons using updateMinute(widget.text) and updateSecond(widget.text); This saves you a lot of time typing all of the functions into each widget control panel. Also you don't have to bother giving all of the buttons special names like I did.
But you might like to format them with the following css.
And again you can grab all of the buttons at one time and change the following setting:
That way you can style all of the buttons at one time.
My save button just copies the final string into a label on the main panel.
app.pages.Testing.descendants.timeLBL2.text=app.pageFragments.TimePicker2.descendants.timeLBL.text;
app.closeDialog();
You will probably want to do something more elegant.
Here's a demo: in preview mode. Sorry about the 24 hour clock. I always use this for my own stuff because it's so much easier and I like it. You'll probably want AM & PM. I'll probably go back and do that too.
For an AM/PM Picker I used these functions:
function updateOutputAP(){
var h=app.pageFragments.TimePicker3.properties.hour||'00';
var m=app.pageFragments.TimePicker3.properties.minute||'00';
var s=app.pageFragments.TimePicker3.properties.second||'00';
var ap=app.pageFragments.TimePicker3.properties.ap||' ';
var t=h + ':' + m + ':' + s + ' ' + ap;
app.pageFragments.TimePicker3.descendants.timeLBL.text=t;
return t;
}
function updateHourPM(v){
app.pageFragments.TimePicker3.properties.hour=v;
app.pageFragments.TimePicker3.properties.ap='PM';
updateOutputAP();
}
function updateHourAM(v){
app.pageFragments.TimePicker3.properties.hour=v;
app.pageFragments.TimePicker3.properties.ap='AM';
updateOutputAP();
}
function updateMinuteAP(v){
app.pageFragments.TimePicker3.properties.minute=v;
updateOutputAP();
}
function updateSecondAP(v){
app.pageFragments.TimePicker3.properties.second=v;
updateOutputAP();
}
And this is what my picker looks like:
Now that I know how to pick the components easily with the mouse it was a break to make this change.
Three AppMaker Time Pickers:
At this time App Maker doesn't provide out of the box Time or Date/Time picker widgets, it means that you need to implement one by yourself. There are at least two ways to accomplish this task:
App Maker way
Wait and hope when App Maker will introduce Time or Date/Time picker widget or use existing App Maker widgets to emulate Time Picker. Calendar Sample can be a good starting point:
Hack into DOM/JS
If you have no concerns about cross-browser compatibility and you are OK to get you hands dirty with DOM manipulation by javascript, creating events listeners and other cool stuff, then you can play with HTML widget and native date/time or time input, or even some third party library.
One simple option would be to simply use a textbox and set the validation in the model field.
You can update your Date object on save or just use as is depending on your application. You get the benefit of auto validation errors in the UI to guide your user and it takes only seconds to set up.
Regex:
\b((1[0-2]|0?[1-9]):([0-5][0-9]) ([AaPp][Mm]))
It seems that youtube are now using ID's for their channels instead of names (part of the V3 api)
However it seems that the embedded iframe playlist player cannot handle these channel ID's
example channel https://www.youtube.com/channel/UCpAOGs57EWRvOPXQhnYHpow
then ID is UCpAOGs57EWRvOPXQhnYHpow
Now try to load this
http://www.youtube.com/embed/?listType=user_uploads&list=UCpAOGs57EWRvOPXQhnYHpow
Can anyone shine a light on this issue ? Or is there some hidden username ?
I also placed this question at the gdata-issues website http://code.google.com/p/gdata-issues/issues/detail?id=6463
The issue here is that a channel is not a playlist; channels can have multiple playlists, yet the listType parameter is designed to look for an actual playlist info object. The documented way around this is to use the data API and call the channel endpoint, looking at the contentDetails part:
GET https://www.googleapis.com/youtube/v3/channels?part=contentDetails&id=UCuo5NTU3pmtPejmlzjCgwdw&key={YOUR_API_KEY}
The result will give you all of the feeds associated with that channel that you can choose from:
"contentDetails": {
"relatedPlaylists": {
"uploads": "UUuo5NTU3pmtPejmlzjCgwdw"
}
}
If available (sometimes with oAuth), there could also be "watch later" lists, "likes" lists, etc.
This may seem like a lot of overhead. In the short term, though, it can be noted that the different feeds are programmatically named; so, for example, if my user channel begins with UC and then a long string, that UC stands for 'user channel' -- and the uploads feed would begin with 'UU' (user uploads) and then have the rest of the same long string. (you'd also have 'LL' for the likes list, 'WL' for the watch later list, 'HL' for the history list, 'FL' for the favorites list, etc. This is NOT documented, and so there's no guarantee that such a naming convention will perpetuate. But at least for now, you could change your ID string from beginning with UC to beginning with UU, like this:
http://www.youtube.com/embed/?listType=user_uploads&list=UUpAOGs57EWRvOPXQhnYHpow
And it embeds nicely.
Just to inform on current state of things -- the change suggested by jlmcdonald doesn't work anymore, but you can still get a proper embed link via videoseries (with the same UC to UU change). I.o.w. link like
http://www.youtube.com/embed/videoseries?list=UUpAOGs57EWRvOPXQhnYHpow
works as of at the moment of writing this.
Is there a way i can have an exposed filter wherein the user can select the number of items displayed by the drupal view?
I am nearly positive that you can do this with hook_views_pre_build (&$view). I know for a fact that you can mess with $view->pager to update whether to use the pager or not and to alter the number of items per page.
This is a snippet from a custom module I did:
if (is_numeric($perpage) && (int) $perpage > 1) {
$view->pager["items_per_page"] = (int) $perpage;
} else if ($perpage == "all") {
$view->pager["use_pager"] = false;
$view->pager["items_per_page"] = 0;
}
I suspect you can turn the pager off and also set the items per page to limit the results.
EDIT:
OK, just saw the part about the exposed filter. The code snippet is actually from a bit of code that simulates an exposed filter for this case. The page has some links on it to select the number of items per page. The links refresh the page, and tack on a perpage=whatever parameter. The hook then sanitizes the input, and basically runs the code snippet above. I have also done something similar using HTML a select, and then wiring up the parameter w/ refresh using jQuery.
Based on this thread in the issue queue, that appears to be a long requested feature. It has apparently been added to the 6.x-3.x-dev branch, so it should be available in the 6.x-3.0-alpha3 release.
Or if you're using Drupal 7, it has been added to the 7.x-3.x-dev branch too, so it should be in the 7.x-3.0-alpha1 release.