Issue with twitter Profile image using Titanium - twitter

I am newbie to titanium, I am learning JSon Parsing with titanium. I am accessing tweets for a specific screen name along with his/her profile picture. It is working well as concern to tweets but not showing the profile picture of that tweet.
My Tweet.js file is :
// Create variable "win" to refer to current window
var win = Titanium.UI.currentWindow;
// Function loadTweets()
function loadTweets()
{
// Empty array "rowData" for our tableview
var rowData = [];
var avatar;
// Create our HTTP Client and name it "loader"
var loader = Titanium.Network.createHTTPClient();
// Sets the HTTP request method, and the URL to get data from
loader.open("GET","http://api.twitter.com/1/statuses/user_timeline.json?screen_name=SenchaTouch");
// Runs the function when the data is ready for us to process
loader.onload = function()
{
var tweets = eval('('+this.responseText+')');
alert(tweets);
for (var i = 0; i < tweets.length; i++)
{
var tweet = tweets[i].text; // The tweet message
var user = tweets[i].user.screen_name; // The screen name of the user
avatar = tweets[i].user.profile_image_url; // The profile image
// Create a row and set its height to auto
var row = Titanium.UI.createTableViewRow({height:'auto'});
// Create the view that will contain the text and avatar
var post_view = Titanium.UI.createView({
height:'auto',
layout:'vertical',
top:5,
right:5,
bottom:5,
left:5
});
// Create image view to hold profile pic
var av_image = Titanium.UI.createImageView({
url:'KS_nav_ui.png', // the image for the image view
top:0,
left:0,
height:48,
width:48
});
post_view.add(av_image);
// Create the label to hold the screen name
var user_lbl = Titanium.UI.createLabel({
text:user,
left:54,
width:120,
top:-48,
bottom:2,
height:16,
textAlign:'left',
color:'#444444',
font:{fontFamily:'Trebuchet MS',fontSize:14,fontWeight:'bold'}
});
post_view.add(user_lbl);
// Create the label to hold the tweet message
var tweet_lbl = Titanium.UI.createLabel({
text:tweet,
left:54,
top:0,
bottom:2,
height:'auto',
width:236,
textAlign:'left',
font:{fontSize:14}
});
post_view.add(tweet_lbl);
// Add the post view to the row
row.add(post_view);
// Give each row a class name
row.className = "item"+i;
// Add row to the rowData array
rowData[i] = row;
}
// Create the table view and set its data source to "rowData" array
var tableView = Titanium.UI.createTableView({data:rowData});
//Add the table view to the window
win.add(tableView);
};
// Send the HTTP request
loader.send();
}
loadTweets();
// Can any find out the flaw ?? Any help would be appreciated.
Thanking in advance :)

At last found it .. The problem was in code. I just use url property in the image view instead of image property. Replacing the image property with that of url has done the trick.
url: avatar, // It should not be used .. It is not working
image: avatar, // It is working very well..

Related

Vaadin addComponentColumn only works in last row

this.grid = new Grid<>(Person.class);
this.grid.setItems(personList);
this.grid.setSelectionMode(SelectionMode.MULTI);
this.grid.removeAllColumns();
this.grid.setColumns("firstname");
this.editButton = new Button(null, ImageIcons.EDIT.create());
this.editButton.getStyle().set("color", "#000000");
this.grid.addComponentColumn(person -> this.editButton);
this.deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create());
this.deleteButton.getStyle().set("color", "#000000");
this.grid.addComponentColumn(person -> this.deleteButton);
this.addComponentAsFirst(this.grid);
I have a personList with several entries. The grid shows all these entries with their first name. But it only shows the buttons in the last row. What is the problem?
You use the very same Button instance for each row. You should create a new Button within the componentRenderer, so each row will have its own Button.
Try it like this:
this.grid = new Grid<>(Person.class, false);
this.grid.setItems(personList);
this.grid.setSelectionMode(SelectionMode.MULTI);
this.grid.setColumns("firstname");
this.grid.addComponentColumn(person -> {
// edit: added click listener for inline-editing of the person. Editor must be configured for this to work. See https://vaadin.com/components/vaadin-grid/java-examples/grid-editor
// You don't have to use inline-editing if you don't want. you can also edit the item in a separate Layout with Input fields and a Binder.
Button editButton = new Button(ImageIcons.EDIT.create(), click -> {
this.grid.getEditor().editItem(person);
});
editButton.getStyle().set("color", "#000000");
return editButton;
});
this.grid.addComponentColumn(person -> {
// edit: added click listener for person removal
Button deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create(), click -> {
this.personDao.remove(person);
// TODO: when using an in-memory dataprovider, fetch all items again from service/dao and set them with grid.setItems(this.personDao.findAll());
// but that is not necessary when using a callback dataprovider, which I belive OP is using
this.grid.getDataProvider().refresh();
});
deleteButton.getStyle().set("color", "#000000");
return deleteButton;
}
this.addComponentAsFirst(this.grid);
Edit: a minor thing but I still wanted to mention it - You do some unnecessary creation of columns, only to remove them all again later. Instead of this you could tell the grid not to create these columns in the first place, by passing false as second parameter of the Grid constructor.
this.grid = new Grid(Person.class, false);
// instead of
this.grid = new Grid(Person.class);
this.grid.removeAllColumns();

AppMaker and picker widget - uploading to a specific folder

I'm trying to have a button to allow users to upload a file, into a specific folder. I tried to follow other advise, and add this hook to
onPickerInit:
var uploadView = new google.picker.DocsUploadView()
uploadView.setParent('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); // test folder
pickerBuilder.addView(uploadView);
I've set the MULTISELECT_ENABLED feature (without it, the destination folder is not respected), and I can in fact now upload the files where they belong. Yay!
HOWEVER: The picker widget now has two upload tabs. The first one just does the regular upload into the drive main folder, the second tab does the right thing. My guess is that appmaker contstructs the first upload tab behind the curtains and there is no feature to disable this.
This is obviously fairly quirky and hardly usable. My questions are:
1) are there (possibly undocumented) API calls in the pickerbuilder to remove the original upload view?
2) Is it possible to respect the destination folder even is the MULTISELECT feature is off ?
Many thanks in advance for any pragmatic solutions!
EDIT 07/28/2020
Due to the constant changes in drive picker, this code aims for a more permanent solution:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
var prps = [];
for(var prop in pickerBuilder){
var value = pickerBuilder[prop];
if(!!value){
if(typeof(value)==="object"){
var proto = value.__proto__; //jshint ignore: line
if(!!proto["addLabel"] && !!proto["addView"]){
prps.push(prop);
for(var key in value){
var target = value[key];
var type = Object.prototype.toString.call(target);
if(type === "[object Array]"){
prps.push(key);
for(var key in target[0]){
var value = target[0][key];
if(typeof(value)==="object"){
prps.push(key);
}
}
for(var key in target[0]){
var value = target[0][key];
if(typeof(value)==="string") {
prps.push(key);
}
}
}
}
}
}
}
}
var views = pickerBuilder[prps[0]][prps[1]];
for(var i=0; i<views.length; i++){
var view = views[i];
if(view[prps[3]] === "upload"){
view[prps[2]].parent = folderId;
}
}
EDIT 06/29/2020
There has been another change in the Drive picker API. To make this work please change what you have to:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
pickerBuilder.rw.kf["0"].Ta.parent = folderId;
EDIT 05/26/2020
There has been another change in the Drive picker API. To make this work please change what you have to:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
pickerBuilder.xw.jf["0"].Ta.parent = folderId;
EDIT 02/17/2020
There has been a change in the Drive picker API. To make this work please change what you have to:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
pickerBuilder.mw.$e["0"].Ra.parent = folderId;
To answer your questions directly:
1.) YES
2.) YES
Now, let's dig a little bit into what's happening under the hood. You are right:
My guess is that appmaker contstructs the first upload tab behind the curtains and there is no feature to disable this.
However, we can manipulate the object. So instead of creating a new picker view, let's simply configure the default one to upload the files to the folder you want. We can achieve that by doing the following:
1.) After you insert a Drive Picker into your UI, make sure the Drive Picker Properties are all empty:
2.) Next, go to the event handlers and click on the onPickerInit event handler. Type in this code:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
pickerBuilder.SW.Vq["0"].mc.parent = folderId;
In summary, I've come to the conclusion that the property SW contains the array of drive views, which are saved under the property Vq. Vq["0"] is the first view in the array of views and the mc property contains the features; hence parent = folderId.

Delete NSObject from model

I have created a file in Swift called infoModel. This is used to pass info from one ViewController to another, and the info is written in a label. This works perfectly, but I want to be able to delete that info, or at least remove it from the label.
I have tried to set label = nil, but the info pops back in when I change to a different viewController and back.
How should I go about to remove the data?
Code infoModel:
import UIKit
class infoModel: NSObject {
var info: String = ""
var info2: String = ""
var info3: String = ""
var info4: String = ""
func currentInfo() -> String {
//return a string with the current info
return info + "" + info2 + "" + info3 + "" + info4 + ""
}
}
And in view controller:
class collectViewController: UIViewController {
var myInfo = infoModel()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
infoLabel.text = myInfo.currentInfo()
}
}
It´s the infoLabel I want to remove from.
*Edit: The app is collecting info from users. The way that it does that, is simply that the user is pressing a/some button/buttons that represents the suitable values for that specific user. The information is then displayed in a different View Controller. If the user presses the wrong button, I want them to be able to delete/remove the information and start over. The removebutton is in the same View controller that the infoLabel is.
When all the information is correct, the user then pushes another button that writes to Firebase Database.
So my goal is that the user is able to delete/remove the info, and start over.
Don't set initial value to myInfo, make it an optional:
var myInfo: infoModel?
and
infoLabel.text = myInfo?.currentInfo()
Now if there is no model, nothing will be set.
Also, you can automatically update the label using:
var myInfo: infoModel? {
didSet {
_ = self.view // load the view if not loaded
infoLabel.text = myInfo?.currentInfo()
}
}
Now just setting myInfo = nil will clear the label.
you need to use the model as a container of your data and changes.
when the user presses the various buttons, you need to update the model, and when the user clicks the remove button, you need to update the model to reflect that state.
Instead of setting the entire object to nil, set the inside variables to nil, so that the model object always exist. You will need to do more unwrapping.
var info: String? = nil
var info2: String? = nil
var info3: String? = nil
var info4: String? = nil
If you don't want to do that, you will need to check the nullability of your model and create a new one when it is nil (as Sultan explained in the other response)
(I could also suggest you use a struct and not a class)
You then need to redraw your UI when the model is updated.
I think in your simple case even running setNeedsDisplay on the view of the controller should do the trick
I actually solved the issue with not being able to re add data to the label just by doing this:
myInfo?.info = ""
myInfo?.info2 = ""
myInfo?.info3 = ""
myInfo?.info4 = ""

How to show selected node on content picker to front page

I want to create a selection of banner with Content Picker' to select node to use other banner. http://screencast.com/t/3gb6TeAe
Now I wonder how to show the selected banner on Content Picker and show it in front page. Any idea to make it in easy way.
I have tried already to get the Url of selected node.
var nodeId = Model.Content.GetPropertyValue("selectBanner");
var node = Umbraco.TypedContent(nodeId);
#node.Name
If my understanding is correct you first need to get the banner node:
// This gets the node selected by your content picker
var bannerNode = Umbraco.TypedContent(Model.Content.GetPropertyValue<int>("selectBanner"));
You then need to get the image specified on the banner node:
// This gets you the image/media set on the banner nodes media picker property
var img = Umbraco.Media(bannerNode.GetPropertyValue("mediaPickerPropertyAlias")).Url
You can then access either the bannerNode url:
#bannerNode.Url
or the image specified on the banner node:
#img.Url
From what I can understand you have a Media Picker in your Banner document type. So you need to access banners image Url... you can do following
var node = Model.Content; // Your content of type banner
var imgUrl = Umbraco.Media(node.GetPropertyValue("selectBanner")).Url // getting property for image and then its url
#node.Name
or if you want to show just image
<img src="#imgUrl"/>

Get contact details to titanium from native iOS contact app

I'm new to Titanium.
Currently I'm working on a project in this the user needs to use the contact details from iOS contacts App.
My app.js looks like this
Window = require('ui/handheld/ApplicationWindow');
var win = Window();
win.open();
var button = Ti.UI.createButton({
title : 'Show Contacts',
width : 100,
height: 50,
});
win.add(button);
button.addEventListener('click',function(e){
Titanium.Contacts.showContacts({ });
});
When I click on a button the following code is displayed:
And when I select an contact the detail is displayed on the other screen:
But I don't want this, When the user selects an individual contact the details should be passed to my app.js file. And no need to go to the details page.
Is there any way to do this ?
Please help me.
Thanks in advance.
It seems that you're missing a declaration of function to be called when a person is selected:
Titanium.Contacts.showContacts({/*missing selectedPerson callback object*/});
You can read more on what parameters can be passed into showContacts method here.
Finally I got it.
I used the following code:
button.addEventListener('click',function(e){
Titanium.Contacts.showContacts(values);
});
var values = {cancel:function(){}};
values.fields = ['firstName', 'lastName', 'phone'];
values.selectedProperty = function(e) {
var cn = e.person.firstName;
var sn = e.person.lastName;
alert('Name'+cn+' '+sn);
};
Reference : Titanium Contacts
var parms = {
animated : true,
selectedPerson : function(e) {
alert(e.person);
}
};
Titanium.Contacts.showContacts(parms);
You will get the details of selected person in e.person object. that can be passed to app.js etc according to your requirements. i just showed it in the alert.

Resources